Esempio n. 1
0
/*!
 * \brief Parse _DiaObject from the given node
 * Fill a GList* with objects which is to be put in a
 * diagram or a group by the caller. 
 * Can be called recursively to allow groups in groups.
 * This is only using the render branch of the file, if the
 * object type is not registered with Dia. Otherwise the objects
 * are just created from their type and properties.
 * \ingroup DiaRenderScriptImport
 */
static GList*
read_items (xmlNodePtr startnode, DiaContext *ctx)
{
  xmlNodePtr node;
  GList *items = NULL;

  for (node = startnode; node != NULL; node = node->next) {
    if (xmlIsBlankNode(node)) 
      continue;
    if (node->type != XML_ELEMENT_NODE)
      continue;
    if (!xmlStrcmp(node->name, (const xmlChar *)"object")) {
      xmlChar *sType = xmlGetProp(node, (const xmlChar *)"type");
      const DiaObjectType *ot = object_get_type ((gchar *)sType);
      xmlNodePtr props = NULL, render = NULL;
      
      props = find_child_named (node, "properties");
      render = find_child_named (node, "render");

      if (ot && !ot->ops) {
	GList *moreitems;
        /* FIXME: 'render' is also the grouping element */
	moreitems = read_items (render->children, ctx);
	if (moreitems) {
	  DiaObject *group = group_create (moreitems);
	    /* apply group props, e.g. transform */
	  object_load_props (group, props, ctx);
	    /* group eats list */
	  items = g_list_append (items, group);
	}
      } else if (ot) {
        Point startpoint = {0.0,0.0};
        Handle *handle1,*handle2;
	DiaObject *o;

	o = ot->ops->create(&startpoint, 
                            ot->default_user_data, 
			    &handle1,&handle2);
	if (o) {
	  object_load_props (o, props, ctx);
	  items = g_list_append (items, o);
	}
      } else if (render) {
        DiaObject *o = _render_object (render, ctx);
	if (o)
	  items = g_list_append (items, o);
      } else {
	g_debug ("DRS-Import: %s?", node->name);
      }
    } else {
      g_debug ("DRS-Import: %s?", node->name);
    }
  }
  return items;
}
static void _render_button(GRAPHICS_CONTROLLER *gc, BD_IG_BUTTON *button, BD_PG_PALETTE *palette,
                           int state, BOG_DATA *bog_data)
{
    BD_PG_OBJECT *object = _find_object_for_button(gc->igs, button, state, bog_data);
    if (!object) {
        GC_TRACE("_render_button(#%d): object (state %d) not found\n", button->id, state);

        _clear_bog_area(gc, bog_data);

        return;
    }

    /* object already rendered ? */
    if (bog_data->visible_object_id == object->id &&
        bog_data->x == button->x_pos && bog_data->y == button->y_pos &&
        bog_data->w == object->width && bog_data->h == object->height) {

        GC_TRACE("skipping already rendered button #%d (object #%d at %d,%d %dx%d)\n",
                 button->id, object->id,
                 button->x_pos, button->y_pos, object->width, object->height);

        return;
    }

    /* new object is smaller than already drawn one ? -> need to render background */
    if (bog_data->w > object->width ||
        bog_data->h > object->height) {

        /* make sure we won't wipe other buttons */
        unsigned ii, skip = 0;
        for (ii = 0; &gc->bog_data[ii] != bog_data; ii++) {
            if (_areas_overlap(bog_data, &gc->bog_data[ii]))
                skip = 1;
            /* FIXME: clean non-overlapping area */
        }

        GC_TRACE("object size changed, %sclearing background at %d,%d %dx%d\n",
                 skip ? " ** NOT ** " : "",
                 bog_data->x, bog_data->y, bog_data->w, bog_data->h);

        if (!skip) {
            _clear_bog_area(gc, bog_data);
        }
    }

    GC_TRACE("render button #%d using object #%d at %d,%d %dx%d\n",
             button->id, object->id,
             button->x_pos, button->y_pos, object->width, object->height);

    _render_object(gc, -1, BD_OVERLAY_IG,
                   button->x_pos, button->y_pos,
                   object, palette);

    bog_data->x = button->x_pos;
    bog_data->y = button->y_pos;
    bog_data->w = object->width;
    bog_data->h = object->height;
    bog_data->visible_object_id = object->id;

    gc->ig_drawn = 1;
    gc->ig_dirty = 1;
}