Пример #1
0
/* 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;
}
Пример #2
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;
}
Пример #3
0
/* 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;
}