📄 vcp_widgets.c
字号:
/** This file, 'vcp_widgets.c', implements most of the GUI widgets that halvcp uses to build a Virtual Control Panel.*//** Copyright (C) 2005 John Kasunich <jmkasunich AT users DOT sourceforge DOT net>*//** This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU General Public License as published by the Free Software Foundation. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA THE AUTHORS OF THIS PROGRAM ACCEPT ABSOLUTELY NO LIABILITY FOR ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of harming persons must have provisions for completely removing power from all motors, etc, before persons enter any danger area. All machinery must be designed to comply with local and national safety codes, and the authors of this software can not, and do not, take any responsibility for such compliance. This code was written as part of the EMC HAL project. For more information, go to www.linuxcnc.org.*/#include <stdio.h>#include <stddef.h>#include <ctype.h>#include <hal.h>#include "vcp.h"/*************** Local Function Prototypes *********************/static void add_to_parent ( vcp_widget_t *parent, GtkWidget *child, int expand, int padding );/*********** Widget Definitions (structs and code) *************//** General notes: Every widget must declare a vcp_widget_def_t structure, and initialize it with the appropriate values. Fields are as follows: 'name' The name of the widget, as a string. 'w_class' The class of the widget. 'w_class_mask' A bitmask identifying legal child widgets. 'attribs' A pointer to an array of vcp_attrib_def_t structs that identify the widget's attributes. Can be NULL if there are no attributes. 'priv_data_size' The number of bytes of RAM needed for the widget's private data, including attribute values (but not HAL data). Can be zero if there are no no attributes and no other internal data. 'init_funct' Pointer to a function that initializes the widget. Can be NULL, but just about any usefull widget will require some init code. When the init_funct is called, it is passed a pointer to a new vcp_widget structure. The 'type' pointer in the structure points to the definition above, so the init function can get any data it needs from the definition, or indirectly from the attribute definitions. The 'parent', 'child', and 'sibling' pointers in the widget structure will already be set, as will the linenum field. The 'priv_data' pointer will point to a block of the desired size. The 'hal_data' field will be NULL, if the widget needs HAL data, the init function must allocate it. The 'poll_funct' field will also be NULL, the init function should set it if needed. If specified, the 'poll_funct' will be called about ten times per second (this may wind up configurable). It is passed a pointer to the widget structure.*//* Widgets start here *//** VCP WIDGET: This is the top level widget in the file. It isn't a real widget, it simply provides a wrapper for everything else. In theory the "main-window" widget could serve this role, but someday I might want to allow for pop-ups or other widgets that are siblings of the main window rather than its children.*/vcp_widget_def_t vcp_def = { "vcp", CL_TOP_LEVEL, CH_ONE | CL_MAIN_WINDOW, NULL, 0, NULL};/** MAIN WINDOW WIDGET: The application must have one and only one of these widgets. It is the main GUI window of the program.*/static int init_main_window(vcp_widget_t *widget);typedef struct { char *title; int height; int width;} main_win_data_t;vcp_attrib_def_t main_win_attribs[] = { { "title", "VCP", ATTRIB_STRING, offsetof(main_win_data_t, title) }, { "height", "-2", ATTRIB_INT, offsetof(main_win_data_t, height) }, { "width", "-2", ATTRIB_INT, offsetof(main_win_data_t, width) }, { NULL, NULL, 0, 0 }};vcp_widget_def_t main_window_def = { "main-window", CL_MAIN_WINDOW, CH_ONE | CL_CONTROL | CL_LAYOUT, main_win_attribs, sizeof(main_win_data_t), init_main_window};static void main_window_closed(GtkWidget * widget, gpointer * gdata){ gtk_main_quit();}static int init_main_window ( vcp_widget_t *wp ){ static int have_one = 0; main_win_data_t *pd; GtkWidget *gwp;printf ( "init main window\n" ); if ( have_one != 0 ) { printf ( "line %d: can't have two main windows\n", wp->linenum ); return -1; } /* get pointer to private data */ pd = (main_win_data_t *)(wp->priv_data); /* create main window, set it's size */ gwp = gtk_window_new(GTK_WINDOW_TOPLEVEL); wp->gtk_widget = gwp; wp->gtk_type = BIN; /* set the minimum size */ gtk_widget_set_usize(GTK_WIDGET(gwp), pd->width, pd->height); /* allow the user to expand it */ gtk_window_set_policy(GTK_WINDOW(gwp), FALSE, TRUE, FALSE); /* set main window title */ gtk_window_set_title(GTK_WINDOW(gwp), pd->title); /* this makes the application exit when the window is closed */ gtk_signal_connect(GTK_OBJECT(gwp), "destroy", GTK_SIGNAL_FUNC(main_window_closed), NULL);printf ( " done\n" ); have_one = 1; return 0;}/** BOX: The box widget is used to place more than one child widget inside a parent widget that normally holds only one child. It can also draw an optional frame and title around the group of widgets it contains.*/static int init_box(vcp_widget_t *widget);typedef struct { char *layout; int expand; int padding; int uniform; int space; int frame; char *title; int border;} box_data_t;vcp_attrib_def_t box_attribs[] = { { "layout", "V", ATTRIB_STRING, offsetof(box_data_t, layout) }, { "expand", "0", ATTRIB_BOOL, offsetof(box_data_t, expand) }, { "padding", "0", ATTRIB_INT, offsetof(box_data_t, padding) }, { "uniform", "0", ATTRIB_BOOL, offsetof(box_data_t, uniform) }, { "space", "0", ATTRIB_INT, offsetof(box_data_t, space) }, { "frame", "0", ATTRIB_BOOL, offsetof(box_data_t, frame) }, { "title", "", ATTRIB_STRING, offsetof(box_data_t, title) }, { "border", "0", ATTRIB_INT, offsetof(box_data_t, border) }, { NULL, NULL, 0, 0 }};vcp_widget_def_t box_def = { "box", CL_LAYOUT, CH_MANY | CL_CONTROL | CL_LAYOUT | CL_LABEL, box_attribs, sizeof(box_data_t), init_box};static int init_box ( vcp_widget_t *wp ){ box_data_t *pd; GtkWidget *gwp, *gwp2; printf ( "init box\n" ); /* get pointer to private data */ pd = (box_data_t *)(wp->priv_data); /* we only look a the first character of the layout param */ pd->layout[0] = toupper(pd->layout[0]); if (( pd->layout[0] != 'V' ) && ( pd->layout[0] != 'H' )) { printf ( "line %d:box layout must be either horizontal or vertical\n", wp->linenum ); return -1; } /* create the box */ if ( pd->layout[0] == 'H' ) { gwp = gtk_hbox_new(pd->uniform, pd->space); } else { gwp = gtk_vbox_new(pd->uniform, pd->space); } wp->gtk_widget = gwp; wp->gtk_type = BOX; gtk_container_set_border_width(GTK_CONTAINER(gwp), pd->border); /* see if we need a frame */ if (( pd->frame != 0 ) || ( pd->title[0] != '\0' )) { /* create a frame */ if ( pd->title[0] == '\0' ) { /* no title */ gwp2 = gtk_frame_new(NULL); } else { gwp2 = gtk_frame_new(pd->title); } gtk_container_add(GTK_CONTAINER(gwp2), gwp); gtk_widget_show(gwp); gwp = gwp2; } /* add to the parent widget */ add_to_parent(wp->parent, gwp, pd->expand, pd->padding); gtk_widget_show(gwp);printf ( " done\n" ); return 0;}/** LABEL: The label widget provides a simple, static label.*/static int init_label(vcp_widget_t *widget);typedef struct { int expand; int padding; char *text;} label_data_t;vcp_attrib_def_t label_attribs[] = {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -