/* * mini-label-preview.c * Copyright (C) 2009 Jim Evins . * * This file is part of gLabels. * * gLabels is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gLabels is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with gLabels. If not, see . */ #include #include "mini-label-preview.h" #include #include "cairo-label-path.h" #include "color.h" #include "marshal.h" /*===========================================*/ /* Private macros and constants. */ /*===========================================*/ #define MARGIN 2 #define SHADOW_OFFSET 3 /*===========================================*/ /* Private types */ /*===========================================*/ struct _glMiniLabelPreviewPrivate { lglTemplate *template; gboolean rotate_flag; }; /*===========================================*/ /* Private globals */ /*===========================================*/ /*===========================================*/ /* Local function prototypes */ /*===========================================*/ static void gl_mini_label_preview_finalize (GObject *object); static void style_set_cb (GtkWidget *widget, GtkStyle *previous_style); static void redraw (glMiniLabelPreview *this); static gboolean draw_cb (GtkWidget *widget, cairo_t *cr); static void draw_preview (glMiniLabelPreview *this, cairo_t *cr); /****************************************************************************/ /* Boilerplate Object stuff. */ /****************************************************************************/ G_DEFINE_TYPE (glMiniLabelPreview, gl_mini_label_preview, GTK_TYPE_DRAWING_AREA) /*****************************************************************************/ /* Class Init Function. */ /*****************************************************************************/ static void gl_mini_label_preview_class_init (glMiniLabelPreviewClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); gl_mini_label_preview_parent_class = g_type_class_peek_parent (class); gobject_class->finalize = gl_mini_label_preview_finalize; widget_class->style_set = style_set_cb; widget_class->draw = draw_cb; } /*****************************************************************************/ /* Object Instance Init Function. */ /*****************************************************************************/ static void gl_mini_label_preview_init (glMiniLabelPreview *this) { gtk_widget_set_has_window (GTK_WIDGET (this), FALSE); this->priv = g_new0 (glMiniLabelPreviewPrivate, 1); } /*****************************************************************************/ /* Finalize Method. */ /*****************************************************************************/ static void gl_mini_label_preview_finalize (GObject *object) { glMiniLabelPreview *this = GL_MINI_LABEL_PREVIEW (object); g_return_if_fail (object != NULL); g_return_if_fail (GL_IS_MINI_LABEL_PREVIEW (object)); lgl_template_free (this->priv->template); g_free (this->priv); G_OBJECT_CLASS (gl_mini_label_preview_parent_class)->finalize (object); } /*****************************************************************************/ /** New Object Generator. */ /*****************************************************************************/ GtkWidget * gl_mini_label_preview_new (gint w, gint h) { glMiniLabelPreview *this; this = g_object_new (GL_TYPE_MINI_LABEL_PREVIEW, NULL); gtk_widget_set_size_request (GTK_WIDGET (this), w, h); return GTK_WIDGET (this); } /*****************************************************************************/ /* Set label by name. */ /*****************************************************************************/ void gl_mini_label_preview_set_by_name (glMiniLabelPreview *this, gchar *name, gboolean rotate_flag) { if (!name) { lgl_template_free (this->priv->template); this->priv->template = NULL; } else { this->priv->template = lgl_db_lookup_template_from_name (name); this->priv->rotate_flag = rotate_flag; } redraw (this); } /*--------------------------------------------------------------------------*/ /* Style set handler (updates colors when style/theme changes). */ /*--------------------------------------------------------------------------*/ static void style_set_cb (GtkWidget *widget, GtkStyle *previous_style) { redraw (GL_MINI_LABEL_PREVIEW (widget)); } /*****************************************************************************/ /* Request redraw. */ /*****************************************************************************/ static void redraw (glMiniLabelPreview *this) { GdkWindow *window; GtkAllocation allocation; window = gtk_widget_get_window (GTK_WIDGET (this)); if (window) { gtk_widget_get_allocation (GTK_WIDGET (this), &allocation); gdk_window_invalidate_rect (window, &allocation, FALSE); } } /*****************************************************************************/ /* "Expose event" callback. */ /*****************************************************************************/ static gboolean draw_cb (GtkWidget *widget, cairo_t *cr) { draw_preview (GL_MINI_LABEL_PREVIEW (widget), cr); return FALSE; } /*****************************************************************************/ /* Draw sample. */ /*****************************************************************************/ static void draw_preview (glMiniLabelPreview *this, cairo_t *cr) { GtkAllocation allocation; GtkStyle *style; gdouble w, h; guint fill_color, line_color, shadow_color; const lglTemplateFrame *frame; gdouble w_label, h_label; gdouble scale; gtk_widget_get_allocation (GTK_WIDGET (this), &allocation); w = allocation.width; h = allocation.height; style = gtk_widget_get_style (GTK_WIDGET (this)); if ( gtk_widget_is_sensitive (GTK_WIDGET (this)) ) { fill_color = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]); line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]); shadow_color = gl_color_from_gdk_color (&style->dark[GTK_STATE_NORMAL]); } else { fill_color = GL_COLOR_NONE; line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]); shadow_color = GL_COLOR_NONE; } if (this->priv->template == NULL) { return; } frame = (lglTemplateFrame *)this->priv->template->frames->data; if (this->priv->rotate_flag) { lgl_template_frame_get_size (frame, &h_label, &w_label); } else { lgl_template_frame_get_size (frame, &w_label, &h_label); } scale = MIN( (w - 2*MARGIN - 2*SHADOW_OFFSET)/w_label, (h - 2*MARGIN - 2*SHADOW_OFFSET)/h_label ); cairo_translate (cr, w/2.0, h/2.0); cairo_scale (cr, scale, scale); cairo_translate (cr, -w_label/2.0, -h_label/2.0); /* * Shadow */ cairo_save (cr); cairo_translate (cr, SHADOW_OFFSET/scale, SHADOW_OFFSET/scale); gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE); cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_color)); cairo_fill (cr); cairo_restore (cr); /* * Label + outline */ gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE); cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color)); cairo_fill_preserve (cr); cairo_set_line_width (cr, 1.0/scale); cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color)); cairo_stroke (cr); } /* * Local Variables: -- emacs * mode: C -- emacs * c-basic-offset: 8 -- emacs * tab-width: 8 -- emacs * indent-tabs-mode: nil -- emacs * End: -- emacs */