📄 vcp_widgets.c
字号:
CL_CONTROL, CH_ONE | CL_LAYOUT | CL_LABEL, button_attribs, sizeof(button_data_t), init_button};static void button_pressed(GtkWidget * widget, gpointer gdata){ vcp_widget_t *wp; button_data_t *dp; button_hal_t *hp; wp = (vcp_widget_t *)gdata; dp = (button_data_t *)wp->priv_data; hp = (button_hal_t *)wp->hal_data; dp->pin_state = 1; *(hp->pin) = dp->pin_state;}static void button_released(GtkWidget * widget, gpointer gdata){ vcp_widget_t *wp; button_data_t *dp; button_hal_t *hp; wp = (vcp_widget_t *)gdata; dp = (button_data_t *)wp->priv_data; hp = (button_hal_t *)wp->hal_data; dp->pin_state = 0; *(hp->pin) = dp->pin_state;}static void button_refresh (vcp_widget_t *wp){ button_data_t *dp; button_hal_t *hp; dp = (button_data_t *)wp->priv_data; hp = (button_hal_t *)wp->hal_data; *(hp->pin) = dp->pin_state;}static int init_button ( vcp_widget_t *wp ){ button_data_t *pd; button_hal_t *hd; int retval; GtkWidget *gwp; pd = (button_data_t *)(wp->priv_data); /* allocate HAL memory for pin */ hd = hal_malloc(sizeof(button_hal_t)); if (hd == NULL) { printf( "init_button(): unable to allocate HAL memory\n" ); return -1; } wp->hal_data = hd; /* export pin */ retval = hal_pin_bit_new(pd->halpin, HAL_OUT, &(hd->pin), comp_id); if (retval != 0) { printf( "init_button(): unable to export HAL pin '%s'\n", pd->halpin ); return retval; } /* does the button have a child? */ if ( wp->child != NULL ) { /* create a plain button so the child can go inside */ gwp = gtk_button_new(); } else { /* create a button with a blank label inside */ gwp = gtk_button_new_with_label(NULL); } wp->gtk_widget = gwp; wp->gtk_type = BIN; /* put it in its parent */ add_to_parent(wp->parent, gwp, pd->expand, pd->padding); /* connect handler functions */ gtk_signal_connect(GTK_OBJECT(gwp), "pressed", GTK_SIGNAL_FUNC(button_pressed), wp); gtk_signal_connect(GTK_OBJECT(gwp), "released", GTK_SIGNAL_FUNC(button_released), wp); /* use a poll function for periodic refresh, even if the user doesn't press the button */ wp->poll_funct = button_refresh; gtk_widget_show(gwp); return 0;}/** TOGGLE: The toggle widget sets a bit HAL pin TRUE or FALSE depending on it's state. The widget is not labeled, but it can accept any child widget (or widgets, if they are in a box). Normally, a label widget would be specified as a child. The appearance (style) of the widget can be either "button" or "checkbox", they work exactly the same.*/static int init_toggle(vcp_widget_t *widget);typedef struct { int expand; int padding; char *halpin; char *style; char state; hal_bit_t pin_state;} toggle_data_t;typedef struct { hal_bit_t *pin;} toggle_hal_t;vcp_attrib_def_t toggle_attribs[] = { { "expand", "0", ATTRIB_BOOL, offsetof(toggle_data_t, expand) }, { "padding", "0", ATTRIB_INT, offsetof(toggle_data_t, padding) }, { "halpin", NULL, ATTRIB_STRING, offsetof(toggle_data_t, halpin) }, { "state", "0", ATTRIB_BOOL, offsetof(toggle_data_t, state) }, { "style", "button", ATTRIB_STRING, offsetof(toggle_data_t, style) }, { NULL, NULL, 0, 0 }};vcp_widget_def_t toggle_def = { "toggle", CL_CONTROL, CH_ONE | CL_LAYOUT | CL_LABEL, toggle_attribs, sizeof(toggle_data_t), init_toggle};static void toggle_toggled(GtkWidget * widget, gpointer gdata){ vcp_widget_t *wp; toggle_data_t *dp; toggle_hal_t *hp; wp = (vcp_widget_t *)gdata; dp = (toggle_data_t *)wp->priv_data; hp = (toggle_hal_t *)wp->hal_data; if (GTK_TOGGLE_BUTTON (widget) ->active) { dp->pin_state = 1; *(hp->pin) = dp->pin_state; } else { dp->pin_state = 0; *(hp->pin) = dp->pin_state; }}static void toggle_refresh (vcp_widget_t *wp){ toggle_data_t *dp; toggle_hal_t *hp; dp = (toggle_data_t *)wp->priv_data; hp = (toggle_hal_t *)wp->hal_data; *(hp->pin) = dp->pin_state;}static int init_toggle ( vcp_widget_t *wp ){ toggle_data_t *pd; toggle_hal_t *hd; int retval; GtkWidget *gwp; pd = (toggle_data_t *)(wp->priv_data); /* allocate HAL memory for pin */ hd = hal_malloc(sizeof(toggle_hal_t)); if (hd == NULL) { printf( "init_toggle(): unable to allocate HAL memory\n" ); return -1; } wp->hal_data = hd; /* export pin */ retval = hal_pin_bit_new(pd->halpin, HAL_OUT, &(hd->pin), comp_id); if (retval != 0) { printf( "init_toggle(): unable to export HAL pin '%s'\n", pd->halpin ); return retval; } /* create the GTK widget */ if ( strncasecmp(pd->style, "button", 6) == 0 ) { /* does it have a child? */ if ( wp->child != NULL ) { /* create a plain GTK toggle button so the child can go inside */ gwp = gtk_toggle_button_new(); } else { /* create a GTK toggle button with a blank label inside */ gwp = gtk_toggle_button_new_with_label(NULL); } } else if ( strncasecmp(pd->style, "check", 5) == 0 ) { /* does it have a child? */ if ( wp->child != NULL ) { /* create a plain GTK check button so the child can go inside */ gwp = gtk_check_button_new(); } else { /* create a GTK check button with a blank label inside */ gwp = gtk_check_button_new_with_label(NULL); } } else { printf ( "line %d:toggle style must be either button or checkbox\n", wp->linenum ); return -1; } wp->gtk_widget = gwp; wp->gtk_type = BIN; /* put it in its parent */ add_to_parent(wp->parent, gwp, pd->expand, pd->padding); /* connect handler functions */ gtk_signal_connect(GTK_OBJECT(gwp), "toggled", GTK_SIGNAL_FUNC(toggle_toggled), wp); /* set the initial toggle state to TRUE/FALSE (state) */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gwp),pd->state); /* use a poll function for periodic refresh, even if the user doesn't press the toggle button */ wp->poll_funct = toggle_refresh; gtk_widget_show(gwp); return 0;}/** LED: The LED widget monitors a bit HAL pin and changes color to indicate the state of the pin.*/static int init_led(vcp_widget_t *widget);typedef struct { int expand; int padding; int diameter; char *halpin; int last; GtkWidget *drawing; /* drawing area for LED image */ GdkColormap *map; /* colormap for LED image */ GdkColor color_border; /* the circle around the LED */ GdkColor color_off; /* LED off color */ GdkColor color_on; /* LED on color */ GdkDrawable *win; /* the window */ GdkGC *context; /* graphics context for drawing LED */} led_data_t;typedef struct { hal_bit_t *pin;} led_hal_t;vcp_attrib_def_t led_attribs[] = { { "expand", "0", ATTRIB_BOOL, offsetof(led_data_t, expand) }, { "padding", "0", ATTRIB_INT, offsetof(led_data_t, padding) }, { "size", "20", ATTRIB_INT, offsetof(led_data_t, diameter) }, { "on-color", "#FF0000", ATTRIB_COLOR, offsetof(led_data_t, color_on) }, { "off-color", "#600000", ATTRIB_COLOR, offsetof(led_data_t, color_off) }, { "halpin", NULL, ATTRIB_STRING, offsetof(led_data_t, halpin) }, { NULL, NULL, 0, 0 }};vcp_widget_def_t led_def = { "LED", CL_DISPLAY, CH_NONE, led_attribs, sizeof(led_data_t), init_led};static int led_refresh (GtkWidget *widget, GdkEventExpose *event, vcp_widget_t *wp){ led_data_t *dp; led_hal_t *hp; int width, height; int border_dia, led_dia; int xstart, ystart; dp = (led_data_t *)wp->priv_data; hp = (led_hal_t *)wp->hal_data; /* get window pointer */ dp->win = dp->drawing->window; if (dp->win == NULL) { /* window isn't visible yet, do nothing */ printf("led_refresh(): win = NULL, bailing!\n"); return FALSE; } /* create drawing context if needed */ if (dp->context == NULL) { dp->context = gdk_gc_new(dp->win); } border_dia = dp->diameter; /* get window dimensions */ gdk_window_get_geometry(dp->win, NULL, NULL, &width, &height, NULL); if ( border_dia > (height-2) ) { border_dia = height-2; } if ( border_dia > (width-2) ) { border_dia = width-2; } led_dia = border_dia; if ( led_dia < 0 ) { led_dia = 0; } xstart = (width-border_dia)/2; ystart = (height-border_dia)/2; /* clear the display */ gdk_window_clear(dp->win); /* draw the LED */ if ( *(hp->pin) ) { gdk_gc_set_foreground(dp->context, &(dp->color_on)); } else { gdk_gc_set_foreground(dp->context, &(dp->color_off)); } gdk_draw_arc ( dp->win, dp->context, 1, xstart, ystart, led_dia, led_dia, 0, 64*360 ); /* draw the LED border */ gdk_gc_set_foreground(dp->context, &(dp->color_border)); gdk_draw_arc ( dp->win, dp->context, 0, xstart, ystart, border_dia, border_dia, 0, 64*360 ); return FALSE;} static void led_refresh_check(vcp_widget_t *wp) { led_data_t *dp; led_hal_t *hp; dp = (led_data_t *)wp->priv_data; hp = (led_hal_t *)wp->hal_data; if( *(hp->pin) != dp->last ) { dp->last = *(hp->pin); gtk_widget_queue_draw(dp->drawing); }}static int init_led ( vcp_widget_t *wp ){ led_data_t *pd; led_hal_t *hd; int retval; GtkWidget *gwp; pd = (led_data_t *)(wp->priv_data); /* allocate HAL memory for pin */ hd = hal_malloc(sizeof(led_hal_t)); if (hd == NULL) { printf( "init_led(): unable to allocate HAL memory\n" ); return -1; } wp->hal_data = hd; /* export pin */ retval = hal_pin_bit_new(pd->halpin, HAL_IN, &(hd->pin), comp_id); if (retval != 0) { printf( "init_button(): unable to export HAL pin '%s'\n", pd->halpin ); return retval; } pd = wp->priv_data; /* allocate a drawing area */ gwp = gtk_drawing_area_new(); /* set its size to fit the LED */ gtk_drawing_area_size(GTK_DRAWING_AREA(gwp), pd->diameter+2, pd->diameter+2); pd->drawing = gwp; pd->last = -1; wp->gtk_widget = gwp; wp->gtk_type = NONE; /* hook up a function to handle expose events */ gtk_signal_connect(GTK_OBJECT(gwp), "expose_event", GTK_SIGNAL_FUNC(led_refresh), wp); gtk_widget_set_double_buffered(GTK_WIDGET(gwp), TRUE); /* get color map */ pd->map = gtk_widget_get_colormap(gwp); /* allocate colors */ alloc_color_rgb(&(pd->color_border), pd->map, 0, 0, 0); alloc_color(&(pd->color_off), pd->map); alloc_color(&(pd->color_on), pd->map); /* put it in its parent */ add_to_parent(wp->parent, gwp, pd->expand, pd->padding); /* use a poll function for periodic refresh */ wp->poll_funct = led_refresh_check; gtk_widget_show(gwp); return 0;}/******************* list of widget definitions ****************/vcp_widget_def_t *widget_defs[] = { &vcp_def, &main_window_def, &box_def, &label_def, &spin_button_def, &toggle_def, &button_def, &led_def, NULL}; /*********************** Local Function Code ********************/static gboolean alloc_color_rgb(GdkColor * color, GdkColormap * map, unsigned char red, unsigned char green, unsigned char blue){ int retval; color->red = ((unsigned long) red) << 8; color->green = ((unsigned long) green) << 8; color->blue = ((unsigned long) blue) << 8; color->pixel = ((unsigned long) red) << 16 | ((unsigned long) green) << 8 | ((unsigned long) blue); retval = gdk_colormap_alloc_color(map, color, FALSE, TRUE); if (retval == 0) { printf("alloc_color_rgb( %d, %d, %d ) failed\n", red, green, blue); } return retval;}static gboolean alloc_color(GdkColor * color, GdkColormap * map){ int retval; retval = gdk_colormap_alloc_color(map, color, FALSE, TRUE); if (retval == 0) { printf("alloc_color( %d, %d, %d ) failed\n", color->red, color->green, color->blue); } return retval;}static void add_to_parent ( vcp_widget_t *parent, GtkWidget *child, int expand, int padding ){ if ( parent->gtk_type == BOX ) { gtk_box_pack_start(GTK_BOX(parent->gtk_widget), child, expand, TRUE, padding); } else if ( parent->gtk_type == BIN ) { gtk_container_add(GTK_CONTAINER(parent->gtk_widget), child); } else { printf ( "can't pack things into '%s'\n", parent->type->name ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -