pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00011 #include <glib.h> 00012 #include <glib-object.h> 00013 #include <gtk/gtk.h> 00014 00015 #include "gtkhid.h" 00016 #include "gui.h" 00017 00018 #include "ghid-cell-renderer-visibility.h" 00019 00020 enum { 00021 TOGGLED, 00022 LAST_SIGNAL 00023 }; 00024 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 }; 00025 00026 enum { 00027 PROP_ACTIVE = 1, 00028 PROP_COLOR 00029 }; 00030 00031 struct _GHidCellRendererVisibility 00032 { 00033 GtkCellRenderer parent; 00034 00035 gboolean active; 00036 gchar *color; 00037 }; 00038 00039 struct _GHidCellRendererVisibilityClass 00040 { 00041 GtkCellRendererClass parent_class; 00042 00043 void (* toggled) (GHidCellRendererVisibility *cell, const gchar *path); 00044 }; 00045 00046 /* RENDERER FUNCTIONS */ 00047 00051 static void 00052 ghid_cell_renderer_visibility_get_size (GtkCellRenderer *cell, 00053 GtkWidget *widget, 00054 GdkRectangle *cell_area, 00055 gint *x_offset, 00056 gint *y_offset, 00057 gint *width, 00058 gint *height) 00059 { 00060 GtkStyle *style = gtk_widget_get_style (widget); 00061 gint w, h; 00062 gint xpad, ypad; 00063 gfloat xalign, yalign; 00064 00065 gtk_cell_renderer_get_padding (cell, &xpad, &ypad); 00066 gtk_cell_renderer_get_alignment (cell, &xalign, &yalign); 00067 00068 w = VISIBILITY_TOGGLE_SIZE + 2 * (xpad + style->xthickness); 00069 h = VISIBILITY_TOGGLE_SIZE + 2 * (ypad + style->ythickness); 00070 00071 if (width) 00072 *width = w; 00073 if (height) 00074 *height = h; 00075 00076 if (cell_area) 00077 { 00078 if (x_offset) 00079 { 00080 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) 00081 xalign = 1. - xalign; 00082 *x_offset = MAX (0, xalign * (cell_area->width - w)); 00083 } 00084 if (y_offset) 00085 *y_offset = MAX(0, yalign * (cell_area->height - h)); 00086 } 00087 } 00088 00092 static void 00093 ghid_cell_renderer_visibility_render (GtkCellRenderer *cell, 00094 GdkWindow *window, 00095 GtkWidget *widget, 00096 GdkRectangle *background_area, 00097 GdkRectangle *cell_area, 00098 GdkRectangle *expose_area, 00099 GtkCellRendererState flags) 00100 { 00101 GHidCellRendererVisibility *pcb_cell; 00102 GdkRectangle toggle_rect; 00103 GdkRectangle draw_rect; 00104 gint xpad, ypad; 00105 00106 pcb_cell = GHID_CELL_RENDERER_VISIBILITY (cell); 00107 ghid_cell_renderer_visibility_get_size (cell, widget, cell_area, 00108 &toggle_rect.x, 00109 &toggle_rect.y, 00110 &toggle_rect.width, 00111 &toggle_rect.height); 00112 gtk_cell_renderer_get_padding (cell, &xpad, &ypad); 00113 00114 toggle_rect.x += cell_area->x + xpad; 00115 toggle_rect.y += cell_area->y + ypad; 00116 toggle_rect.width -= xpad * 2; 00117 toggle_rect.height -= ypad * 2; 00118 00119 if (toggle_rect.width <= 0 || toggle_rect.height <= 0) 00120 return; 00121 00122 if (gdk_rectangle_intersect (expose_area, cell_area, &draw_rect)) 00123 { 00124 GdkColor color; 00125 cairo_t *cr = gdk_cairo_create (window); 00126 cairo_pattern_t *pattern; 00127 00128 if (expose_area) 00129 { 00130 gdk_cairo_rectangle (cr, expose_area); 00131 cairo_clip (cr); 00132 } 00133 cairo_set_line_width (cr, 1); 00134 00135 cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5, 00136 toggle_rect.width - 1, toggle_rect.height - 1); 00137 cairo_set_source_rgb (cr, 1, 1, 1); 00138 cairo_fill_preserve (cr); 00139 cairo_set_source_rgb (cr, 0, 0, 0); 00140 cairo_stroke (cr); 00141 00142 gdk_color_parse (pcb_cell->color, &color); 00143 if (flags & GTK_CELL_RENDERER_PRELIT) 00144 { 00145 color.red = (4*color.red + 65535) / 5; 00146 color.green = (4*color.green + 65535) / 5; 00147 color.blue = (4*color.blue + 65535) / 5; 00148 } 00149 00150 pattern = cairo_pattern_create_radial ((toggle_rect.width - 1.) * 0.75 + toggle_rect.x + 0.5, 00151 (toggle_rect.height - 1.) * 0.75 + toggle_rect.y + 0.5, 00152 0., 00153 (toggle_rect.width - 1.) * 0.50 + toggle_rect.x + 0.5, 00154 (toggle_rect.height - 1.) * 0.50 + toggle_rect.y + 0.5, 00155 (toggle_rect.width - 1.) * 0.71); 00156 00157 cairo_pattern_add_color_stop_rgb (pattern, 0.0, 00158 (color.red / 65535. * 4. + 1.) / 5., 00159 (color.green / 65535. * 4. + 1.) / 5., 00160 (color.blue / 65535. * 4. + 1.) / 5.); 00161 cairo_pattern_add_color_stop_rgb (pattern, 1.0, 00162 (color.red / 65535. * 5. + 0.) / 5., 00163 (color.green / 65535. * 5. + 0.) / 5., 00164 (color.blue / 65535. * 5. + 0.) / 5.); 00165 cairo_set_source (cr, pattern); 00166 cairo_pattern_destroy (pattern); 00167 00168 if (pcb_cell->active) 00169 cairo_rectangle (cr, toggle_rect.x + 0.5, toggle_rect.y + 0.5, 00170 toggle_rect.width - 1, toggle_rect.height - 1); 00171 else 00172 { 00173 cairo_move_to (cr, toggle_rect.x + 1, toggle_rect.y + 1); 00174 cairo_rel_line_to (cr, toggle_rect.width / 2, 0); 00175 cairo_rel_line_to (cr, -toggle_rect.width / 2, toggle_rect.width / 2); 00176 cairo_close_path (cr); 00177 } 00178 cairo_fill (cr); 00179 00180 cairo_destroy (cr); 00181 } 00182 } 00183 00187 static gint 00188 ghid_cell_renderer_visibility_activate (GtkCellRenderer *cell, 00189 GdkEvent *event, 00190 GtkWidget *widget, 00191 const gchar *path, 00192 GdkRectangle *background_area, 00193 GdkRectangle *cell_area, 00194 GtkCellRendererState flags) 00195 { 00196 g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path); 00197 return TRUE; 00198 } 00199 00200 /* Setter/Getter */ 00201 static void 00202 ghid_cell_renderer_visibility_get_property (GObject *object, 00203 guint param_id, 00204 GValue *value, 00205 GParamSpec *pspec) 00206 { 00207 GHidCellRendererVisibility *pcb_cell = 00208 GHID_CELL_RENDERER_VISIBILITY (object); 00209 00210 switch (param_id) 00211 { 00212 case PROP_ACTIVE: 00213 g_value_set_boolean (value, pcb_cell->active); 00214 break; 00215 case PROP_COLOR: 00216 g_value_set_string (value, pcb_cell->color); 00217 break; 00218 } 00219 } 00220 00221 static void 00222 ghid_cell_renderer_visibility_set_property (GObject *object, 00223 guint param_id, 00224 const GValue *value, 00225 GParamSpec *pspec) 00226 { 00227 GHidCellRendererVisibility *pcb_cell = 00228 GHID_CELL_RENDERER_VISIBILITY (object); 00229 00230 switch (param_id) 00231 { 00232 case PROP_ACTIVE: 00233 pcb_cell->active = g_value_get_boolean (value); 00234 break; 00235 case PROP_COLOR: 00236 g_free (pcb_cell->color); 00237 pcb_cell->color = g_value_dup_string (value); 00238 break; 00239 } 00240 } 00241 00242 00243 /* CONSTRUCTOR */ 00244 static void 00245 ghid_cell_renderer_visibility_init (GHidCellRendererVisibility *ls) 00246 { 00247 g_object_set (ls, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); 00248 } 00249 00250 static void 00251 ghid_cell_renderer_visibility_class_init (GHidCellRendererVisibilityClass *klass) 00252 { 00253 GObjectClass *object_class = G_OBJECT_CLASS (klass); 00254 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); 00255 00256 object_class->get_property = ghid_cell_renderer_visibility_get_property; 00257 object_class->set_property = ghid_cell_renderer_visibility_set_property; 00258 00259 cell_class->get_size = ghid_cell_renderer_visibility_get_size; 00260 cell_class->render = ghid_cell_renderer_visibility_render; 00261 cell_class->activate = ghid_cell_renderer_visibility_activate; 00262 00263 g_object_class_install_property (object_class, PROP_ACTIVE, 00264 g_param_spec_boolean ("active", 00265 _("Visibility state"), 00266 _("Visibility of the layer"), 00267 FALSE, 00268 G_PARAM_READWRITE)); 00269 g_object_class_install_property (object_class, PROP_COLOR, 00270 g_param_spec_string ("color", 00271 _("Layer color"), 00272 _("Layer color"), 00273 FALSE, 00274 G_PARAM_READWRITE)); 00275 00276 00285 toggle_cell_signals[TOGGLED] = 00286 g_signal_new ("toggled", 00287 G_OBJECT_CLASS_TYPE (object_class), 00288 G_SIGNAL_RUN_LAST, 00289 G_STRUCT_OFFSET (GHidCellRendererVisibilityClass, toggled), 00290 NULL, NULL, 00291 g_cclosure_marshal_VOID__STRING, 00292 G_TYPE_NONE, 1, 00293 G_TYPE_STRING); 00294 } 00295 00296 /* PUBLIC FUNCTIONS */ 00297 GType 00298 ghid_cell_renderer_visibility_get_type (void) 00299 { 00300 static GType ls_type = 0; 00301 00302 if (!ls_type) 00303 { 00304 const GTypeInfo ls_info = 00305 { 00306 sizeof (GHidCellRendererVisibilityClass), 00307 NULL, /* base_init */ 00308 NULL, /* base_finalize */ 00309 (GClassInitFunc) ghid_cell_renderer_visibility_class_init, 00310 NULL, /* class_finalize */ 00311 NULL, /* class_data */ 00312 sizeof (GHidCellRendererVisibility), 00313 0, /* n_preallocs */ 00314 (GInstanceInitFunc) ghid_cell_renderer_visibility_init, 00315 }; 00316 00317 ls_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, 00318 "GHidCellRendererVisibility", 00319 &ls_info, 00320 0); 00321 } 00322 00323 return ls_type; 00324 } 00325 00326 GtkCellRenderer * 00327 ghid_cell_renderer_visibility_new (void) 00328 { 00329 GHidCellRendererVisibility *rv = 00330 g_object_new (GHID_CELL_RENDERER_VISIBILITY_TYPE, NULL); 00331 00332 rv->active = FALSE; 00333 00334 return GTK_CELL_RENDERER (rv); 00335 } 00336