Re: How to use gtk_render_handle on patterned widget?



On Mon, 2012-01-23 at 16:13 -0500, Peter Hurley wrote:
> Hi all,
> 
> I'm hoping to get some clarification regarding the semantics of
> gtk_render_handle. The stock theming engine renders the handle centered
> within the rectangle parameters (@x,y  width x height). Unfortunately,
> it also wipes the background with the pattern scaled to width x height.
> 
> What's the correct method to render the handle on, for example, the left
> side of a widget if the existing background is patterned?
> 
> The approach gnome-panel takes is:
> 	cairo_rectangle (cr,
> 			 frame->priv->handle_rect.x,
> 			 frame->priv->handle_rect.y,
> 			 frame->priv->handle_rect.width,
> 			 frame->priv->handle_rect.height);
> 	cairo_clip (cr);
> 	gtk_render_handle (context, cr,
> 			   0, 0,
> 			   gtk_widget_get_allocated_width (widget),
> 			   gtk_widget_get_allocated_height (widget));
> 
> Unfortunately, this often means that the handle is rendered outside the
> clip and not visible.
> 
> Without changing the theming engine, ISTM that the only way to draw a
> handle within a subarea of a patterned widget is to:
> 	set background to the widget pattern
> 	render background
> 	construct new subpattern from base widget pattern
> 	set background to the new subpattern
> 	render handle
> 
> Is this correct?

I figured this out. No need to clip and fill the entire widget.

First, rescale the pattern matrix to the rectangle into which to render
the handle. Second, only specify the rectangle for the handle itself.

Like this,
	context = gtk_widget_get_style_context (widget);
	state = gtk_widget_get_state_flags (widget);
	gtk_style_context_save (context);
	gtk_style_context_set_state (context, state);

	cairo_save (cr);

	/* Set the pattern transform so as to correctly render
	 * a patterned background with the handle
	 */
	gtk_style_context_get (context, state,
			       "background-image", &bg_pattern,
			       NULL);
	if (bg_pattern) {
		cairo_matrix_t ptm;

		cairo_matrix_init_translate (&ptm,
					   frame->priv->handle_rect.x,
					   frame->priv->handle_rect.y);
		cairo_matrix_scale (&ptm,
				    frame->priv->handle_rect.width,
				    frame->priv->handle_rect.height);
		cairo_pattern_set_matrix (bg_pattern, &ptm);
		cairo_pattern_destroy (bg_pattern);
	}

	gtk_render_handle (context, cr,
			   frame->priv->handle_rect.x,
			   frame->priv->handle_rect.y,
			   frame->priv->handle_rect.width,
			   frame->priv->handle_rect.height);
	cairo_restore (cr);

The solution isn't fully robust in that it doesn't address 2nd pattern
(like with prelight), but this does what I need.

Regards,
Peter Hurley


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]