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; }
glob widget_base_get(struct widget *w, int property) { struct divnode *maindiv = w->in->div ? w->in->div : w->in; /* handle some universal properties */ switch (property) { case PG_WP_ABSOLUTEX: /* Absolute coordinates */ /* activate_client_divnodes(w->owner); divtree_size_and_calc(w->dt); */ return maindiv->r.x; case PG_WP_ABSOLUTEY: /* activate_client_divnodes(w->owner); divtree_size_and_calc(w->dt); */ return maindiv->r.y; case PG_WP_WIDTH: /* Real width and height */ activate_client_divnodes(w->owner); divtree_size_and_calc(w->dt); return maindiv->calc.w; case PG_WP_HEIGHT: activate_client_divnodes(w->owner); divtree_size_and_calc(w->dt); return maindiv->calc.h; case PG_WP_SCROLL_X: return -maindiv->translation.x; case PG_WP_SCROLL_Y: return -maindiv->translation.y; case PG_WP_SIDE: return w->in->flags & (~SIDEMASK); case PG_WP_SIZE: return w->in->split; case PG_WP_NAME: return w->name; case PG_WP_PUBLICBOX: return w->publicbox; case PG_WP_STATE: return maindiv->state; case PG_WP_BIND: return w->scrollbind; case PG_WP_TRIGGERMASK: return w->trigger_mask; case PG_WP_PREFERRED_W: resizewidget(w); return max(maindiv->preferred.w, maindiv->child.w); case PG_WP_PREFERRED_H: resizewidget(w); return max(maindiv->preferred.h, maindiv->child.h); case PG_WP_AUTO_ORIENTATION: return w->auto_orientation; case PG_WP_TYPE: return w->type; } return 0; }
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; }
g_error widget_attach(struct widget *w, struct divtree *dt,struct divnode **where, handle container) { DBG("widget %p, container %d\n",w,container); if (!dt) dt = &fakedt; /* Recalc the old attach point */ if (w->dt && w->dt->head) { w->dt->head->flags |= DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_RECALC | DIVTREE_NEED_RESIZE; } /* Change the container and divtree of this and all child widgets */ if (w->sub) r_widget_setcontainer(*w->sub,w->container,container,dt); w->dt = dt; w->container = container; /* If this widget is already in the divtree, remove it */ if (w->out) { if (w->where) *w->where = *w->out; /* Make sure that the attachment point is connected to the _beginning_ * of another widget. (Necessary to prevent improper detachment when * a widget is embedded within another) */ if (*w->out && (*w->out)->owner && (*w->out)==(*w->out)->owner->in) (*w->out)->owner->where = w->where; *w->out = NULL; } else if (w->where) *w->where = NULL; /* Take off all the unnecessary divscroll flags */ r_div_unscroll(w->in); /* Add the widget to the divtree */ w->where = where; if (where) { *w->out = *where; *where = w->in; if (w->out && *w->out && (*w->out)->owner) { (*w->out)->owner->where = w->out; } /* If we just added a widget that can accept text input, and this is inside * a popup box, keep it in the nontoolbar area so keyboards still work */ if ((w->trigger_mask & PG_TRIGGER_NONTOOLBAR) && dt->head->next && dt->head->next->div && dt->head->next->div->owner->type == PG_WIDGET_POPUP) { dt->head->next->div->flags |= DIVNODE_POPUP_NONTOOLBAR; } /* Resize for the first time */ resizewidget(w); } /* Recalc the new attach point */ if (dt && dt->head) { dt->head->flags |= DIVNODE_NEED_RECALC; dt->flags |= DIVTREE_NEED_RECALC | DIVTREE_NEED_RESIZE; } return success; }