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 + -
显示快捷键?