g_error field_install(struct widget *self) { g_error e; e = textbox_install(self); errorcheck; widget_set(self, PG_WP_MULTILINE, 0); widget_set(self, PG_WP_THOBJ, PGTH_O_FIELD); return success; }
g_error flatbutton_install(struct widget *self) { g_error e; e = button_install(self); errorcheck; /* Customize */ widget_set(self, PG_WP_THOBJ_BUTTON, PGTH_O_FLATBUTTON); widget_set(self, PG_WP_THOBJ_BUTTON_ON, PGTH_O_FLATBUTTON_ON); widget_set(self, PG_WP_THOBJ_BUTTON_HILIGHT, PGTH_O_FLATBUTTON_HILIGHT); widget_set(self, PG_WP_THOBJ_BUTTON_ON_NOHILIGHT, PGTH_O_FLATBUTTON_ON); return success; }
g_error tabpage_set(struct widget *self,int property, glob data) { struct widget *w; g_error e; /* Redirect applicable properties to the tab */ if (is_tab_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab)) && w) return widget_set(w, property, data); /* Redirect applicable properties to the tab bar */ if (is_tab_bar_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab_bar)) && w) return widget_set(w, property, data); return WIDGET_PARENT->set(self,property,data); }
int panel_rotate_callback(int event, struct widget *from, s32 param, int owner, const u8 *data) { struct widget *p; p = from->callback_owner; if (p && event==PG_WE_ACTIVATE) { switch (widget_get(p,PG_WP_SIDE)) { case PG_S_TOP: widget_set(p,PG_WP_SIDE,PG_S_RIGHT); break; case PG_S_RIGHT: widget_set(p,PG_WP_SIDE,PG_S_BOTTOM); break; case PG_S_BOTTOM: widget_set(p,PG_WP_SIDE,PG_S_LEFT); break; case PG_S_LEFT: widget_set(p,PG_WP_SIDE,PG_S_TOP); break; } update(NULL,1); } return 1; /* Absorb event */ }
void scroll_to_divnode(struct divnode *div) { s16 dx = 0,dy = 0; struct divnode *ds = div->divscroll; struct widget *w; if (!ds) return; /* If the divnode is larger or equal size to the scrolled * container, no need to scroll it in. * This fixes some confusing scroll behavior when focusing the textbox widget. */ if ( (div->r.x <= ds->calc.x && (div->r.x + div->r.w) > (ds->calc.x + ds->calc.w)) || (div->r.y <= ds->calc.y && (div->r.y + div->r.h) > (ds->calc.y + ds->calc.h)) ) return; /* Figure out how much to scroll, if any. */ if (div->r.x < ds->calc.x) dx = div->r.x - ds->calc.x; else if ( (div->r.x + div->r.w) > (ds->calc.x + ds->calc.w) ) dx = (div->r.x + div->r.w) - (ds->calc.x + ds->calc.w); if (div->r.y < ds->calc.y) dy = div->r.y - ds->calc.y; else if ( (div->r.y + div->r.h) > (ds->calc.y + ds->calc.h) ) dy = (div->r.y + div->r.h) - (ds->calc.y + ds->calc.h); /* No scrolling? */ if (!(dx || dy)) return; /* Get a pointer to the scroll bar */ if (!iserror(rdhandle((void **)&w,PG_TYPE_WIDGET,-1, ds->owner->scrollbind)) && w) { if (dx) widget_set(w,PG_WP_SCROLL_X,widget_get(w,PG_WP_SCROLL_X) + dx); if (dy) widget_set(w,PG_WP_SCROLL_Y,widget_get(w,PG_WP_SCROLL_Y) + dy); update(NULL,1); } }
g_error submenuitem_install(struct widget *self) { g_error e; /* Start with a button */ e = button_install(self); errorcheck; /* Customize */ widget_set(self, PG_WP_THOBJ_BUTTON, PGTH_O_SUBMENUITEM); widget_set(self, PG_WP_THOBJ_BUTTON_ON, PGTH_O_SUBMENUITEM_HILIGHT); widget_set(self, PG_WP_THOBJ_BUTTON_HILIGHT, PGTH_O_SUBMENUITEM_HILIGHT); widget_set(self, PG_WP_THOBJ_BUTTON_ON_NOHILIGHT, PGTH_O_SUBMENUITEM_HILIGHT); /* We need extra events */ widget_set(self,PG_WP_EXTDEVENTS,PG_EXEV_PNTR_UP | PG_EXEV_NOCLICK); #ifdef CONFIG_SUBMENU_NAVIGATION /* TTH: Register submenuitem_trigger callback */ self->def->trigger = submenuitem_trigger; #endif /* CONFIG_SUBMENU_NAVIGATION */ /* Stack vertically */ widget_set(self,PG_WP_SIDE,PG_S_TOP); return success; }
g_error panel_set(struct widget *self,int property, glob data) { struct widget *w; g_error e; struct app_info **app; switch (property) { case PG_WP_SIZE: /* Alias 0 to our minimum rolled-up size */ e = rdhandle((void **) &w, PG_TYPE_WIDGET, self->owner, DATA->hbar); errorcheck; if (data==0) data = w->in->split; widget_base_set(self,property,data); break; case PG_WP_SIDE: e = rdhandle((void **) &w, PG_TYPE_WIDGET, self->owner, DATA->hbar); errorcheck; switch (data) { /* Invert the side for the panelbar */ case PG_S_TOP: widget_set(w,PG_WP_SIDE,PG_S_BOTTOM); break; case PG_S_BOTTOM: widget_set(w,PG_WP_SIDE,PG_S_TOP); break; case PG_S_LEFT: widget_set(w,PG_WP_SIDE,PG_S_RIGHT); break; case PG_S_RIGHT: widget_set(w,PG_WP_SIDE,PG_S_LEFT); break; } return mkerror(ERRT_PASS,0); case PG_WP_THOBJ: DATA->bg->state = data; resizewidget(self); self->in->flags |= DIVNODE_NEED_RECALC; self->dt->flags |= DIVTREE_NEED_RECALC; break; case PG_WP_TEXT: e = rdhandle((void **) &w, PG_TYPE_WIDGET, self->owner, DATA->hlabel); errorcheck; app = appmgr_findapp(self); if (app && *app) (*app)->name = data; return widget_set(w,property,data); case PG_WP_IMAGE: e = rdhandle((void **) &w, PG_TYPE_WIDGET, self->owner, DATA->hlabel); errorcheck; return widget_set(w,property,data); case PG_WP_MARGIN: DATA->margin = data; DATA->margin_override = data >= 0; resizewidget(self); break; default: return mkerror(ERRT_PASS,0); } return success; }
g_error label_install(struct widget *self) { g_error e; /* Start with a button */ e = button_install(self); errorcheck; /* Customize */ widget_set(self, PG_WP_THOBJ_BUTTON, PGTH_O_LABEL); /* Make it inert */ widget_set(self,PG_WP_EXTDEVENTS,PG_EXEV_NO_HOTSPOT); widget_set(self,PG_WP_TRIGGERMASK,0); /* Stack vertically */ widget_set(self,PG_WP_SIDE,PG_S_TOP); /* Transparent by default */ widget_set(self,PG_WP_TRANSPARENT,1); return success; }
/* Create a standard panel button. * Note that the app owns these handles, so an app may delete one or more buttons. * This means that we _must_ only refer to the buttons by their handle unless of * course we're in a callback triggered by that button. */ g_error panel_std_button(handle *h, struct widget *self, int thobj, int thobj_on, int thobj_hilight, int exev, int (*callback)(int event, struct widget *from, s32 param, int owner, const u8 *data)) { struct widget *w, *bar; g_error e; e = rdhandle((void **) &bar, PG_TYPE_WIDGET, self->owner, DATA->hbar); errorcheck; w = NULL; e = widget_derive(&w,h,PG_WIDGET_BUTTON,bar,DATA->hbar,PG_DERIVE_INSIDE,self->owner); errorcheck; w->callback = callback; w->callback_owner = self; widget_set(w, PG_WP_THOBJ_BUTTON, thobj); widget_set(w, PG_WP_THOBJ_BUTTON_ON, thobj_on); widget_set(w, PG_WP_THOBJ_BUTTON_HILIGHT, thobj_hilight); widget_set(w, PG_WP_THOBJ_BUTTON_ON_NOHILIGHT, thobj_on); widget_set(w, PG_WP_EXTDEVENTS, exev); return success; }
g_error tabpage_install(struct widget *self) { g_error e; struct widget *tab; WIDGET_INSTALL_PARENT(PG_WIDGET_BOX); WIDGET_ALLOC_DATA(tabpagedata); /* Set custom defaults */ e = widget_base_set(self, PG_WP_THOBJ, PGTH_O_TAB_PAGE); errorcheck; e = widget_base_set(self, PG_WP_SIZE, 0); errorcheck; /* Go ahead and create the tab. We will attach the tab * later when we're attached ourselves, but create it early so the * properties can be set. */ e = widget_create(&tab, &DATA->htab, PG_WIDGET_BUTTON, self->dt, self->container, self->owner); errorcheck; e = widget_set(tab, PG_WP_EXTDEVENTS, PG_EXEV_TOGGLE | PG_EXEV_EXCLUSIVE); errorcheck; e = widget_set(tab, PG_WP_THOBJ_BUTTON, PGTH_O_TAB); errorcheck; e = widget_set(tab, PG_WP_THOBJ_BUTTON_HILIGHT, PGTH_O_TAB_HILIGHT); errorcheck; e = widget_set(tab, PG_WP_THOBJ_BUTTON_ON, PGTH_O_TAB_ON); errorcheck; e = widget_set(tab, PG_WP_THOBJ_BUTTON_ON_NOHILIGHT, PGTH_O_TAB_ON_NOHILIGHT); errorcheck; tab->callback = &tabpage_tab_callback; tab->callback_owner = self; return success; }
void panel_resize(struct widget *self) { struct widget *bar = NULL; rdhandle((void **) &bar, PG_TYPE_WIDGET, self->owner, DATA->hbar); if (DATA->margin_override) DATA->bg->split = DATA->margin; else DATA->bg->split = theme_lookup(DATA->bg->state,PGTH_P_MARGIN); self->in->div->split = theme_lookup(DATA->bg->state,PGTH_P_BORDER_SIZE); /* The minimum setting on the panelbar needs to leave room for the margin * on both sides, and the panelbar width itself. */ if (bar) widget_set(bar, PG_WP_MINIMUM, widget_get(bar, PG_WP_SIZE) + (self->in->div->split << 1)); }
g_error checkbox_install(struct widget *self) { g_error e; /* Start with a button */ e = button_install(self); errorcheck; /* Customize */ widget_set(self, PG_WP_THOBJ_BUTTON, PGTH_O_CHECKBOX); widget_set(self, PG_WP_THOBJ_BUTTON_ON, PGTH_O_CHECKBOX_ON); widget_set(self, PG_WP_THOBJ_BUTTON_HILIGHT, PGTH_O_CHECKBOX_HILIGHT); widget_set(self, PG_WP_THOBJ_BUTTON_ON_NOHILIGHT, PGTH_O_CHECKBOX_ON_NOHILIGHT); /* Use alternate click event handling to toggle */ widget_set(self,PG_WP_EXTDEVENTS,PG_EXEV_TOGGLE); /* Stack vertically */ widget_set(self,PG_WP_SIDE,PG_S_TOP); return success; }
/* This is called whenever the widget is attached, after the attaching * process is complete. We use this as a hook for managing the tab and tab_bar. */ g_error tabpage_post_attach(struct widget *self, struct widget *parent, int rship) { struct widget *tab, *tab_bar, *parent_tab; g_error e; handle existing_bar = 0; /* Dereference handles */ e = rdhandle((void**)&tab, PG_TYPE_WIDGET, self->owner, DATA->htab); errorcheck; e = rdhandle((void**)&tab_bar, PG_TYPE_WIDGET, self->owner, DATA->htab_bar); errorcheck; /* Detach our tab. It will be reattached later if necessary */ e = widget_derive(&tab, &DATA->htab, tab->type, NULL, 0, 0, self->owner); errorcheck; /* If we already have a tab bar but it's empty, delete it */ if (DATA->htab_bar && !widget_traverse(tab_bar, PG_TRAVERSE_CHILDREN, 0)) { handle_free(self->owner, DATA->htab_bar); DATA->htab_bar = 0; } /* Are we being attached rather than detached? */ if (parent) { /* If we're attaching before or after another tab page, share its tab bar */ if (parent->type==PG_WIDGET_TABPAGE && (rship==PG_DERIVE_BEFORE || rship==PG_DERIVE_AFTER)) { struct widget *self = parent; existing_bar = DATA->htab_bar; } DATA->htab_bar = existing_bar; /* Otherwise, create a new tab bar */ if (!DATA->htab_bar) { tab_bar = NULL; e = widget_derive(&tab_bar, &DATA->htab_bar, PG_WIDGET_TOOLBAR, self, self->h, PG_DERIVE_BEFORE, self->owner); errorcheck; e = widget_set(tab_bar, PG_WP_THOBJ, PGTH_O_TAB_BAR); errorcheck; tab_bar->auto_orientation = PG_AUTO_SIDE; } /* If we're attaching on an existing bar, attach the tab in the same * relative order as the tab pages themselves. */ parent_tab = NULL; rdhandle((void**)&parent_tab, PG_TYPE_WIDGET, self->owner, widget_get(parent, PG_WP_TAB)); if (existing_bar && parent_tab) { e = widget_derive(&tab, &DATA->htab, tab->type, parent_tab, parent_tab->h, rship, self->owner); errorcheck; } /* Otherwise just put it in our tab bar directly */ else { e = widget_derive(&tab, &DATA->htab, tab->type, tab_bar, tab_bar->h, PG_DERIVE_INSIDE, self->owner); errorcheck; } /* If we were here first, make ourselves active */ if (!existing_bar) { e = widget_set(self, PG_WP_ON, 1); errorcheck; } } return success; }
g_error widget_base_set(struct widget *w, int property, glob data) { char *str; struct divnode *maindiv = w->in->div ? w->in->div : w->in; switch (property) { /* Set the size, assuming initial split at w->in. * Calls resize handler if it exists, and sets the * appropriate flags. */ case PG_WP_SIDE: if (!VALID_SIDE(data)) return mkerror(PG_ERRT_BADPARAM,2); w->in->flags &= SIDEMASK; w->in->flags |= ((sidet)data) | DIVNODE_NEED_RECALC; resizewidget(w); w->dt->flags |= DIVTREE_NEED_RECALC; redraw_bg(w); if (w->auto_orientation) { /* Set orientation on all child widgets */ struct widget *p; p = widget_traverse(w, PG_TRAVERSE_CHILDREN, 0); while (p) { switch (data) { case PG_S_LEFT: case PG_S_RIGHT: if (w->auto_orientation & PG_AUTO_DIRECTION) widget_set(p, PG_WP_DIRECTION, PG_DIR_VERTICAL); if (w->auto_orientation & PG_AUTO_SIDE) switch (widget_get(p, PG_WP_SIDE)) { case PG_S_LEFT: widget_set(p, PG_WP_SIDE, PG_S_TOP); break; case PG_S_RIGHT: widget_set(p, PG_WP_SIDE, PG_S_BOTTOM); break; } break; case PG_S_TOP: case PG_S_BOTTOM: if (w->auto_orientation & PG_AUTO_DIRECTION) widget_set(p, PG_WP_DIRECTION, PG_DIR_HORIZONTAL); if (w->auto_orientation & PG_AUTO_SIDE) switch (widget_get(p, PG_WP_SIDE)) { case PG_S_TOP: widget_set(p, PG_WP_SIDE, PG_S_LEFT); break; case PG_S_BOTTOM: widget_set(p, PG_WP_SIDE, PG_S_RIGHT); break; } break; } p = widget_traverse(p, PG_TRAVERSE_FORWARD,1); } } break; case PG_WP_SIZE: if (data<0) { /* Automatic sizing */ w->in->flags |= DIVNODE_SIZE_AUTOSPLIT; w->dt->flags |= DIVTREE_NEED_RESIZE; } else { w->in->split = data; w->in->flags &= ~DIVNODE_SIZE_AUTOSPLIT; /* No auto resizing */ } w->in->flags |= DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_RECALC; redraw_bg(w); break; case PG_WP_SIZEMODE: w->in->flags &= ~DIVNODE_SIZE_AUTOSPLIT; /* No auto resizing */ w->in->flags &= ~PG_SZMODEMASK; w->in->flags |= data & PG_SZMODEMASK; redraw_bg(w); break; case PG_WP_SCROLL_X: if (data > w->in->child.w - w->in->r.w) data = w->in->child.w - w->in->r.w; if (data < 0) data = 0; if (maindiv->translation.x != -data) { maindiv->translation.x = -data; maindiv->flags |= DIVNODE_SCROLL_ONLY | DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_REDRAW; hotspot_free(); } maindiv->flags |= DIVNODE_DIVSCROLL | DIVNODE_EXTEND_WIDTH; break; case PG_WP_SCROLL_Y: if (data > w->in->child.h - w->in->r.h) data = w->in->child.h - w->in->r.h; if (data < 0) data = 0; if (maindiv->translation.y != -data) { maindiv->translation.y = -data; maindiv->flags |= DIVNODE_SCROLL_ONLY | DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_REDRAW; hotspot_free(); } maindiv->flags |= DIVNODE_DIVSCROLL | DIVNODE_EXTEND_HEIGHT; break; case PG_WP_NAME: if (iserror(rdhandle((void **)&str,PG_TYPE_PGSTRING,-1,data))) return mkerror(PG_ERRT_HANDLE,18); w->name = handle_canonicalize((handle) data); break; case PG_WP_PUBLICBOX: w->publicbox = data; break; case PG_WP_BIND: w->scrollbind = data; break; case PG_WP_THOBJ: maindiv->state = data; resizewidget(w); w->in->flags |= DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_RECALC; break; case PG_WP_TRIGGERMASK: w->trigger_mask = data; break; case PG_WP_HILIGHTED: { struct widget *p; // // Pass the message onto the other sub widgets // p = widget_traverse(w, PG_TRAVERSE_CHILDREN, 0); while (p) { widget_set(p, PG_WP_HILIGHTED, data); p = widget_traverse(p, PG_TRAVERSE_FORWARD,1); } } break; case PG_WP_AUTO_ORIENTATION: w->auto_orientation = data; break; default: return mkerror(PG_ERRT_BADPARAM,6); /* Unknown property */ } return success; }
/** Create contents of the accept dialog in here. @return 0 if success, -1 on errors. */ int nhdlg_create_content(void) { /* Variables. */ GtkWidget *window = (GtkWidget *)widget(ID_NHDLG); GtkWidget *frame, *w, *vb, *vb1, *vb2, *sw, *hb, *hp, *exp; gtk_container_set_border_width(GTK_CONTAINER(window), 1); /* Create remote HIT info. */ frame = gtk_frame_new(NULL); gtk_frame_set_label(GTK_FRAME(frame), lang_get("nhdlg-newinfo")); gtk_frame_set_label_align(GTK_FRAME(frame), 0.0, 0.0); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), frame, TRUE, TRUE, 3); gtk_widget_show(GTK_WIDGET(frame)); /* This box is for adding everything inside previous frame. */ vb = gtk_vbox_new(FALSE, 1); gtk_container_add(GTK_CONTAINER(frame), vb); gtk_widget_show(GTK_WIDGET(vb)); /* Now create basic information. */ hb = gtk_hbox_new(FALSE, 1); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 3); gtk_widget_show(GTK_WIDGET(hb)); w = gtk_label_new(lang_get("nhdlg-newhit")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 3); gtk_widget_show(GTK_WIDGET(w)); w = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 3); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_HIT, w); gtk_tooltips_set_tip(widget(ID_TOOLTIPS), w, lang_get("nhdlg-tt-hit"), lang_get("nhdlg-tt-hit-priv")); hb = gtk_hbox_new(FALSE, 1); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 3); gtk_widget_show(GTK_WIDGET(hb)); w = gtk_label_new(lang_get("nhdlg-name")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 3); gtk_widget_show(GTK_WIDGET(w)); w = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(w), ""); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 3); gtk_entry_set_activates_default(GTK_ENTRY(w), TRUE); gtk_entry_set_max_length(GTK_ENTRY(w), MAX_NAME_LEN); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_NAME, w); w = gtk_label_new(lang_get("nhdlg-group")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 3); gtk_widget_show(GTK_WIDGET(w)); w = gtk_combo_box_new_text(); g_signal_connect(w, "changed", G_CALLBACK(button_event), (gpointer)IDB_NH_RGROUPS); widget_set(ID_NH_RGROUP, w); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 3); gtk_widget_show(GTK_WIDGET(w)); /* Separator between basic and advanced. */ w = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vb), w, FALSE, FALSE, 2); gtk_widget_show(GTK_WIDGET(w)); /* Advanced information. */ exp = gtk_expander_new(lang_get("nhdlg-advanced")); gtk_box_pack_start(GTK_BOX(vb), exp, FALSE, TRUE, 2); gtk_widget_show(GTK_WIDGET(exp)); widget_set(ID_NH_EXPANDER, exp); g_signal_connect(exp, "activate", G_CALLBACK(button_event), (gpointer)IDB_NH_EXPANDER); g_signal_connect(exp, "check-resize", G_CALLBACK(button_event), (gpointer)IDB_NH_EXPANDER); vb2 = gtk_vbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(exp), vb2); gtk_widget_show(GTK_WIDGET(vb2)); hb = gtk_hbox_new(FALSE, 1); gtk_box_pack_start(GTK_BOX(vb2), hb, FALSE, FALSE, 1); gtk_widget_show(GTK_WIDGET(hb)); /* w = gtk_label_new(lang_get("nhdlg-url")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 5); gtk_widget_show(GTK_WIDGET(w)); w = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(w), ""); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 5); gtk_entry_set_max_length(GTK_ENTRY(w), MAX_URL_LEN); gtk_entry_set_activates_default(GTK_ENTRY(w), TRUE); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_URL, w);*/ /* w = gtk_label_new(lang_get("nhdlg-port")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 5); gtk_widget_show(GTK_WIDGET(w)); w = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(w), "0"); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, TRUE, 5); gtk_widget_set_size_request(GTK_WIDGET(w), 70, -1); gtk_entry_set_max_length(GTK_ENTRY(w), 8); gtk_entry_set_activates_default(GTK_ENTRY(w), TRUE); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_PORT, w);*/ frame = gtk_frame_new(NULL); gtk_frame_set_label(GTK_FRAME(frame), lang_get("nhdlg-g-info")); gtk_frame_set_label_align(GTK_FRAME(frame), 0.0, 0.0); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); gtk_box_pack_start(GTK_BOX(vb2), frame, FALSE, FALSE, 1); gtk_widget_show(GTK_WIDGET(frame)); vb2 = gtk_vbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(frame), vb2); gtk_widget_show(GTK_WIDGET(vb2)); hb = gtk_hbox_new(FALSE, 1); gtk_box_pack_start(GTK_BOX(vb2), hb, FALSE, FALSE, 1); gtk_widget_show(GTK_WIDGET(hb)); w = gtk_label_new(lang_get("nhdlg-g-localhit")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 5); gtk_widget_show(GTK_WIDGET(w)); w = gtk_combo_box_new_text(); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 1); gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_LOCAL, w); hb = gtk_hbox_new(FALSE, 1); gtk_box_pack_start(GTK_BOX(vb2), hb, FALSE, FALSE, 1); gtk_widget_show(GTK_WIDGET(hb)); w = gtk_label_new(lang_get("nhdlg-g-type")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 5); gtk_widget_show(GTK_WIDGET(w)); w = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(w), lang_get("group-type-accept")); gtk_combo_box_append_text(GTK_COMBO_BOX(w), lang_get("group-type-deny")); gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 1); gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_TYPE1, w); w = gtk_label_new(lang_get("nhdlg-g-lightweight")); gtk_box_pack_start(GTK_BOX(hb), w, FALSE, FALSE, 5); gtk_widget_show(GTK_WIDGET(w)); w = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(w), lang_get("group-type2-normal")); gtk_combo_box_append_text(GTK_COMBO_BOX(w), lang_get("group-type2-lightweight")); gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0); gtk_box_pack_start(GTK_BOX(hb), w, TRUE, TRUE, 1); gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE); gtk_widget_show(GTK_WIDGET(w)); widget_set(ID_NH_TYPE2, w); return (0); }
g_error panel_install(struct widget *self) { struct widget *bar, *title; g_error e; WIDGET_ALLOC_DATA(paneldata); /* This split determines the size of the main panel area */ e = newdiv(&self->in,self); errorcheck; self->in->flags &= ~(DIVNODE_SIZE_AUTOSPLIT | DIVNODE_SIZE_RECURSIVE); self->in->flags |= PG_S_TOP; /* An optional border inside that main panel area */ e = newdiv(&self->in->div,self); errorcheck; self->in->div->flags &= ~(DIVNODE_SIZE_AUTOSPLIT | DIVNODE_SIZE_RECURSIVE); self->in->div->flags |= DIVNODE_SPLIT_BORDER; self->in->div->build = &build_panel_border; /* Create the panelbar widget */ e = widget_create(&bar,&DATA->hbar,PG_WIDGET_PANELBAR, self->dt,self->container,self->owner); errorcheck; e = widget_attach(bar,self->dt,&self->in->div->div,0); errorcheck; e = widget_set(bar,PG_WP_BIND,self->h); errorcheck; /* This draws the panel background */ e = newdiv(bar->out,self); errorcheck; DATA->bg = *bar->out; DATA->bg->flags |= DIVNODE_SPLIT_BORDER; DATA->bg->flags &= ~DIVNODE_SIZE_AUTOSPLIT; DATA->bg->build = &build_bgfill_only; DATA->bg->state = PGTH_O_PANEL; /* Set up us the container! */ self->out = &self->in->next; self->sub = &DATA->bg->div; /* Firstly, create a label widget in the panelbar to present the title */ title = NULL; e = widget_derive(&title,&DATA->hlabel,PG_WIDGET_LABEL,bar,DATA->hbar, PG_DERIVE_INSIDE,self->owner); errorcheck; widget_set(title,PG_WP_SIDE,PG_S_ALL); widget_set(title,PG_WP_THOBJ,PGTH_O_PANELBAR); /* Nextly, create the standard buttons for a panel app */ e = panel_std_button(&DATA->hzoom, self, PGTH_O_ZOOMBTN, PGTH_O_ZOOMBTN_ON, PGTH_O_ZOOMBTN_HILIGHT, PG_EXEV_TOGGLE, &panel_zoom_callback); errorcheck; e = panel_std_button(&DATA->hrotate, self, PGTH_O_ROTATEBTN, PGTH_O_ROTATEBTN_ON, PGTH_O_ROTATEBTN_HILIGHT, 0, &panel_rotate_callback); errorcheck; e = panel_std_button(&DATA->hclose, self, PGTH_O_CLOSEBTN, PGTH_O_CLOSEBTN_ON, PGTH_O_CLOSEBTN_HILIGHT, 0, &panel_close_callback); errorcheck; /* Make sure we default to our minimum rolled-up size */ widget_set(self, PG_WP_SIZE, 0); return success; }
void panelbar_trigger_solid(struct widget *self,s32 type,union trigparam *param) { bool force = 0; struct widget *boundwidget; int s; switch (type) { case PG_TRIGGER_ENTER: DATA->over = 1; break; case PG_TRIGGER_LEAVE: DATA->over=0; break; case PG_TRIGGER_DOWN: if (param->mouse.chbtn != 1) return; /* If we're bound to another widget (we should be) save its current size */ if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { DATA->oldsize = widget_get(boundwidget,PG_WP_SIZE); /* To make things easier during dragging, * get the effective split to equal the split */ widget_set(boundwidget, PG_WP_SIZEMODE, PG_SZMODE_PIXEL); widget_set(boundwidget, PG_WP_SIZE, panel_effective_split(boundwidget->in)); } DATA->on = 1; DATA->x = param->mouse.x; DATA->y = param->mouse.y; DATA->draglen = 0; break; case PG_TRIGGER_UP: case PG_TRIGGER_RELEASE: if (!DATA->on) return; if (!(param->mouse.chbtn & 1)) return; if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { if (DATA->draglen < MINDRAGLEN) { /* This was a click, not a drag */ DATA->over = 0; widget_set(boundwidget,PG_WP_SIZEMODE,PG_SZMODE_PIXEL); if (DATA->oldsize > DATA->minimum) /* Roll up the panel */ widget_set(boundwidget,PG_WP_SIZE,DATA->minimum); else /* Unroll the panel */ widget_set(boundwidget,PG_WP_SIZE,DATA->unrolled); update(NULL,1); } else { s = panel_effective_split(boundwidget->in); /* Save this as the new unrolled split, * Unless the user manually rolled up the panel */ if ((s-DATA->minimum) > MAXROLLUP) DATA->unrolled = s; else s = DATA->minimum; } } DATA->on = 0; break; case PG_TRIGGER_MOVE: case PG_TRIGGER_DRAG: if (!DATA->on) return; if (panel_throttle(self)) return; if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { s = panel_calcsplit(self,param->mouse.x,param->mouse.y, widget_get(boundwidget,PG_WP_SIDE)); DATA->draglen += abs(s); if (s) { s += boundwidget->in->split; /* FIXME: This isn't quite right, in solid dragging mode the panelbar * can get out of sync with the cursor when this s < DATA->minimum code * comes into effect. */ if (s < DATA->minimum) s = DATA->minimum; else { DATA->x = param->mouse.x; DATA->y = param->mouse.y; } widget_set(boundwidget, PG_WP_SIZE,s); update(NULL,1); } } return; } themeify_panelbar(self,force); }
void panelbar_trigger_sprite(struct widget *self,s32 type,union trigparam *param) { bool force = 0; struct widget *boundwidget; int s; switch (type) { case PG_TRIGGER_ENTER: DATA->over = 1; break; case PG_TRIGGER_LEAVE: /* If we're dragging, the mouse didn't REALLY leave */ if (DATA->on) return; DATA->over=0; break; case PG_TRIGGER_DOWN: if (param->mouse.chbtn != 1) return; /* If we're bound to another widget (we should be) save its current size */ if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { DATA->oldsize = widget_get(boundwidget,PG_WP_SIZE); /* If we're not rolled up, save this as the unrolled split */ if (DATA->oldsize > DATA->minimum) DATA->unrolled = DATA->oldsize; } DATA->on = 1; DATA->x = param->mouse.x; DATA->y = param->mouse.y; DATA->draglen = 0; /* Update the screen now, so we have an up-to-date picture of the panelbar stored in DATA->s */ themeify_panelbar(self,1); VID(sprite_hideall) (); /* This line combined with the zero flag on */ update(NULL,0); /* the next gets a clean spriteless grab */ /* In case there was no release trigger (bug in input driver) */ if (DATA->s) { free_sprite(DATA->s); DATA->s = NULL; } if (DATA->sbit) { VID(bitmap_free) (DATA->sbit); DATA->sbit = NULL; } /* Allocate the new sprite */ if(iserror(new_sprite(&DATA->s,self->dt,DATA->panelbar->r.w,DATA->panelbar->r.h))) { DATA->s = NULL; return; } if (iserror(VID(bitmap_new) (&DATA->sbit,DATA->panelbar->r.w,DATA->panelbar->r.h,vid->bpp))) { free_sprite(DATA->s); DATA->s = NULL; DATA->sbit = NULL; return; } DATA->s->bitmap = &DATA->sbit; /* Grab a bitmap of the panelbar to use as the sprite */ VID(blit) (DATA->sbit,0,0,DATA->panelbar->r.w,DATA->panelbar->r.h, self->dt->display,DATA->s->x = DATA->panelbar->r.x,DATA->s->y = DATA->panelbar->r.y, PG_LGOP_NONE); /* Clip the sprite to the travel allowed by boundwidget's parent */ if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { DATA->s->clip_to = boundwidget->in; } return; case PG_TRIGGER_UP: case PG_TRIGGER_RELEASE: if (!DATA->on) return; if (!(param->mouse.chbtn & 1)) return; if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner, DATA->bindto)) && boundwidget) { s = panel_calcsplit(self,param->mouse.x,param->mouse.y, widget_get(boundwidget,PG_WP_SIDE)); if (DATA->draglen < MINDRAGLEN) { /* This was a click, not a drag */ DATA->over = 0; widget_set(boundwidget,PG_WP_SIZEMODE,PG_SZMODE_PIXEL); if (DATA->oldsize > DATA->minimum) /* Roll up the panel */ widget_set(boundwidget,PG_WP_SIZE,DATA->minimum); else /* Unroll the panel */ widget_set(boundwidget,PG_WP_SIZE,DATA->unrolled); } else { s += panel_effective_split(boundwidget->in); /* Save this as the new unrolled split, * Unless the user manually rolled up the panel */ if ((s-DATA->minimum) > MAXROLLUP) DATA->unrolled = s; else s = DATA->minimum; widget_set(boundwidget,PG_WP_SIZEMODE,PG_SZMODE_PIXEL); widget_set(boundwidget,PG_WP_SIZE,s); DATA->over = 1; } } VID(bitmap_free) (DATA->sbit); free_sprite(DATA->s); DATA->s = NULL; DATA->sbit = NULL; force = 1; /* Definitely draw the new position */ DATA->on = 0; break; case PG_TRIGGER_MOVE: case PG_TRIGGER_DRAG: if (!DATA->on) return; /* Ok, button 1 is dragging through our widget... */ if (panel_throttle(self)) return; /* Race condition prevention? * Without this, sometimes segfaults because DATA->s is NULL. * Possibly events_pending() triggered another event? */ if (!DATA->s) return; /* Determine where to blit the bar to... */ switch (self->in->flags & (~SIDEMASK)) { case PG_S_TOP: case PG_S_BOTTOM: DATA->s->x = DATA->panelbar->r.x; DATA->draglen += abs(param->mouse.y - DATA->y + DATA->panelbar->r.y - DATA->s->y); DATA->s->y = param->mouse.y - DATA->y + DATA->panelbar->r.y; break; case PG_S_LEFT: case PG_S_RIGHT: DATA->s->y = DATA->panelbar->r.y; DATA->draglen += abs(param->mouse.x - DATA->x + DATA->panelbar->r.x - DATA->s->x); DATA->s->x = param->mouse.x - DATA->x + DATA->panelbar->r.x; break; } /* Reposition sprite */ VID(sprite_update) (DATA->s); return; } themeify_panelbar(self,force); }