Ejemplo n.º 1
0
void
html_cluealigned_init (HTMLClueAligned *aligned,
		       HTMLClueAlignedClass *klass,
		       HTMLObject *parent,
		       gint x, gint y,
		       gint max_width, gint percent)
{
	HTMLClue *clue;
	HTMLObject *object;

	clue = HTML_CLUE (aligned);
	object = HTML_OBJECT (aligned);

	html_clue_init (clue, HTML_CLUE_CLASS (klass));

	object->x = x;
	object->y = y;
	object->max_width = max_width;
	object->percent = percent;

	if (percent > 0)
		object->flags &= ~HTML_OBJECT_FLAG_FIXEDWIDTH;

	clue->valign = HTML_VALIGN_BOTTOM;
	clue->halign = HTML_HALIGN_LEFT;

	aligned->next_aligned = NULL;

	object->parent = parent;
	object->flags |= HTML_OBJECT_FLAG_ALIGNED;
}
Ejemplo n.º 2
0
void
html_cluev_init (HTMLClueV *cluev,
		 HTMLClueVClass *klass,
		 gint x, gint y,
		 gint percent)
{
	HTMLObject *object;
	HTMLClue *clue;

	object = HTML_OBJECT (cluev);
	clue = HTML_CLUE (cluev);

	html_clue_init (clue, HTML_CLUE_CLASS (klass));

	object->x = x;
	object->y = y;
	object->percent = percent;

	clue->valign = HTML_VALIGN_BOTTOM;
	clue->halign = HTML_HALIGN_NONE;
	cluev->dir = HTML_DIRECTION_DERIVED;
	clue->head = clue->tail = clue->curr = NULL;

	cluev->align_left_list = NULL;
	cluev->align_right_list = NULL;
	cluev->padding = 0;
	cluev->border_style = HTML_BORDER_NONE;
	cluev->border_width = 0;
	cluev->border_color = NULL;
	cluev->background_color = NULL;
}
Ejemplo n.º 3
0
HTMLTableCell *
html_engine_new_cell (HTMLEngine *e,
                      HTMLTable *table)
{
	HTMLObject    *cell;
	HTMLObject    *text;
	HTMLObject    *flow;

	cell  = html_table_cell_new (1, 1, table->padding);
	flow  = html_clueflow_new (HTML_CLUEFLOW_STYLE_NORMAL, g_byte_array_new (),
				   HTML_LIST_TYPE_UNORDERED, 0, HTML_CLEAR_NONE);
	text  = html_engine_new_text_empty (e);

	html_clue_append (HTML_CLUE (flow), text);
	html_clue_append (HTML_CLUE (cell), flow);

	return HTML_TABLE_CELL (cell);
}
Ejemplo n.º 4
0
static void
set_max_width (HTMLObject *o, HTMLPainter *painter, gint max_width)
{
	HTMLObject *obj;

	o->max_width = max_width;
	max_width   -= 2 * (HTML_CLUEV (o)->padding + HTML_CLUEV (o)->border_width) * html_painter_get_pixel_size (painter);
	for (obj = HTML_CLUE (o)->head; obj != NULL; obj = obj->next)
		html_object_set_max_width (obj, painter, max_width);
}
Ejemplo n.º 5
0
static void
set_max_width (HTMLObject *o, HTMLPainter *painter, gint max_width)
{
	HTMLObject *obj;

	o->max_width = max_width;

	for (obj = HTML_CLUE (o)->head; obj != 0; obj = obj->next)
		html_object_set_max_width (obj, painter, max_width);
}
Ejemplo n.º 6
0
static void
set_max_height (HTMLObject *o, HTMLPainter *painter, gint height)
{
	HTMLClue *clue = HTML_CLUE (o);

	/* Is it necessary to calc size here? It doesn't seem to. */
	/* html_object_calc_size (o, painter, NULL); */
	if (o->ascent < height) {
		(* HTML_OBJECT_CLASS (parent_class)->set_max_height) (o, painter, height);
		clue->curr = NULL;
	}
}
Ejemplo n.º 7
0
static void
table_set_align (HTMLEngine *e,
                 HTMLTable *t,
                 HTMLHAlignType align,
                 HTMLUndoDirection dir)
{
	HTMLTableSetAttrUndo *undo;

	/* table gone */
	if (!t)
		return;

	g_return_if_fail (HTML_OBJECT (t)->parent);

	undo = attr_undo_new (HTML_TABLE_ALIGN);
	undo->attr.align = HTML_CLUE (HTML_OBJECT (t)->parent)->halign;

	if (align == HTML_HALIGN_NONE || align == HTML_HALIGN_CENTER) {
		if (HTML_IS_CLUEALIGNED (HTML_OBJECT (t)->parent)) {
			HTMLObject *aclue = HTML_OBJECT (t)->parent;

			html_clue_remove (HTML_CLUE (aclue), HTML_OBJECT (t));
			html_clue_append_after (HTML_CLUE (aclue->parent), HTML_OBJECT (t), aclue);
			html_clue_remove (HTML_CLUE (aclue->parent), aclue);
			html_object_destroy (aclue);
		}
	} else if (align == HTML_HALIGN_LEFT || align == HTML_HALIGN_RIGHT) {
		if (HTML_IS_CLUEFLOW (HTML_OBJECT (t)->parent)) {
			HTMLObject *aclue, *flow = HTML_OBJECT (t)->parent;

			html_clue_remove (HTML_CLUE (flow), HTML_OBJECT (t));
			aclue = html_cluealigned_new (NULL, 0, 0, flow->max_width, 100);
			html_clue_append (HTML_CLUE (flow), aclue);
			html_clue_append (HTML_CLUE (aclue), HTML_OBJECT (t));
		}
	} else
		g_assert_not_reached ();

	html_undo_add_action (e->undo, e,
			      html_undo_action_new ("Set table align", table_set_align_undo_action,
						    HTML_UNDO_DATA (undo),
						    html_cursor_get_position (e->cursor),
						    html_cursor_get_position (e->cursor)), dir);

	HTML_CLUE (HTML_OBJECT (t)->parent)->halign = align;
	html_object_change_set (HTML_OBJECT (t)->parent, HTML_CHANGE_ALL_CALC);
	html_engine_schedule_update (e);
}
Ejemplo n.º 8
0
static gboolean
html_clue_aligned_real_calc_size (HTMLObject *o, HTMLPainter *painter, GList **changed_objs)
{
	HTMLObject *obj;
	gboolean changed;
	gint old_width, old_ascent;

	changed = HTML_OBJECT_CLASS (&html_clue_class)->calc_size (o, painter, changed_objs);

	old_width = o->width;
	old_ascent = o->ascent;

	o->width = 0;
	o->ascent = ALIGN_BORDER;
	o->descent = 0;

	/* FIXME: Shouldn't it call `calc_size()' on the children first!?!  */

	for (obj = HTML_CLUE (o)->head; obj != 0; obj = obj->next) {
		if (obj->width > o->width)
			o->width = obj->width;

		o->ascent += obj->ascent + obj->descent;

		if (obj->x != ALIGN_BORDER) {
			obj->x = ALIGN_BORDER;
			changed = TRUE;
		}

		if (obj->y != o->ascent - obj->descent) {
			obj->y = o->ascent - obj->descent;
			changed = TRUE;
		}
	}

	o->ascent += ALIGN_BORDER;
	o->width += ALIGN_BORDER * 2;

	if (old_width != o->width || old_ascent != o->ascent)
		changed = TRUE;

	return changed;
}
Ejemplo n.º 9
0
static gboolean
relayout (HTMLObject *self,
	  HTMLEngine *engine,
	  HTMLObject *child)
{
	gint prev_width, prev_ascent, prev_descent;
	gboolean changed;

	if (html_engine_frozen (engine))
		return FALSE;

	if (child == NULL)
		child = HTML_CLUE (self)->head;
	html_object_calc_size (child, engine->painter, NULL);

	HTML_CLUE (self)->curr = NULL;

	prev_width = self->width;
	prev_ascent = self->ascent;
	prev_descent = self->descent;

	changed = html_cluev_do_layout (self, engine->painter, FALSE, NULL);
	if (changed)
		html_engine_queue_draw (engine, self);

	if (prev_width == self->width
	    && prev_ascent == self->ascent
	    && prev_descent == self->descent)
		return FALSE;

	if (self->parent == NULL) {
		/* FIXME resize the widget, e.g. scrollbars and such.  */
		html_engine_queue_draw (engine, self);

		/* FIXME extreme ugliness.  */
		self->x = 0;
		self->y = self->ascent;
	} else {
		/* Relayout our parent starting from us.  */
		if (!html_object_relayout (self->parent, engine, self))
			html_engine_queue_draw (engine, self);
	}

	/* If the object has shrunk, we have to clean the areas around
	   it so that we don't leave garbage on the screen.  FIXME:
	   this wastes some time if there is an object on the right of
	   or under this one.  */

	if (prev_ascent + prev_descent > self->ascent + self->descent)
		html_engine_queue_clear (engine,
					 self->x,
					 self->y + self->descent,
					 self->width,
					 (prev_ascent + prev_descent
					  - (self->ascent + self->descent)));

	if (prev_width > self->width)
		html_engine_queue_clear (engine,
					 self->x + self->width,
					 self->y - self->ascent,
					 prev_width - self->width,
					 self->ascent + self->descent);

	return TRUE;
}
Ejemplo n.º 10
0
static HTMLObject *
check_point (HTMLObject *self,
	     HTMLPainter *painter,
	     gint x, gint y,
	     guint *offset_return,
	     gboolean for_cursor)
{
	HTMLObject *p;
	HTMLObject *obj;
	HTMLClueAligned *clue;
	gint padding = HTML_CLUEV (self)->padding;

	if (x < self->x || x >= self->x + self->width
	    || y < self->y - self->ascent || y >= self->y + self->descent)
		return NULL;

	x = x - self->x;
	y = y - self->y + self->ascent;

	if (!for_cursor) {
		if (x < padding || y < padding) {
			if (offset_return)
				*offset_return = 0;
			return self;
		}
		if (x >= self->width - padding || y >= self->ascent + self->descent - padding) {
			if (offset_return)
				*offset_return = 1;
			return self;
		}
	}

	for (clue = HTML_CLUEALIGNED (HTML_CLUEV (self)->align_left_list);
	     clue != NULL;
	     clue = clue->next_aligned) {
		HTMLObject *parent;

		parent = HTML_OBJECT (clue)->parent;
		obj = html_object_check_point (HTML_OBJECT (clue),
					       painter,
					       x - parent->x,
					       y - parent->y + parent->ascent,
					       offset_return,
					       for_cursor);
		if (obj != NULL) {
			return obj;
		}
	}

	for (clue = HTML_CLUEALIGNED (HTML_CLUEV (self)->align_right_list);
	     clue != NULL;
	     clue = clue->next_aligned) {
		HTMLObject *parent;

		parent = HTML_OBJECT (clue)->parent;
		obj = html_object_check_point (HTML_OBJECT (clue),
					       painter,
					       x - parent->x,
					       y - parent->y + parent->ascent,
					       offset_return,
					       for_cursor);
		if (obj != NULL) {
			return obj;
		}
	}

	for (p = HTML_CLUE (self)->head; p != 0; p = p->next) {
		gint x1, y1;

		if (!for_cursor) {
			x1 = x;
			y1 = y;
		} else {
			if (x >= p->x + p->width) {
				x1 = MAX (0, p->x + p->width - 1);
			} else if (x < p->x) {
				x1 = p->x;
			} else {
				x1 = x;
			}

			if (p->next == NULL && y > p->y + p->descent - 1) {
				x1 = MAX (0, p->x + p->width - 1);
				y1 = p->y + p->descent - 1;
			} else if (p->prev == NULL && y < p->y - p->ascent) {
				y1 = p->y - p->ascent;
			} else {
				y1 = y;
			}
		}

		obj = html_object_check_point (p, painter, x1, y1, offset_return, for_cursor);
		if (obj != NULL)
			return obj;
	}

	if (!for_cursor) {
		if (x >= 0 && y >= 0 && x < self->width && y < self->ascent + self->descent) {
			if (offset_return) {
				if (x < self->width/2)
					*offset_return = 0;
				else
					*offset_return = 1;
			}
			return self;
		}
	}

	return NULL;
}
Ejemplo n.º 11
0
static gboolean
html_cluev_do_layout (HTMLObject *o, HTMLPainter *painter, gboolean calc_size, GList **changed_objs)
{
	HTMLClueV *cluev;
	HTMLClue *clue;
	HTMLObject *obj;
	HTMLObject *aclue;
	GList *local_changed_objs;
	gint lmargin;
	gboolean changed;
	gint old_width, old_ascent, old_descent;
	gint new_x;
	gint pixel_size;
	gint padding;
	gint padding2;
	gboolean first_change;
	gint first_y_off = 0;

	/* printf ("HTMLClueV::do_layout\n"); */

	cluev = HTML_CLUEV (o);
	clue = HTML_CLUE (o);

	pixel_size = html_painter_get_pixel_size (painter);
	padding    = pixel_size * (cluev->padding + cluev->border_width);
	padding2   = 2 * padding;

	old_width = o->width;
	old_ascent = o->ascent;
	old_descent = o->descent;

	changed = FALSE;
	first_change = TRUE;
	local_changed_objs = NULL;

	lmargin = get_lmargin (o, painter);

	/* If we have already called calc_size for the children, then just
	   continue from the last object done in previous call. */

	if (clue->curr != NULL) {
		if (clue->curr->prev)
			o->ascent = clue->curr->prev->y + clue->curr->prev->descent;
		else
			o->ascent = padding;
		remove_aligned_by_parent (cluev, clue->curr);
	} else {
		o->width = 0;
		o->ascent = padding;
		o->descent = 0;
		clue->curr = clue->head;
	}

	while (clue->curr != NULL) {
		gint old_y, old_y_off, new_y_off;
		/* Set an initial ypos so that the alignment stuff knows where
		   the top of this object is */
		old_y = clue->curr->y;
		old_y_off = clue->curr->y - clue->curr->ascent;
		clue->curr->y = o->ascent;

		switch (html_object_get_clear (clue->curr)) {
		case HTML_CLEAR_ALL: {
			gint y;

			do {
				y = clue->curr->y;
				clue->curr->y = html_clue_get_left_clear (clue, clue->curr->y);
				clue->curr->y = html_clue_get_right_clear (clue, clue->curr->y);
			} while (clue->curr->y != y);
			break;
		}
		case HTML_CLEAR_LEFT:
			clue->curr->y = html_clue_get_left_clear (clue, clue->curr->y);
			break;
		case HTML_CLEAR_RIGHT:
			clue->curr->y = html_clue_get_right_clear (clue, clue->curr->y);
			break;
		case HTML_CLEAR_NONE:
			break;
		case HTML_CLEAR_INHERIT:
			/* TODO */
			break;
		}

		o->ascent = clue->curr->y;
		lmargin = get_lmargin (o, painter);

		if (calc_size)
			changed |= html_object_calc_size (clue->curr, painter, changed_objs);

		if (o->width < clue->curr->width + padding2)
			o->width = clue->curr->width + padding2;
		o->ascent += clue->curr->ascent + clue->curr->descent;

		new_y_off = o->ascent - clue->curr->descent - clue->curr->ascent;
		if (clue->curr->x != lmargin || old_y_off != new_y_off) {
			if (changed_objs) {
				/* printf ("y: %d ", o->ascent - clue->curr->descent); */
				if (first_change) {
					first_change = FALSE;
					/* if it's new one (y == 0) clear from new y_off, else from old one or new one,
					   which one is higher */
					first_y_off = old_y && old_y_off < new_y_off ? old_y_off : new_y_off;
					/* printf ("\nfirst_y_off: %d x %d --> %d\n", old_y_off, new_y_off, first_y_off); */
				}
				html_object_add_to_changed (&local_changed_objs, clue->curr);
			}
		}
		clue->curr->x = lmargin;
		clue->curr->y = o->ascent - clue->curr->descent;

		clue->curr = clue->curr->next;
	}

	o->ascent += padding;

	/* Remember the last object so that we can start from here next time
	   we are called. */
	clue->curr = clue->tail;

	if (o->max_width != 0 && o->width < o->max_width)
		o->width = o->max_width;

	if (clue->halign == HTML_HALIGN_CENTER) {
		for (obj = clue->head; obj != 0; obj = obj->next) {
			new_x = lmargin + (o->width - obj->width - padding2) / 2;
			if (obj->x != new_x) {
				obj->x = new_x;
				changed = TRUE;
			}
		}
	} else if (clue->halign == HTML_HALIGN_RIGHT) {
		for (obj = clue->head; obj != 0; obj = obj->next) {
			new_x = lmargin + (o->width - obj->width - padding2);
			if (obj->x != new_x) {
				obj->x = new_x;
				changed = TRUE;
			}
		}
	}

	for (aclue = cluev->align_left_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) {
		if (aclue->y + aclue->parent->y - aclue->parent->ascent > o->ascent)
			o->ascent = aclue->y + aclue->parent->y - aclue->parent->ascent;
	}

	for (aclue = cluev->align_right_list; aclue != NULL; aclue = cluev_next_aligned (aclue)) {
		if (aclue->y + aclue->parent->y - aclue->parent->ascent > o->ascent)
			o->ascent = aclue->y + aclue->parent->y - aclue->parent->ascent;
	}

	if (!changed
	    && (o->ascent != old_ascent || o->descent != old_descent || o->width != old_width))
		changed = TRUE;

	if (changed_objs && local_changed_objs) {
		if (!first_change && o->width > o->max_width) {
			add_clear_area_behind (changed_objs, o, o->max_width, first_y_off,
					       o->width - o->max_width, o->ascent + o->descent - first_y_off);
		}
		*changed_objs = g_list_concat (local_changed_objs, *changed_objs);
	}

	return changed;
}