classicladder_gtk.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,261 行 · 第 1/3 页
C
1,261 行
/* Classic Ladder Project *//* Copyright (C) 2001-2006 Marc Le Douarain *//* http://www.multimania.com/mavati/classicladder *//* http://www.sourceforge.net/projects/classicladder *//* February 2001 *//* ---------------------------- *//* GTK Interface & Main *//* Inspired (at the start) from the scribble example. *//* ---------------------------------- *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <gtk/gtk.h>#include <gdk/gdk.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include "classicladder.h"#include "global.h"#include "classicladder_gtk.h"// #include "hardware.h"#define NBR_BOOLS_VAR_SPY 15 //for bit variable list (15 in each column)#define NBR_TYPE_BOOLS_SPY 3 // for 3 columns#define NBR_FREE_VAR_SPY 10 //for word variable list (10 variables)GdkPixmap *pixmap = NULL;GtkWidget *drawing_area = NULL;GtkWidget *offsetboolvar[ NBR_TYPE_BOOLS_SPY ];int ValOffsetBoolVar[ NBR_TYPE_BOOLS_SPY ] = { 0, 0, 0 };GtkWidget *chkvar[ NBR_TYPE_BOOLS_SPY ][ NBR_BOOLS_VAR_SPY ];GtkWidget *EntryVarSpy[NBR_FREE_VAR_SPY*2];int VarSpy[NBR_FREE_VAR_SPY][2] = { {VAR_MEM_WORD,0}, {VAR_MEM_WORD,1}, {VAR_MEM_WORD,2}, {VAR_MEM_WORD,3}, {VAR_MEM_WORD,4}, {VAR_MEM_WORD,5}, {VAR_MEM_WORD,6}, {VAR_MEM_WORD,7}, {VAR_MEM_WORD,8},{VAR_MEM_WORD,9 } }; /* defaults vars to spy */static int VarWindowToggle; // toggle display of vars window variable GtkWidget *DisplayFormatVarSpy[NBR_FREE_VAR_SPY];GtkWidget *entrylabel,*entrycomment;GtkWidget *CheckDispSymbols;#if defined( RT_SUPPORT ) || defined( __XENO__ )GtkWidget *DurationOfLastScan;#endifGtkWidget *ButtonRunStop;GtkWidget *VScrollBar;GtkWidget *HScrollBar;GtkAdjustment * AdjustVScrollBar;GtkAdjustment * AdjustHScrollBar;GtkWidget *FileSelector;GtkWidget *ConfirmDialog;GtkWidget *RungWindow;GtkWidget *windowvars;GtkWidget *windowvars2; #include "drawing.h"#include "vars_access.h"#include "calc.h"#include "files.h"#include "edit.h"#include "edit_gtk.h"#include "editproperties_gtk.h"#include "manager_gtk.h"#include "config_gtk.h"// #include "socket_server.h"// #include "socket_modbus_master.h"#ifdef SEQUENTIAL_SUPPORT#include "calc_sequential.h"#endif#ifdef GNOME_PRINT_USE#include "print_gnome.h"#endif#include "symbols_gtk.h"/* Create a new backing pixmap of the appropriate size */static gint configure_event( GtkWidget *widget, GdkEventConfigure *event ){ if (pixmap) gdk_pixmap_unref(pixmap); pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); return TRUE;}/* Redraw the screen from the backing pixmap */static gint expose_event( GtkWidget *widget, GdkEventExpose *event ){ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE;}void UpdateVScrollBar(){ int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; if ( iCurrentLanguage==SECTION_IN_LADDER ) { int NbrRungs = 1; int ScanRung = InfosGene->FirstRung; int NumCurrentRung = 0; while ( ScanRung!=InfosGene->LastRung ) { NbrRungs++; ScanRung = RungArray[ ScanRung ].NextRung; } ScanRung = InfosGene->FirstRung; while ( ScanRung!=InfosGene->CurrentRung ) { NumCurrentRung++; ScanRung = RungArray[ ScanRung ].NextRung; }//printf("Nbr rungs=%d , NumRung=%d\n", NbrRungs, NumCurrentRung); AdjustVScrollBar->lower = 0; AdjustVScrollBar->upper = NbrRungs * InfosGene->BlockHeight*RUNG_HEIGHT; AdjustVScrollBar->value = NumCurrentRung * InfosGene->BlockHeight*RUNG_HEIGHT; while( AdjustVScrollBar->value+InfosGene->PageHeight > AdjustVScrollBar->upper ) { AdjustVScrollBar->value = AdjustVScrollBar->value - InfosGene->BlockHeight*RUNG_HEIGHT; } AdjustVScrollBar->step_increment = InfosGene->BlockHeight; AdjustVScrollBar->page_increment = InfosGene->BlockHeight*RUNG_HEIGHT; AdjustVScrollBar->page_size = InfosGene->PageHeight; gtk_adjustment_changed( AdjustVScrollBar ); gtk_adjustment_value_changed( AdjustVScrollBar ); gtk_widget_hide( HScrollBar );// gtk_widget_show( entrylabel );// gtk_widget_show( entrycomment ); }#ifdef SEQUENTIAL_SUPPORT if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL ) { gtk_widget_show( HScrollBar );// gtk_widget_hide( entrylabel );// gtk_widget_hide( entrycomment ); refresh_label_comment( ); AdjustVScrollBar->lower = 0; AdjustVScrollBar->upper = SEQ_PAGE_HEIGHT * SEQ_SIZE_DEF; AdjustVScrollBar->value = 0; AdjustVScrollBar->step_increment = SEQ_SIZE_DEF; AdjustVScrollBar->page_increment = InfosGene->PageHeight; AdjustVScrollBar->page_size = InfosGene->PageHeight; gtk_adjustment_changed( AdjustVScrollBar ); gtk_adjustment_value_changed( AdjustVScrollBar ); AdjustHScrollBar->lower = 0; AdjustHScrollBar->upper = SEQ_PAGE_WIDTH * SEQ_SIZE_DEF; AdjustHScrollBar->value = 0; AdjustHScrollBar->step_increment = SEQ_SIZE_DEF; AdjustHScrollBar->page_increment = InfosGene->PageWidth; AdjustHScrollBar->page_size = InfosGene->PageWidth; gtk_adjustment_changed( AdjustHScrollBar ); gtk_adjustment_value_changed( AdjustHScrollBar ); }#endif}void ChoiceOfTheCurrentRung( int NbrOfRungsAfterTopRung ){ int DecptNbrRungs = NbrOfRungsAfterTopRung;//printf("OffsetHiddenTopRungDisplayed=%d\n", InfosGene->OffsetHiddenTopRungDisplayed); // per default, the current rung, is the top one displayed... InfosGene->CurrentRung = InfosGene->TopRungDisplayed; // if OffsetHiddenTopRungDisplayed==0, vertical shift of the current rung is 0, // else this is the y value to substract to have the vertical shift... (we will add many full rungs heights after!) InfosGene->OffsetCurrentRungDisplayed = -1*InfosGene->OffsetHiddenTopRungDisplayed;//printf("=> In choice of current rung, %d passes...(CurrentRung=%d)\n",NbrOfRungsAfterTopRung, InfosGene->CurrentRung); while( DecptNbrRungs>0 && InfosGene->CurrentRung!=InfosGene->LastRung ) { InfosGene->CurrentRung = RungArray[ InfosGene->CurrentRung ].NextRung; InfosGene->OffsetCurrentRungDisplayed += InfosGene->BlockHeight*RUNG_HEIGHT; DecptNbrRungs--; }//printf("-> CurrentRung=%d , OffsetCurrentRungDisplayed=%d\n", InfosGene->CurrentRung, InfosGene->OffsetCurrentRungDisplayed); if ( InfosGene->OffsetCurrentRungDisplayed<0 ) printf( "Error in ChoiceOfTheCurrentRung( %d ) with OffsetCurrentRungDisplayed=%d\n", NbrOfRungsAfterTopRung, InfosGene->OffsetCurrentRungDisplayed ); refresh_label_comment( );}static gint VScrollBar_value_changed_event( GtkAdjustment * ScrollBar, void * not_used ){ int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; if ( iCurrentLanguage==SECTION_IN_LADDER ) { int NumRung = ((int)ScrollBar->value)/(InfosGene->BlockHeight*RUNG_HEIGHT); int ScanRung = 0; InfosGene->TopRungDisplayed = InfosGene->FirstRung; if ( NumRung<0 ) NumRung = 0; while( ScanRung!=NumRung ) { InfosGene->TopRungDisplayed = RungArray[ InfosGene->TopRungDisplayed ].NextRung; ScanRung++; } InfosGene->OffsetHiddenTopRungDisplayed = ((int)ScrollBar->value)%(InfosGene->BlockHeight*RUNG_HEIGHT); // if top rung displayed entirely (no vertical offset), it's the current rung => give '0'. // else, search the next one => give '1'. ChoiceOfTheCurrentRung( (InfosGene->OffsetHiddenTopRungDisplayed>0)?1:0 ); } InfosGene->VScrollValue = (int)ScrollBar->value; return TRUE;}static gint HScrollBar_value_changed_event( GtkAdjustment * ScrollBar, void * not_used ){ InfosGene->HScrollValue = (int)ScrollBar->value; return TRUE;}static gint button_press_event( GtkWidget *widget, GdkEventButton *event ){ if (event->button == 1 && pixmap != NULL) { if (EditDatas.ModeEdit) { EditElementInThePage(event->x,event->y); } else { // we can select the current rung by clicking on one. // the current rung is the one that will be modified... int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; if ( iCurrentLanguage==SECTION_IN_LADDER ) { char DoSelection = TRUE; if ( InfosGene->OffsetHiddenTopRungDisplayed>0 ) { if ( event->y<InfosGene->BlockHeight*RUNG_HEIGHT-InfosGene->OffsetHiddenTopRungDisplayed ) DoSelection = FALSE; } if ( DoSelection ) { int NbrRungsShift = (event->y+InfosGene->OffsetHiddenTopRungDisplayed)/(InfosGene->BlockHeight*RUNG_HEIGHT);printf("Select the current rung, with a shift of rungs=%d\n", NbrRungsShift ); ChoiceOfTheCurrentRung( NbrRungsShift ); } } } } return TRUE;}/* Draw a rectangle on the screen *//*static void draw_brush( GtkWidget *widget, gdouble x, gdouble y){ GdkRectangle update_rect; update_rect.x = x - 5; update_rect.y = y - 5; update_rect.width = 100; update_rect.height = 100; gdk_draw_rectangle (pixmap, widget->style->black_gc, TRUE, update_rect.x, update_rect.y, update_rect.width, update_rect.height); gtk_widget_draw (widget, &update_rect);}*/static gint chkvar_press_event( GtkWidget *widget, void * numcheck ){ int NumCheckWidget = (int)numcheck; int Type = VAR_MEM_BIT; int Offset = ValOffsetBoolVar[ 0 ]; int NumCheck = NumCheckWidget; if( NumCheckWidget>=NBR_BOOLS_VAR_SPY && NumCheckWidget<2*NBR_BOOLS_VAR_SPY ) { Type = VAR_PHYS_INPUT; Offset = ValOffsetBoolVar[ 1 ]; NumCheck -= NBR_BOOLS_VAR_SPY; } if( NumCheckWidget>=2*NBR_BOOLS_VAR_SPY && NumCheckWidget<3*NBR_BOOLS_VAR_SPY ) { Type = VAR_PHYS_OUTPUT; Offset = ValOffsetBoolVar[ 2 ]; NumCheck -= 2*NBR_BOOLS_VAR_SPY; } if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) WriteVar(Type,Offset+NumCheck,1); else WriteVar(Type,Offset+NumCheck,0); return TRUE;}static gint EntryVarSpy_activate_event(GtkWidget *widget, int * NumVarSpy){ int NewVarType,NewVarOffset; char BufferVar[30]; strcpy(BufferVar, gtk_entry_get_text((GtkEntry *)widget) ); if (TextParserForAVar(BufferVar , &NewVarType, &NewVarOffset, NULL, FALSE/*PartialNames*/)) { *NumVarSpy++ = NewVarType; *NumVarSpy = NewVarOffset; } else { int OldType,OldOffset; /* Error Message */printf("ici...\n"); if (ErrorMessageVarParser) ShowMessageBox("Error",ErrorMessageVarParser,"Ok"); else ShowMessageBox( "Error", "Unknown variable...", "Ok" ); OldType = *NumVarSpy++; OldOffset = *NumVarSpy; /* put back old correct var */ gtk_entry_set_text((GtkEntry *)widget,DisplayInfo(OldType,OldOffset)); } return TRUE;}static gint OffsetBoolVar_activate_event(GtkWidget *widget, void * NumVarSpy){ int Maxi = 0; int NumType = (int)NumVarSpy; int ValOffset = atoi( gtk_entry_get_text((GtkEntry *)widget) ); switch( NumType ) { case 0: Maxi = NBR_BITS; break; case 1: Maxi = NBR_PHYS_INPUTS; break; case 2: Maxi = NBR_PHYS_OUTPUTS; break; } if ( ValOffset+NBR_BOOLS_VAR_SPY>Maxi || ValOffset<0 ) ValOffset = 0; ValOffsetBoolVar[ NumType ] = ValOffset; UpdateAllLabelsBoolsVars( ); RefreshAllBoolsVars( ); return TRUE;}void refresh_label_comment( void ){ StrRung * RfhRung; if ( SectionArray[ InfosGene->CurrentSection ].Language==SECTION_IN_LADDER ) { RfhRung = &RungArray[InfosGene->CurrentRung]; gtk_entry_set_text((GtkEntry *)entrylabel,RfhRung->Label); gtk_entry_set_text((GtkEntry *)entrycomment,RfhRung->Comment); } else { gtk_entry_set_text((GtkEntry *)entrylabel,""); gtk_entry_set_text((GtkEntry *)entrycomment,""); }}void clear_label_comment(){ gtk_entry_set_text((GtkEntry *)entrylabel,""); gtk_entry_set_text((GtkEntry *)entrycomment,"");}void save_label_comment_edited(){ strcpy(EditDatas.Rung.Label,gtk_entry_get_text((GtkEntry *)entrylabel)); strcpy(EditDatas.Rung.Comment,gtk_entry_get_text((GtkEntry *)entrycomment));}void autorize_prevnext_buttons(int Yes){ if (Yes) { gtk_widget_set_sensitive(VScrollBar, TRUE); gtk_widget_set_sensitive(entrylabel, FALSE); gtk_widget_set_sensitive(entrycomment, FALSE); } else { gtk_widget_set_sensitive(VScrollBar, FALSE); gtk_widget_set_sensitive(entrylabel, TRUE); gtk_widget_set_sensitive(entrycomment, TRUE); }}// **this function not needed after mod to refresh at realtime period// ** but is good example how to add a button/function to ladder window//void ButtonRefresh_click()//{// if (InfosGene->SizesInfos.nbr_refresh <=10)// {// InfosGene->SizesInfos.nbr_refresh=100;// }// else// {// InfosGene->SizesInfos.nbr_refresh-=10; // }// } void ButtonRunStop_click(){ if (InfosGene->LadderState==STATE_RUN) { InfosGene->LadderState = STATE_STOP; gtk_label_set_text(GTK_LABEL(GTK_BIN(ButtonRunStop)->child),"Run"); } else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?