1 /* Lepton EDA Schematic Capture
2  * Copyright (C) 1998-2010 Ales Hvezda
3  * Copyright (C) 1998-2014 gEDA Contributors
4  * Copyright (C) 2017-2021 Lepton EDA Contributors
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 /*!
21  * \file gschem_bottom_widget.c
22  *
23  * \brief A widget for the "status bar" at the bottom of the window
24  */
25 
26 #include <config.h>
27 
28 #include <stdio.h>
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #ifdef HAVE_MATH_H
36 #include <math.h>
37 #endif
38 
39 #include "gschem.h"
40 
41 
42 /*  The padding used around labels in the "status bar"
43  */
44 
45 #define LABEL_XPAD 10
46 #define LABEL_YPAD 5
47 
48 
49 
50 enum
51 {
52   PROP_0,
53   PROP_GRID_MODE,
54   PROP_GRID_SIZE,
55   PROP_LEFT_BUTTON_TEXT,
56   PROP_MIDDLE_BUTTON_TEXT,
57   PROP_RIGHT_BUTTON_TEXT,
58   PROP_SNAP_MODE,
59   PROP_SNAP_SIZE,
60   PROP_STATUS_TEXT,
61   PROP_STATUS_TEXT_COLOR,
62   PROP_RUBBER_BAND_MODE,
63   PROP_MAGNETIC_NET_MODE,
64   PROP_TOPLEVEL
65 };
66 
67 
68 
69 static void
70 dispose (GObject *object);
71 
72 static void
73 finalize (GObject *object);
74 
75 static void
76 get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec);
77 
78 static void
79 gschem_bottom_widget_class_init (GschemBottomWidgetClass *klass);
80 
81 static void
82 gschem_bottom_widget_init (GschemBottomWidget *view);
83 
84 static void
85 set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec);
86 
87 static void
88 update_grid_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused);
89 
90 static void
91 update_rubber_band_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused);
92 
93 static void
94 update_magnetic_net_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused);
95 
96 
97 
98 /* convenience macro - gobject type implementation:
99 */
100 #ifdef ENABLE_GTK3
101 G_DEFINE_TYPE (GschemBottomWidget, gschem_bottom_widget, GTK_TYPE_BOX);
102 #else
103 G_DEFINE_TYPE (GschemBottomWidget, gschem_bottom_widget, GTK_TYPE_HBOX);
104 #endif
105 
106 
107 static gboolean
on_click_rubber_band(GtkWidget * ebox,GdkEvent * e,gpointer data)108 on_click_rubber_band (GtkWidget* ebox, GdkEvent* e, gpointer data)
109 {
110   GschemBottomWidget* widget = (GschemBottomWidget*) data;
111   g_return_val_if_fail (widget != NULL, FALSE);
112 
113   GdkEventButton* ebtn = (GdkEventButton*) e;
114   if (ebtn->type == GDK_BUTTON_PRESS && ebtn->button == 1)
115   {
116     gschem_options_cycle_net_rubber_band_mode (widget->toplevel->options);
117     return TRUE;
118   }
119 
120   return FALSE;
121 }
122 
123 
124 
125 static gboolean
on_click_magnetic_net(GtkWidget * ebox,GdkEvent * e,gpointer data)126 on_click_magnetic_net (GtkWidget* ebox, GdkEvent* e, gpointer data)
127 {
128   GschemBottomWidget* widget = (GschemBottomWidget*) data;
129   g_return_val_if_fail (widget != NULL, FALSE);
130 
131   GdkEventButton* ebtn = (GdkEventButton*) e;
132   if (ebtn->type == GDK_BUTTON_PRESS && ebtn->button == 1)
133   {
134     gschem_options_cycle_magnetic_net_mode (widget->toplevel->options);
135     return TRUE;
136   }
137 
138   return FALSE;
139 }
140 
141 
142 
143 static gboolean
on_click_grid_size(GtkWidget * ebox,GdkEvent * e,gpointer data)144 on_click_grid_size (GtkWidget* ebox, GdkEvent* e, gpointer data)
145 {
146   GschemBottomWidget* widget = (GschemBottomWidget*) data;
147   g_return_val_if_fail (widget != NULL, FALSE);
148 
149   GdkEventButton* ebtn = (GdkEventButton*) e;
150   if (ebtn->type == GDK_BUTTON_PRESS && ebtn->button == 1)
151   {
152     gschem_options_cycle_grid_mode (widget->toplevel->options);
153     return TRUE;
154   }
155 
156   return FALSE;
157 }
158 
159 
160 
161 static gboolean
on_click_snap_info(GtkWidget * ebox,GdkEvent * e,gpointer data)162 on_click_snap_info (GtkWidget* ebox, GdkEvent* e, gpointer data)
163 {
164   GschemBottomWidget* widget = (GschemBottomWidget*) data;
165   g_return_val_if_fail (widget != NULL, FALSE);
166 
167   GdkEventButton* ebtn = (GdkEventButton*) e;
168   if (ebtn->type == GDK_BUTTON_PRESS && ebtn->button == 1)
169   {
170     gschem_options_cycle_snap_mode (widget->toplevel->options);
171     return TRUE;
172   }
173 
174   return FALSE;
175 }
176 
177 
178 
179 /*! \brief Dispose of the object
180  */
181 static void
dispose(GObject * object)182 dispose (GObject *object)
183 {
184   /* lastly, chain up to the parent dispose */
185 
186   GschemBottomWidgetClass* cls = GSCHEM_BOTTOM_WIDGET_GET_CLASS (object);
187   GObjectClass* parent_cls = (GObjectClass*) g_type_class_peek_parent (cls);
188 
189   parent_cls->dispose (object);
190 }
191 
192 
193 
194 /*! \brief Finalize object
195  */
196 static void
finalize(GObject * object)197 finalize (GObject *object)
198 {
199   /* lastly, chain up to the parent finalize */
200 
201   GschemBottomWidgetClass* cls = GSCHEM_BOTTOM_WIDGET_GET_CLASS (object);
202   GObjectClass* parent_cls = (GObjectClass*) g_type_class_peek_parent (cls);
203 
204   parent_cls->finalize (object);
205 }
206 
207 
208 
209 /*! \brief Get a property
210  *
211  *  \param [in]     object
212  *  \param [in]     param_id
213  *  \param [in,out] value
214  *  \param [in]     pspec
215  */
216 static void
get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)217 get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec)
218 {
219   GschemBottomWidget *widget = GSCHEM_BOTTOM_WIDGET (object);
220 
221   switch (param_id) {
222     case PROP_TOPLEVEL:
223           g_value_set_pointer (value, widget->toplevel);
224           break;
225 
226     case PROP_GRID_MODE:
227       g_value_set_int (value, gschem_bottom_widget_get_grid_mode (widget));
228       break;
229 
230     case PROP_GRID_SIZE:
231       g_value_set_int (value, gschem_bottom_widget_get_grid_size (widget));
232       break;
233 
234     case PROP_LEFT_BUTTON_TEXT:
235       g_value_set_string (value, gschem_bottom_widget_get_left_button_text (widget));
236       break;
237 
238     case PROP_MIDDLE_BUTTON_TEXT:
239       g_value_set_string (value, gschem_bottom_widget_get_middle_button_text (widget));
240       break;
241 
242     case PROP_RIGHT_BUTTON_TEXT:
243       g_value_set_string (value, gschem_bottom_widget_get_right_button_text (widget));
244       break;
245 
246     case PROP_SNAP_MODE:
247       g_value_set_int (value, gschem_bottom_widget_get_snap_mode (widget));
248       break;
249 
250     case PROP_SNAP_SIZE:
251       g_value_set_int (value, gschem_bottom_widget_get_snap_size (widget));
252       break;
253 
254     case PROP_STATUS_TEXT:
255       g_value_set_string (value, gschem_bottom_widget_get_status_text (widget));
256       break;
257 
258     case PROP_RUBBER_BAND_MODE:
259       g_value_set_boolean (value, gschem_bottom_widget_get_rubber_band_mode (widget));
260       break;
261 
262     case PROP_MAGNETIC_NET_MODE:
263       g_value_set_boolean (value, gschem_bottom_widget_get_magnetic_net_mode (widget));
264       break;
265 
266     default:
267       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
268   }
269 }
270 
271 
272 
273 /*! \brief Initialize GschemBottomWidget class
274  *
275  *  \param [in] klass The class for the GschemBottomWidget
276  */
277 static void
gschem_bottom_widget_class_init(GschemBottomWidgetClass * klass)278 gschem_bottom_widget_class_init (GschemBottomWidgetClass *klass)
279 {
280   G_OBJECT_CLASS (klass)->dispose  = dispose;
281   G_OBJECT_CLASS (klass)->finalize = finalize;
282 
283   G_OBJECT_CLASS (klass)->get_property = get_property;
284   G_OBJECT_CLASS (klass)->set_property = set_property;
285 
286   GParamFlags flags = (GParamFlags) (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
287   GParamSpec* spec  = g_param_spec_pointer ("toplevel", "", "", flags);
288   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TOPLEVEL, spec);
289 
290   g_object_class_install_property (G_OBJECT_CLASS (klass),
291                                    PROP_GRID_MODE,
292                                    g_param_spec_int ("grid-mode",
293                                                      "Grid Mode",
294                                                      "Grid Mode",
295                                                      0,
296                                                      (GRID_MODE_COUNT - 1),
297                                                      GRID_MODE_NONE,
298                                                      (GParamFlags) (G_PARAM_READWRITE
299                                                                     | G_PARAM_CONSTRUCT)));
300 
301   g_object_class_install_property (G_OBJECT_CLASS (klass),
302                                    PROP_GRID_SIZE,
303                                    g_param_spec_int ("grid-size",
304                                                      "Grid Size",
305                                                      "Grid Size",
306                                                      G_MININT,
307                                                      G_MAXINT,
308                                                      0,
309                                                      (GParamFlags) (G_PARAM_READWRITE
310                                                                     | G_PARAM_CONSTRUCT)));
311 
312   g_object_class_install_property (G_OBJECT_CLASS (klass),
313                                    PROP_LEFT_BUTTON_TEXT,
314                                    g_param_spec_string ("left-button-text",
315                                                         "Left Button Text",
316                                                         "Left Button Text",
317                                                         "none",
318                                                         (GParamFlags) (G_PARAM_READWRITE
319                                                                        | G_PARAM_CONSTRUCT)));
320 
321   g_object_class_install_property (G_OBJECT_CLASS (klass),
322                                    PROP_MIDDLE_BUTTON_TEXT,
323                                    g_param_spec_string ("middle-button-text",
324                                                         "Middle Button Text",
325                                                         "Middle Button Text",
326                                                         "none",
327                                                         (GParamFlags) (G_PARAM_READWRITE
328                                                                        | G_PARAM_CONSTRUCT)));
329 
330   g_object_class_install_property (G_OBJECT_CLASS (klass),
331                                    PROP_RIGHT_BUTTON_TEXT,
332                                    g_param_spec_string ("right-button-text",
333                                                         "Right Button Text",
334                                                         "Right Button Text",
335                                                         "none",
336                                                         (GParamFlags) (G_PARAM_READWRITE
337                                                                        | G_PARAM_CONSTRUCT)));
338 
339   g_object_class_install_property (G_OBJECT_CLASS (klass),
340                                    PROP_SNAP_MODE,
341                                    g_param_spec_int ("snap-mode",
342                                                      "Snap Mode",
343                                                      "Snap Mode",
344                                                      G_MININT,
345                                                      G_MAXINT,
346                                                      0,
347                                                      (GParamFlags) (G_PARAM_READWRITE
348                                                                     | G_PARAM_CONSTRUCT)));
349 
350   g_object_class_install_property (G_OBJECT_CLASS (klass),
351                                    PROP_SNAP_SIZE,
352                                    g_param_spec_int ("snap-size",
353                                                      "Snap Size",
354                                                      "Snap Size",
355                                                      G_MININT,
356                                                      G_MAXINT,
357                                                      0,
358                                                      (GParamFlags) (G_PARAM_READWRITE
359                                                                     | G_PARAM_CONSTRUCT)));
360 
361   g_object_class_install_property (G_OBJECT_CLASS (klass),
362                                    PROP_STATUS_TEXT,
363                                    g_param_spec_string ("status-text",
364                                                         "Status Text",
365                                                         "Status Text",
366                                                         "none",
367                                                         (GParamFlags) (G_PARAM_READWRITE
368                                                                        | G_PARAM_CONSTRUCT)));
369 
370   g_object_class_install_property (G_OBJECT_CLASS (klass),
371                                    PROP_STATUS_TEXT_COLOR,
372                                    g_param_spec_boolean ("status-text-color",
373                                                          "Status State",
374                                                          "Status State",
375                                                          FALSE,
376                                                          (GParamFlags) (G_PARAM_READWRITE
377                                                                         | G_PARAM_CONSTRUCT)));
378 
379   g_object_class_install_property (G_OBJECT_CLASS (klass),
380                                    PROP_RUBBER_BAND_MODE,
381                                    g_param_spec_boolean ("net-rubber-band-mode",
382                                                          "Rubber Band Mode",
383                                                          "Rubber Band Mode",
384                                                          TRUE,
385                                                          (GParamFlags) (G_PARAM_READWRITE
386                                                                         | G_PARAM_CONSTRUCT)));
387 
388   g_object_class_install_property (G_OBJECT_CLASS (klass),
389                                    PROP_MAGNETIC_NET_MODE,
390                                    g_param_spec_boolean ("magnetic-net-mode",
391                                                          "Magnetic Net Mode",
392                                                          "Magnetic Net Mode",
393                                                          TRUE,
394                                                          (GParamFlags) (G_PARAM_READWRITE
395                                                                         | G_PARAM_CONSTRUCT)));
396 
397 }
398 
399 
400 
401 /*! \brief Get the grid mode
402  *
403  *  \param [in] widget This GschemBottomWidget
404  *  \return The grid mode
405  */
406 int
gschem_bottom_widget_get_grid_mode(GschemBottomWidget * widget)407 gschem_bottom_widget_get_grid_mode (GschemBottomWidget *widget)
408 {
409   g_return_val_if_fail (widget != NULL, 0);
410 
411   return widget->grid_mode;
412 }
413 
414 
415 
416 /*! \brief Get the grid size
417  *
418  *  \param [in] widget This GschemBottomWidget
419  *  \return The grid size
420  */
421 int
gschem_bottom_widget_get_grid_size(GschemBottomWidget * widget)422 gschem_bottom_widget_get_grid_size (GschemBottomWidget *widget)
423 {
424   g_return_val_if_fail (widget != NULL, 0);
425 
426   return widget->grid_size;
427 }
428 
429 
430 
431 /*! \brief Get the left button text
432  *
433  *  \param [in] widget This GschemBottomWidget
434  *  \return The left button text
435  */
436 const char*
gschem_bottom_widget_get_left_button_text(GschemBottomWidget * widget)437 gschem_bottom_widget_get_left_button_text (GschemBottomWidget *widget)
438 {
439   g_return_val_if_fail (widget != NULL, NULL);
440 
441   return gtk_label_get_text (GTK_LABEL (widget->left_button_label));
442 }
443 
444 
445 
446 /*! \brief Get the middle button text
447  *
448  *  \param [in] widget This GschemBottomWidget
449  *  \return The middle button text
450  */
451 const char*
gschem_bottom_widget_get_middle_button_text(GschemBottomWidget * widget)452 gschem_bottom_widget_get_middle_button_text (GschemBottomWidget *widget)
453 {
454   g_return_val_if_fail (widget != NULL, NULL);
455 
456   return gtk_label_get_text (GTK_LABEL (widget->middle_button_label));
457 }
458 
459 
460 
461 /*! \brief Get the right button text
462  *
463  *  \param [in] widget This GschemBottomWidget
464  *  \return The right button text
465  */
466 const char*
gschem_bottom_widget_get_right_button_text(GschemBottomWidget * widget)467 gschem_bottom_widget_get_right_button_text (GschemBottomWidget *widget)
468 {
469   g_return_val_if_fail (widget != NULL, NULL);
470 
471   return gtk_label_get_text (GTK_LABEL (widget->right_button_label));
472 }
473 
474 
475 
476 /*! \brief Get the snap mode
477  *
478  *  \param [in] widget This GschemBottomWidget
479  *  \return The snap mode
480  */
481 int
gschem_bottom_widget_get_snap_mode(GschemBottomWidget * widget)482 gschem_bottom_widget_get_snap_mode (GschemBottomWidget *widget)
483 {
484   g_return_val_if_fail (widget != NULL, 0);
485 
486   return widget->snap_mode;
487 }
488 
489 
490 
491 /*! \brief Get the snap size
492  *
493  *  \param [in] widget This GschemBottomWidget
494  *  \return The snap size
495  */
496 int
gschem_bottom_widget_get_snap_size(GschemBottomWidget * widget)497 gschem_bottom_widget_get_snap_size (GschemBottomWidget *widget)
498 {
499   g_return_val_if_fail (widget != NULL, 0);
500 
501   return widget->snap_size;
502 }
503 
504 
505 
506 /*! \brief Get the status text
507  *
508  *  \param [in] widget This GschemBottomWidget
509  *  \return The status text
510  */
511 const char*
gschem_bottom_widget_get_status_text(GschemBottomWidget * widget)512 gschem_bottom_widget_get_status_text (GschemBottomWidget *widget)
513 {
514   g_return_val_if_fail (widget != NULL, NULL);
515 
516   return gtk_label_get_text (GTK_LABEL (widget->status_label));
517 }
518 
519 
520 
521 /*! \brief Get the rubber band mode
522  *
523  *  \param  widget This GschemBottomWidget
524  *  \return        The rubber band mode: on (TRUE) or off (FALSE)
525  */
526 gboolean
gschem_bottom_widget_get_rubber_band_mode(GschemBottomWidget * widget)527 gschem_bottom_widget_get_rubber_band_mode (GschemBottomWidget *widget)
528 {
529   g_return_val_if_fail (widget != NULL, 0);
530 
531   return widget->rubber_band_mode;
532 }
533 
534 
535 
536 /*! \brief Get the magnetic net mode
537  *
538  *  \param  widget This GschemBottomWidget
539  *  \return        The magnetic net mode: on (TRUE) or off (FALSE)
540  */
541 gboolean
gschem_bottom_widget_get_magnetic_net_mode(GschemBottomWidget * widget)542 gschem_bottom_widget_get_magnetic_net_mode (GschemBottomWidget *widget)
543 {
544   g_return_val_if_fail (widget != NULL, 0);
545 
546   return widget->magnetic_net_mode;
547 }
548 
549 
550 
551 static GtkWidget*
separator_new()552 separator_new ()
553 {
554 #ifdef ENABLE_GTK3
555   return gtk_separator_new (GTK_ORIENTATION_VERTICAL);
556 #else
557   return gtk_vseparator_new ();
558 #endif
559 }
560 
561 
562 /*! \brief Set grid_snap_widget text
563  *
564  *  \param  widget  This GschemBottomWidget
565  *  \param  str     Text to set. Newly-allocated string. Will be g_free()'d
566  */
567 static void
set_snap_info_widget_text(GschemBottomWidget * widget,gchar * str)568 set_snap_info_widget_text (GschemBottomWidget* widget,
569                            gchar* str)
570 {
571   g_return_if_fail (widget != NULL);
572 
573   gtk_label_set_markup (GTK_LABEL(widget->grid_snap_widget), str);
574   g_free (str);
575 }
576 
577 
578 
579 /*! \brief Set grid_snap_widget color
580  *
581  *  \param  widget      This GschemBottomWidget
582  *  \param  color_name  Color name, e.g. "red", "blue"
583  */
584 static void
set_snap_info_widget_color(GschemBottomWidget * widget,const gchar * color_name)585 set_snap_info_widget_color (GschemBottomWidget* widget,
586                             const gchar* color_name)
587 {
588   g_return_if_fail (widget != NULL);
589 
590 #ifdef ENABLE_GTK3
591   GdkRGBA color;
592   gdk_rgba_parse (&color, color_name);
593   gtk_widget_override_color (GTK_WIDGET (widget->grid_snap_widget),
594                              GTK_STATE_FLAG_NORMAL,
595                              &color);
596 #else
597   GdkColor color;
598   gdk_color_parse (color_name, &color);
599   gtk_widget_modify_fg (GTK_WIDGET (widget->grid_snap_widget),
600                         GTK_STATE_NORMAL,
601                         &color);
602 #endif
603 }
604 
605 
606 
607 /*! \brief Set grid_snap_widget text and color
608  *
609  *  \param  widget      This GschemBottomWidget
610  *  \param  str         Text to set. Newly-allocated string. Will be g_free()'d
611  *  \param  color_name  Color name, e.g. "red", "blue"
612  */
613 static void
set_snap_info_widget(GschemBottomWidget * widget,gchar * str,const gchar * color_name)614 set_snap_info_widget (GschemBottomWidget* widget,
615                       gchar* str,
616                       const gchar* color_name)
617 {
618   g_return_if_fail (widget != NULL);
619 
620   set_snap_info_widget_text (widget, str);
621   set_snap_info_widget_color (widget, color_name);
622 }
623 
624 
625 
626 /*! \brief Reset grid_snap_widget visual state
627  *
628  *  \par Function Description
629  *  Remove any text decorations, reset text color to black
630  *
631  *  \param  widget  This GschemBottomWidget
632  */
633 static void
reset_snap_info_widget(GschemBottomWidget * widget)634 reset_snap_info_widget (GschemBottomWidget* widget)
635 {
636   g_return_if_fail (widget != NULL);
637 
638   gchar* txt = g_strdup_printf ("Snap: %d", widget->snap_size);
639   set_snap_info_widget (widget, txt, "black");
640 }
641 
642 
643 
644 /*! \brief Update info in the grid_snap_widget depending on current snap settings
645  *
646  *  \param  widget  This GschemBottomWidget
647  */
648 static void
update_snap_info_widget(GschemBottomWidget * widget)649 update_snap_info_widget (GschemBottomWidget* widget)
650 {
651   g_return_if_fail (widget != NULL);
652 
653   gchar* cwd = g_get_current_dir();
654   EdaConfig* cfg = eda_config_get_context_for_path (cwd);
655   g_free (cwd);
656 
657   gint default_snap_size = DEFAULT_SNAP_SIZE;
658 
659   if (cfg != NULL)
660   {
661     GError* err = NULL;
662     gint val = eda_config_get_int (cfg,
663                                    "schematic.gui",
664                                    "snap-size",
665                                    &err);
666     if (err == NULL)
667     {
668       default_snap_size = val;
669     }
670 
671     g_clear_error (&err);
672   }
673 
674 
675   reset_snap_info_widget (widget);
676 
677   gchar* txt = NULL;
678 
679   if (widget->snap_mode == SNAP_OFF)
680   {
681       txt = g_strdup_printf (_("<b>Snap: OFF</b>"));
682       set_snap_info_widget (widget, txt, "blue");
683   }
684   else
685   if (widget->snap_mode == SNAP_GRID)
686   {
687     if (widget->snap_size != default_snap_size)
688     {
689       txt = g_strdup_printf (_("Snap: <b>%d</b>"), widget->snap_size);
690       set_snap_info_widget (widget, txt, "red");
691     }
692   }
693   else
694   if (widget->snap_mode == SNAP_RESNAP)
695   {
696     if (widget->snap_size != default_snap_size)
697     {
698       txt = g_strdup_printf (_("<u>Re</u>snap: <b>%d</b>"), widget->snap_size);
699       set_snap_info_widget(widget, txt, "red");
700     }
701     else
702     {
703       txt = g_strdup_printf (_("<u>Re</u>snap: %d"), widget->snap_size);
704       set_snap_info_widget_text(widget, txt);
705     }
706   }
707   else
708   {
709     g_critical ("%s: update_snap_info_widget(): widget->snap_mode out of range: %d\n",
710                 __FILE__,
711                 widget->snap_mode);
712   }
713 
714 
715   if (widget->snap_mode != SNAP_OFF &&
716       widget->snap_size != default_snap_size)
717   {
718     gchar* tooltip = g_strdup_printf(
719       _("Snap size.\n"
720         "Click to change the snapping mode.\n"
721         "Attention: current snap size (%d) differs\n"
722         "from the value set in configuration: %d."),
723         widget->snap_size,
724         default_snap_size);
725 
726     gtk_widget_set_tooltip_text (widget->grid_snap_widget,
727                                  tooltip);
728     g_free (tooltip);
729   }
730   else
731   {
732     gtk_widget_set_tooltip_text (widget->grid_snap_widget,
733                                  _("Snap size.\n"
734                                    "Click to change the snapping mode."));
735   }
736 
737 } /* update_snap_info_widget() */
738 
739 
740 
741 /*! \brief Create grid_snap_widget
742  *
743  *  \param  widget  This GschemBottomWidget
744  */
745 static void
create_snap_info_widget(GschemBottomWidget * widget)746 create_snap_info_widget (GschemBottomWidget* widget)
747 {
748   g_return_if_fail (widget != NULL);
749 
750   widget->grid_snap_widget = gtk_label_new (NULL);
751 
752   GtkWidget* ebox = gtk_event_box_new();
753   gtk_container_add (GTK_CONTAINER (ebox), widget->grid_snap_widget);
754   gtk_widget_show_all (ebox);
755 
756   gchar* str = g_strdup_printf ("Snap: <b>%d</b>", widget->snap_size);
757   gtk_label_set_markup (GTK_LABEL(widget->grid_snap_widget), str);
758   g_free (str);
759 
760   gtk_misc_set_padding (GTK_MISC (widget->grid_snap_widget),
761                         LABEL_XPAD,
762                         LABEL_YPAD);
763   gtk_box_pack_start (GTK_BOX (widget), ebox, FALSE, FALSE, 0);
764 
765   gtk_box_pack_start (GTK_BOX (widget), separator_new(), FALSE, FALSE, 0);
766 
767   g_signal_connect (G_OBJECT (ebox),
768                     "button-press-event",
769                     G_CALLBACK (&on_click_snap_info),
770                     widget);
771 }
772 
773 
774 
775 /*! \brief Update info in the grid_size_widget depending on current grid settings
776  *
777  *  \param  widget  This GschemBottomWidget
778  */
779 static void
update_grid_size_widget(GschemBottomWidget * widget)780 update_grid_size_widget (GschemBottomWidget* widget)
781 {
782   g_return_if_fail (widget != NULL);
783 
784   gchar* str = NULL;
785 
786   if (widget->grid_mode == GRID_MODE_NONE)
787   {
788     str = g_strdup (_("Grid: OFF"));
789   }
790   else
791   if (widget->grid_size <= 0)
792   {
793     str = g_strdup (_("Grid: NONE"));
794   }
795   else
796   {
797     str = g_strdup_printf ("Grid: %d", widget->grid_size);
798   }
799 
800   gtk_label_set_label (GTK_LABEL(widget->grid_size_widget), str);
801   gtk_widget_set_tooltip_text (widget->grid_size_widget,
802                                _("Grid size.\n"
803                                  "Click to change the grid style."));
804   g_free (str);
805 }
806 
807 
808 
809 /*! \brief Create grid_size_widget
810  *
811  *  \param  widget  This GschemBottomWidget
812  */
813 static void
create_grid_size_widget(GschemBottomWidget * widget)814 create_grid_size_widget (GschemBottomWidget* widget)
815 {
816   g_return_if_fail (widget != NULL);
817 
818   widget->grid_size_widget = gtk_label_new (NULL);
819 
820   GtkWidget* ebox = gtk_event_box_new();
821   gtk_container_add (GTK_CONTAINER (ebox), widget->grid_size_widget);
822   gtk_widget_show_all (ebox);
823 
824   gchar* str = g_strdup_printf ("Grid: %d", widget->grid_size);
825   gtk_label_set_markup (GTK_LABEL(widget->grid_size_widget),
826                         str);
827   g_free (str);
828 
829   gtk_misc_set_padding (GTK_MISC (widget->grid_size_widget),
830                         LABEL_XPAD,
831                         LABEL_YPAD);
832   gtk_box_pack_start (GTK_BOX (widget), ebox, FALSE, FALSE, 0);
833 
834   gtk_box_pack_start (GTK_BOX (widget), separator_new(), FALSE, FALSE, 0);
835 
836   g_signal_connect (G_OBJECT (ebox),
837                     "button-press-event",
838                     G_CALLBACK (&on_click_grid_size),
839                     widget);
840 }
841 
842 
843 
844 /*! \brief Initialize GschemBottomWidget instance
845  *
846  *  \param [in,out] view the gschem page view
847  */
848 static void
gschem_bottom_widget_init(GschemBottomWidget * widget)849 gschem_bottom_widget_init (GschemBottomWidget *widget)
850 {
851   GtkWidget *separator;
852 
853   g_return_if_fail (widget != NULL);
854 
855   widget->left_button_label = gtk_label_new (NULL);
856   gtk_widget_set_tooltip_text (widget->left_button_label, _("Left mouse button"));
857   gtk_misc_set_padding (GTK_MISC (widget->left_button_label), LABEL_XPAD, LABEL_YPAD);
858 
859   widget->middle_button_label = gtk_label_new (NULL);
860   gtk_widget_set_tooltip_text (widget->middle_button_label, _("Middle mouse button"));
861   gtk_misc_set_padding (GTK_MISC (widget->middle_button_label), LABEL_XPAD, LABEL_YPAD);
862 
863   widget->right_button_label = gtk_label_new (NULL);
864   gtk_widget_set_tooltip_text (widget->right_button_label, _("Right mouse button"));
865   gtk_misc_set_padding (GTK_MISC (widget->right_button_label), LABEL_XPAD, LABEL_YPAD);
866 
867 
868   /* default values for configuration settings: */
869   gboolean show_mouse_indicators       = TRUE;
870   gboolean show_rubber_band_indicator  = FALSE;
871   gboolean show_magnetic_net_indicator = FALSE;
872 #ifdef ENABLE_GTK3
873   gdk_rgba_parse (&widget->status_inactive_color, "black");
874   gdk_rgba_parse (&widget->status_active_color, "green");
875 #else
876   gdk_color_parse ("black", &widget->status_inactive_color);
877   gdk_color_parse ("green", &widget->status_active_color);
878 #endif
879   widget->status_bold_font = FALSE;
880 
881   gchar* cwd = g_get_current_dir();
882   EdaConfig* cfg = eda_config_get_context_for_path (cwd);
883   g_free (cwd);
884 
885   if (cfg != NULL)
886   {
887     GError*  err = NULL;
888     gboolean val = FALSE;
889 
890     /* mouse indicators: */
891     val = eda_config_get_boolean (cfg,
892                                   "schematic.status-bar",
893                                   "show-mouse-buttons",
894                                   &err);
895     if (err == NULL)
896       show_mouse_indicators = val;
897     g_clear_error (&err);
898 
899     /* net rubber band indicator: */
900     val = eda_config_get_boolean (cfg,
901                                   "schematic.status-bar",
902                                   "show-rubber-band",
903                                   &err);
904     if (err == NULL)
905       show_rubber_band_indicator = val;
906     g_clear_error (&err);
907 
908     /* magnetic net indicator: */
909     val = eda_config_get_boolean (cfg,
910                                   "schematic.status-bar",
911                                   "show-magnetic-net",
912                                   &err);
913     if (err == NULL)
914       show_magnetic_net_indicator = val;
915     g_clear_error (&err);
916 
917     /* status line active color: */
918     gchar* color = eda_config_get_string (cfg,
919                                           "schematic.status-bar",
920                                           "status-active-color",
921                                           &err);
922     if (color != NULL)
923     {
924 #ifdef ENABLE_GTK3
925       gdk_rgba_parse (&widget->status_active_color, color);
926 #else
927       gdk_color_parse (color, &widget->status_active_color);
928 #endif
929       g_free (color);
930     }
931     g_clear_error (&err);
932 
933     /* status line bold font: */
934     val = eda_config_get_boolean (cfg,
935                                   "schematic.status-bar",
936                                   "status-bold-font",
937                                   &err);
938     if (err == NULL)
939       widget->status_bold_font = val;
940     g_clear_error (&err);
941   }
942 
943 
944   if (show_mouse_indicators)
945   {
946     gtk_box_pack_start (GTK_BOX (widget), widget->left_button_label, FALSE, FALSE, 0);
947     gtk_box_pack_start (GTK_BOX (widget), separator_new(), FALSE, FALSE, 0);
948     gtk_box_pack_start (GTK_BOX (widget), widget->middle_button_label, FALSE, FALSE, 0);
949     gtk_box_pack_start (GTK_BOX (widget), separator_new(), FALSE, FALSE, 0);
950     gtk_box_pack_start (GTK_BOX (widget), widget->right_button_label, FALSE, FALSE, 0);
951     gtk_box_pack_start (GTK_BOX (widget), separator_new(), FALSE, FALSE, 0);
952   }
953 
954 
955   create_snap_info_widget (widget);
956   create_grid_size_widget (widget);
957 
958 
959   separator = separator_new ();
960   gtk_box_pack_start (GTK_BOX (widget), separator, FALSE, FALSE, 0);
961 
962 
963   widget->rubber_band_label = gtk_label_new (NULL);
964   gtk_widget_set_tooltip_text (widget->rubber_band_label,
965                                _("Net rubber band mode.\n"
966                                  "Click to toggle ON/OFF."));
967   gtk_misc_set_padding (GTK_MISC (widget->rubber_band_label), LABEL_XPAD, LABEL_YPAD);
968   if (show_rubber_band_indicator)
969   {
970     GtkWidget* ebox_rubber_band = gtk_event_box_new();
971     gtk_container_add (GTK_CONTAINER (ebox_rubber_band), widget->rubber_band_label);
972     gtk_widget_show_all (ebox_rubber_band);
973     gtk_box_pack_start (GTK_BOX (widget), ebox_rubber_band, FALSE, FALSE, 0);
974 
975     g_signal_connect (G_OBJECT (ebox_rubber_band),
976                       "button-press-event",
977                       G_CALLBACK (&on_click_rubber_band),
978                       widget);
979   }
980 
981 
982   separator = separator_new ();
983   gtk_box_pack_start (GTK_BOX (widget), separator, FALSE, FALSE, 0);
984 
985 
986   widget->magnetic_net_label = gtk_label_new (NULL);
987   gtk_widget_set_tooltip_text (widget->magnetic_net_label,
988                                _("Magnetic net mode.\n"
989                                  "Click to toggle ON/OFF."));
990   gtk_misc_set_padding (GTK_MISC (widget->magnetic_net_label), LABEL_XPAD, LABEL_YPAD);
991   if (show_magnetic_net_indicator)
992   {
993     GtkWidget* ebox_magnetic_net = gtk_event_box_new();
994     gtk_container_add (GTK_CONTAINER (ebox_magnetic_net), widget->magnetic_net_label);
995     gtk_widget_show_all (ebox_magnetic_net);
996     gtk_box_pack_start (GTK_BOX (widget), ebox_magnetic_net, FALSE, FALSE, 0);
997 
998     g_signal_connect (G_OBJECT (ebox_magnetic_net),
999                       "button-press-event",
1000                       G_CALLBACK (&on_click_magnetic_net),
1001                       widget);
1002   }
1003 
1004 
1005   widget->status_label = gtk_label_new (NULL);
1006   gtk_widget_set_tooltip_text (widget->status_label, _("Current action mode"));
1007   gtk_misc_set_padding (GTK_MISC (widget->status_label), LABEL_XPAD, LABEL_YPAD);
1008   gtk_box_pack_end (GTK_BOX (widget), widget->status_label, FALSE, FALSE, 0);
1009 
1010   separator = separator_new ();
1011   gtk_box_pack_start (GTK_BOX (widget), separator, FALSE, FALSE, 0);
1012 
1013   g_signal_connect (G_OBJECT (widget),
1014                     "notify::grid-mode",
1015                     G_CALLBACK (update_grid_label),
1016                     NULL);
1017 
1018   g_signal_connect (G_OBJECT (widget),
1019                     "notify::grid-size",
1020                     G_CALLBACK (update_grid_label),
1021                     NULL);
1022 
1023   g_signal_connect (G_OBJECT (widget),
1024                     "notify::snap-mode",
1025                     G_CALLBACK (update_grid_label),
1026                     NULL);
1027 
1028   g_signal_connect (G_OBJECT (widget),
1029                     "notify::snap-size",
1030                     G_CALLBACK (update_grid_label),
1031                     NULL);
1032 
1033   g_signal_connect (G_OBJECT (widget),
1034                     "notify::net-rubber-band-mode",
1035                     G_CALLBACK (update_rubber_band_label),
1036                     NULL);
1037 
1038   g_signal_connect (G_OBJECT (widget),
1039                     "notify::magnetic-net-mode",
1040                     G_CALLBACK (update_magnetic_net_label),
1041                     NULL);
1042 }
1043 
1044 
1045 
1046 /*! \brief Set the grid mode
1047  *
1048  *  \param [in,out] view This GschemBottomWidget
1049  *  \param [in]     size The grid mode
1050  */
1051 void
gschem_bottom_widget_set_grid_mode(GschemBottomWidget * widget,int mode)1052 gschem_bottom_widget_set_grid_mode (GschemBottomWidget *widget, int mode)
1053 {
1054   g_return_if_fail (widget != NULL);
1055 
1056   widget->grid_mode = mode;
1057 
1058   g_object_notify (G_OBJECT (widget), "grid-mode");
1059 }
1060 
1061 
1062 
1063 /*! \brief Set the grid size
1064  *
1065  *  \param [in,out] view This GschemBottomWidget
1066  *  \param [in]     size The grid size
1067  */
1068 void
gschem_bottom_widget_set_grid_size(GschemBottomWidget * widget,int size)1069 gschem_bottom_widget_set_grid_size (GschemBottomWidget *widget, int size)
1070 {
1071   g_return_if_fail (widget != NULL);
1072 
1073   widget->grid_size = size;
1074 
1075   g_object_notify (G_OBJECT (widget), "grid-size");
1076 }
1077 
1078 
1079 
1080 /*! \brief Set the left button text
1081  *
1082  *  \param [in,out] view This GschemBottomWidget
1083  *  \param [in]     text The text
1084  */
1085 void
gschem_bottom_widget_set_left_button_text(GschemBottomWidget * widget,const char * text)1086 gschem_bottom_widget_set_left_button_text (GschemBottomWidget *widget, const char *text)
1087 {
1088   g_return_if_fail (widget != NULL);
1089 
1090   gtk_label_set_text (GTK_LABEL (widget->left_button_label), text);
1091 
1092   g_object_notify (G_OBJECT (widget), "left-button-text");
1093 }
1094 
1095 
1096 
1097 /*! \brief Set the middle button text
1098  *
1099  *  \param [in,out] view This GschemBottomWidget
1100  *  \param [in]     text The text
1101  */
1102 void
gschem_bottom_widget_set_middle_button_text(GschemBottomWidget * widget,const char * text)1103 gschem_bottom_widget_set_middle_button_text (GschemBottomWidget *widget, const char *text)
1104 {
1105   g_return_if_fail (widget != NULL);
1106 
1107   gtk_label_set_text (GTK_LABEL (widget->middle_button_label), text);
1108 
1109   g_object_notify (G_OBJECT (widget), "middle-button-text");
1110 }
1111 
1112 
1113 
1114 /*! \brief Set the right button text
1115  *
1116  *  \param [in,out] view This GschemBottomWidget
1117  *  \param [in]     text The text
1118  */
1119 void
gschem_bottom_widget_set_right_button_text(GschemBottomWidget * widget,const char * text)1120 gschem_bottom_widget_set_right_button_text (GschemBottomWidget *widget, const char *text)
1121 {
1122   g_return_if_fail (widget != NULL);
1123 
1124   gtk_label_set_text (GTK_LABEL (widget->right_button_label), text);
1125 
1126   g_object_notify (G_OBJECT (widget), "right-button-text");
1127 }
1128 
1129 
1130 
1131 /*! \brief Set the snap mode
1132  *
1133  *  \param [in,out] view This GschemBottomWidget
1134  *  \param [in]     size The snap mode
1135  */
1136 void
gschem_bottom_widget_set_snap_mode(GschemBottomWidget * widget,int mode)1137 gschem_bottom_widget_set_snap_mode (GschemBottomWidget *widget, int mode)
1138 {
1139   g_return_if_fail (widget != NULL);
1140 
1141   widget->snap_mode = mode;
1142 
1143   g_object_notify (G_OBJECT (widget), "snap-mode");
1144 }
1145 
1146 
1147 
1148 /*! \brief Set the snap size
1149  *
1150  *  \param [in,out] view This GschemBottomWidget
1151  *  \param [in]     size The snap size
1152  */
1153 void
gschem_bottom_widget_set_snap_size(GschemBottomWidget * widget,int size)1154 gschem_bottom_widget_set_snap_size (GschemBottomWidget *widget, int size)
1155 {
1156   g_return_if_fail (widget != NULL);
1157 
1158   widget->snap_size = size;
1159 
1160   g_object_notify (G_OBJECT (widget), "snap-size");
1161 }
1162 
1163 
1164 /*! \brief Set the status text color
1165  *
1166  *  \par Function Description
1167  *  Changes the status text color to show if the current editing
1168  *  action is active or not.
1169  *
1170  *  \param [in,out] view    This GschemBottomWidget
1171  *  \param [in]     active  The state to visualise
1172  */
1173 void
gschem_bottom_widget_set_status_text_color(GschemBottomWidget * widget,gboolean active)1174 gschem_bottom_widget_set_status_text_color (GschemBottomWidget *widget, gboolean active)
1175 {
1176   g_return_if_fail (widget != NULL);
1177 
1178 #ifdef ENABLE_GTK3
1179   const GdkRGBA* color = NULL;
1180 #else
1181   const GdkColor* color = NULL;
1182 #endif
1183 
1184   if (active) {
1185     color = &widget->status_active_color;
1186   } else {
1187     color = &widget->status_inactive_color;
1188   }
1189 
1190 #ifdef ENABLE_GTK3
1191   gtk_widget_override_color (GTK_WIDGET (widget->status_label),
1192                              GTK_STATE_FLAG_NORMAL,
1193                              color);
1194 #else
1195   gtk_widget_modify_fg (GTK_WIDGET (widget->status_label),
1196                         GTK_STATE_NORMAL,
1197                         color);
1198 #endif
1199 }
1200 
1201 
1202 /*! \brief Set the status text
1203  *
1204  *  \param [in,out] view This GschemBottomWidget
1205  *  \param [in]     text The status text
1206  */
1207 void
gschem_bottom_widget_set_status_text(GschemBottomWidget * widget,const char * text)1208 gschem_bottom_widget_set_status_text (GschemBottomWidget *widget, const char *text)
1209 {
1210   g_return_if_fail (widget != NULL);
1211 
1212   gchar* str = g_markup_printf_escaped (widget->status_bold_font
1213                                         ? "<b>%s</b>"
1214                                         : "%s",
1215                                         text);
1216 
1217   gtk_label_set_markup (GTK_LABEL (widget->status_label), str);
1218   g_free (str);
1219 
1220   g_object_notify (G_OBJECT (widget), "status-text");
1221 }
1222 
1223 
1224 
1225 /*! \brief Set the rubber band mode
1226  *
1227  *  \param [in] widget  This GschemBottomWidget
1228  *  \param [in] mode    The rubber band mode: on (TRUE) or off (FALSE)
1229  */
1230 void
gschem_bottom_widget_set_rubber_band_mode(GschemBottomWidget * widget,gboolean mode)1231 gschem_bottom_widget_set_rubber_band_mode (GschemBottomWidget *widget, gboolean mode)
1232 {
1233   g_return_if_fail (widget != NULL);
1234 
1235   widget->rubber_band_mode = mode;
1236 
1237   g_object_notify (G_OBJECT (widget), "net-rubber-band-mode");
1238 }
1239 
1240 
1241 
1242 /*! \brief Set the magnetic net mode
1243  *
1244  *  \param [in] widget  This GschemBottomWidget
1245  *  \param [in] mode    The magnetic net mode: on (TRUE) or off (FALSE)
1246  */
1247 void
gschem_bottom_widget_set_magnetic_net_mode(GschemBottomWidget * widget,gboolean mode)1248 gschem_bottom_widget_set_magnetic_net_mode (GschemBottomWidget *widget, gboolean mode)
1249 {
1250   g_return_if_fail (widget != NULL);
1251 
1252   widget->magnetic_net_mode = mode;
1253 
1254   g_object_notify (G_OBJECT (widget), "magnetic-net-mode");
1255 }
1256 
1257 
1258 
1259 /*! \brief Set a gobject property
1260  */
1261 static void
set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)1262 set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
1263 {
1264   GschemBottomWidget *widget = GSCHEM_BOTTOM_WIDGET (object);
1265 
1266   switch (param_id) {
1267     case PROP_TOPLEVEL:
1268           widget->toplevel = GSCHEM_TOPLEVEL (g_value_get_pointer (value));
1269           break;
1270 
1271     case PROP_GRID_MODE:
1272       gschem_bottom_widget_set_grid_mode (widget, g_value_get_int (value));
1273       break;
1274 
1275     case PROP_GRID_SIZE:
1276       gschem_bottom_widget_set_grid_size (widget, g_value_get_int (value));
1277       break;
1278 
1279     case PROP_LEFT_BUTTON_TEXT:
1280       gschem_bottom_widget_set_left_button_text (widget, g_value_get_string (value));
1281       break;
1282 
1283     case PROP_MIDDLE_BUTTON_TEXT:
1284       gschem_bottom_widget_set_middle_button_text (widget, g_value_get_string (value));
1285       break;
1286 
1287     case PROP_RIGHT_BUTTON_TEXT:
1288       gschem_bottom_widget_set_right_button_text (widget, g_value_get_string (value));
1289       break;
1290 
1291     case PROP_SNAP_MODE:
1292       gschem_bottom_widget_set_snap_mode (widget, g_value_get_int (value));
1293       break;
1294 
1295     case PROP_SNAP_SIZE:
1296       gschem_bottom_widget_set_snap_size (widget, g_value_get_int (value));
1297       break;
1298 
1299     case PROP_STATUS_TEXT:
1300       gschem_bottom_widget_set_status_text (widget, g_value_get_string (value));
1301       break;
1302 
1303     case PROP_STATUS_TEXT_COLOR:
1304       gschem_bottom_widget_set_status_text_color (widget, g_value_get_boolean (value));
1305       break;
1306 
1307     case PROP_RUBBER_BAND_MODE:
1308       gschem_bottom_widget_set_rubber_band_mode (widget, g_value_get_boolean (value));
1309       break;
1310 
1311     case PROP_MAGNETIC_NET_MODE:
1312       gschem_bottom_widget_set_magnetic_net_mode (widget, g_value_get_boolean (value));
1313       break;
1314 
1315     default:
1316       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1317   }
1318 }
1319 
1320 
1321 
1322 /*! \brief Write the snap and grid settings to the status bar.
1323  *
1324  *  \param [in] widget This GschemBottomWidget
1325  *  \param [in] pspec  The parameter that changed
1326  *  \param [in] unused
1327  */
1328 static void
update_grid_label(GschemBottomWidget * widget,GParamSpec * pspec,gpointer unused)1329 update_grid_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused)
1330 {
1331   update_snap_info_widget (widget);
1332   update_grid_size_widget (widget);
1333 }
1334 
1335 
1336 
1337 /*! \brief Display the rubber band indicator in the status bar
1338  *
1339  *  \param [in] widget This GschemBottomWidget
1340  *  \param [in] pspec  The parameter that changed
1341  *  \param [in] unused
1342  */
1343 static void
update_rubber_band_label(GschemBottomWidget * widget,GParamSpec * pspec,gpointer unused)1344 update_rubber_band_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused)
1345 {
1346   g_return_if_fail (widget != NULL);
1347 
1348 #ifdef ENABLE_GTK3
1349   GdkRGBA color;
1350   gdk_rgba_parse (&color, widget->rubber_band_mode ? "green" : "blue");
1351   gtk_widget_override_color (GTK_WIDGET (widget->rubber_band_label),
1352                              GTK_STATE_FLAG_NORMAL,
1353                              &color);
1354 #else
1355   GdkColor color;
1356   gdk_color_parse (widget->rubber_band_mode ? "green" : "blue", &color);
1357   gtk_widget_modify_fg (GTK_WIDGET (widget->rubber_band_label),
1358                         GTK_STATE_NORMAL,
1359                         &color);
1360 #endif
1361 
1362   gtk_label_set_markup (GTK_LABEL (widget->rubber_band_label),
1363                         widget->rubber_band_mode ?
1364                         "RB: <b>ON</b>" : "RB: off");
1365 }
1366 
1367 
1368 
1369 /*! \brief Display the magnetic net indicator in the status bar
1370  *
1371  *  \param [in] widget This GschemBottomWidget
1372  *  \param [in] pspec  The parameter that changed
1373  *  \param [in] unused
1374  */
1375 static void
update_magnetic_net_label(GschemBottomWidget * widget,GParamSpec * pspec,gpointer unused)1376 update_magnetic_net_label (GschemBottomWidget *widget, GParamSpec *pspec, gpointer unused)
1377 {
1378   g_return_if_fail (widget != NULL);
1379 
1380 #ifdef ENABLE_GTK3
1381   GdkRGBA color;
1382   gdk_rgba_parse (&color, widget->magnetic_net_mode ? "purple" : "darkgray");
1383   gtk_widget_override_color (GTK_WIDGET (widget->magnetic_net_label),
1384                              GTK_STATE_FLAG_NORMAL,
1385                              &color);
1386 #else
1387   GdkColor color;
1388   gdk_color_parse (widget->magnetic_net_mode ? "purple" : "darkgray", &color);
1389   gtk_widget_modify_fg (GTK_WIDGET (widget->magnetic_net_label),
1390                         GTK_STATE_NORMAL,
1391                         &color);
1392 #endif
1393 
1394   gtk_label_set_markup (GTK_LABEL (widget->magnetic_net_label),
1395                     widget->magnetic_net_mode ?
1396                     "MN: <b>ON</b>" : "MN: off");
1397 }
1398