Code

The dialog to panel refactoring:
[inkscape.git] / src / ui / widget / panel.cpp
1 /**
2  * \brief Panel widget
3  *
4  * Authors:
5  *   Bryce Harrington <bryce@bryceharrington.org>
6  *   Jon A. Cruz <jon@joncruz.org>
7  *
8  * Copyright (C) 2004 Bryce Harrington
9  * Copyright (C) 2005 Jon A. Cruz
10  *
11  * Released under GNU GPL.  Read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
18 #include <glibmm/i18n.h>
20 #include <gtkmm/dialog.h> // for Gtk::RESPONSE_*
21 #include <gtkmm/stock.h>
23 #include "panel.h"
24 #include "icon-size.h"
25 #include "prefs-utils.h"
26 #include "desktop-handles.h"
27 #include "inkscape.h"
29 namespace Inkscape {
30 namespace UI {
31 namespace Widget {
33 static const int PANEL_SETTING_SIZE = 0;
34 static const int PANEL_SETTING_MODE = 1;
35 static const int PANEL_SETTING_WRAP = 2;
36 static const int PANEL_SETTING_NEXTFREE = 3;
38 /**
39  *    Construct a Panel
40  */
42 Panel::Panel(Glib::ustring const &label, gchar const *prefs_path, 
43              int verb_num, Glib::ustring const &apply_label,
44              bool menu_desired) :
45     _prefs_path(prefs_path),
46     _menu_desired(menu_desired),
47     _label(label),
48     _apply_label(apply_label),
49     _verb_num(verb_num),
50     _temp_arrow(Gtk::ARROW_LEFT, Gtk::SHADOW_ETCHED_OUT),
51     _menu(0),
52     _action_area(0),
53     _fillable(0)
54 {
55     _init();
56 }
58 Panel::~Panel()
59 {
60     delete _menu;
61 }
63 void Panel::_popper(GdkEventButton* event)
64 {
65     if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) {
66         if (_menu) {
67             _menu->popup(event->button, event->time);
68         }
69     }
70 }
72 void Panel::_init()
73 {
74     Glib::ustring tmp("<");
75     _anchor = Gtk::ANCHOR_CENTER;
77     guint panel_size = 0;
78     if (_prefs_path) {
79         panel_size = prefs_get_int_attribute_limited( _prefs_path, "panel_size", 1, 0, 10 );
80     }
82     guint panel_mode = 0;
83     if (_prefs_path) {
84         panel_mode = prefs_get_int_attribute_limited( _prefs_path, "panel_mode", 1, 0, 10 );
85     }
87     guint panel_wrap = 0;
88     if (_prefs_path) {
89         panel_wrap = prefs_get_int_attribute_limited( _prefs_path, "panel_wrap", 0, 0, 1 );
90     }
92     _menu = new Gtk::Menu();
93     {
94         const char *things[] = {
95             N_("tiny"),
96             N_("small"),
97             N_("medium"),
98             N_("large"),
99             N_("huge")
100         };
101         Gtk::RadioMenuItem::Group groupOne;
102         for (unsigned int i = 0; i < G_N_ELEMENTS(things); i++) {
103             Glib::ustring foo(gettext(things[i]));
104             Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, foo));
105             _menu->append(*single);
106             if (i == panel_size) {
107                 single->set_active(true);
108             }
109             single->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_SIZE, i));
110        }
111     }
112     _menu->append(*manage(new Gtk::SeparatorMenuItem()));
113     Gtk::RadioMenuItem::Group group;
114     Glib::ustring one_label(_("List"));
115     Glib::ustring two_label(_("Grid"));
116     Gtk::RadioMenuItem *one = manage(new Gtk::RadioMenuItem(group, one_label));
117     Gtk::RadioMenuItem *two = manage(new Gtk::RadioMenuItem(group, two_label));
119     if (panel_mode == 0) {
120         one->set_active(true);
121     } else if (panel_mode == 1) {
122         two->set_active(true);
123     }
125     _menu->append(*one);
126     _non_horizontal.push_back(one);
127     _menu->append(*two);
128     _non_horizontal.push_back(two);
129     Gtk::MenuItem* sep = manage(new Gtk::SeparatorMenuItem());
130     _menu->append(*sep);
131     _non_horizontal.push_back(sep);
132     one->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_MODE, 0));
133     two->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_MODE, 1));
135     {
136         Glib::ustring wrap_label(_("Wrap"));
137         Gtk::CheckMenuItem *check = manage(new Gtk::CheckMenuItem(wrap_label));
138         check->set_active(panel_wrap);
139         _menu->append(*check);
140         _non_vertical.push_back(check);
142         check->signal_toggled().connect(sigc::bind<Gtk::CheckMenuItem*>(sigc::mem_fun(*this, &Panel::_wrapToggled), check));
144         sep = manage(new Gtk::SeparatorMenuItem());
145         _menu->append(*sep);
146         _non_vertical.push_back(sep);
147     }
149     _menu->show_all_children();
150     for ( std::vector<Gtk::Widget*>::iterator iter = _non_vertical.begin(); iter != _non_vertical.end(); ++iter ) {
151         (*iter)->hide();
152     }
154     // _close_button.set_label("X");
156     if (!_label.empty()) {
157         _tab_title.set_label(_label);
158         _top_bar.pack_start(_tab_title);
159     }
161     // _top_bar.pack_end(_close_button, false, false);
164     if ( _menu_desired ) {
165         _top_bar.pack_end(_menu_popper, false, false);
166         Gtk::Frame* outliner = manage(new Gtk::Frame());
167         outliner->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
168         outliner->add(_temp_arrow);
169         _menu_popper.add(*outliner);
170         _menu_popper.signal_button_press_event().connect_notify(sigc::mem_fun(*this, &Panel::_popper));
171     }
173     pack_start(_top_bar, false, false);
175     Gtk::HBox* boxy = manage(new Gtk::HBox());
177     boxy->pack_start(_contents, true, true);
178     boxy->pack_start(_right_bar, false, true);
180     pack_start(*boxy, true, true);
182     signalResponse().connect(sigc::mem_fun(*this, &Panel::_handleResponse));
184     show_all_children();
186     _bounceCall(PANEL_SETTING_SIZE, panel_size);
187     _bounceCall(PANEL_SETTING_MODE, panel_mode);
188     _bounceCall(PANEL_SETTING_WRAP, panel_wrap);
191 void Panel::setLabel(Glib::ustring const &label)
193     if (_label.empty() && !label.empty())
194         _top_bar.pack_start(_tab_title);
195     else if (!_label.empty() && label.empty())
196         _top_bar.remove(_tab_title);
198     _label = label;
199     _tab_title.set_label(_label);
202 void Panel::setOrientation(Gtk::AnchorType how)
204     if (_anchor != how) {
205         _anchor = how;
206         switch (_anchor) {
207             case Gtk::ANCHOR_NORTH:
208             case Gtk::ANCHOR_SOUTH:
209             {
210                 if (_menu_desired) {
211                     _menu_popper.reference();
212                     _top_bar.remove(_menu_popper);
213                     _right_bar.pack_start(_menu_popper, false, false);
214                     _menu_popper.unreference();
216                     for (std::vector<Gtk::Widget*>::iterator iter = _non_horizontal.begin(); iter != _non_horizontal.end(); ++iter) {
217                         (*iter)->hide();
218                     }
219                     for (std::vector<Gtk::Widget*>::iterator iter = _non_vertical.begin(); iter != _non_vertical.end(); ++iter) {
220                         (*iter)->show();
221                     }
222                 }
223                 // Ensure we are not in "list" mode
224                 _bounceCall(PANEL_SETTING_MODE, 1);
225                 if (!_label.empty())
226                     _top_bar.remove(_tab_title);
227             }
228             break;
230             default:
231             {
232                 if ( _menu_desired ) {
233                     for (std::vector<Gtk::Widget*>::iterator iter = _non_horizontal.begin(); iter != _non_horizontal.end(); ++iter) {
234                         (*iter)->show();
235                     }
236                     for (std::vector<Gtk::Widget*>::iterator iter = _non_vertical.begin(); iter != _non_vertical.end(); ++iter) {
237                         (*iter)->hide();
238                     }
239                 }
240             }
241         }
242     }
245 void Panel::present()
247     _signal_present.emit();
251 void Panel::restorePanelPrefs()
253     guint panel_size = 0;
254     if (_prefs_path) {
255         panel_size = prefs_get_int_attribute_limited(_prefs_path, "panel_size", 1, 0, 10);
256     }
257     guint panel_mode = 0;
258     if (_prefs_path) {
259         panel_mode = prefs_get_int_attribute_limited(_prefs_path, "panel_mode", 1, 0, 10);
260     }
261     guint panel_wrap = 0;
262     if (_prefs_path) {
263         panel_wrap = prefs_get_int_attribute_limited(_prefs_path, "panel_wrap", 0, 0, 1 );
264     }
265     _bounceCall(PANEL_SETTING_SIZE, panel_size);
266     _bounceCall(PANEL_SETTING_MODE, panel_mode);
267     _bounceCall(PANEL_SETTING_WRAP, panel_wrap);
270 sigc::signal<void, int> &
271 Panel::signalResponse()
273     return _signal_response;
276 sigc::signal<void> &
277 Panel::signalPresent()
279     return _signal_present;
282 void Panel::_bounceCall(int i, int j)
284     _menu->set_active(0);
285     switch (i) {
286     case PANEL_SETTING_SIZE:
287         if (_prefs_path) {
288             prefs_set_int_attribute(_prefs_path, "panel_size", j);
289         }
290         if (_fillable) {
291             ViewType curr_type = _fillable->getPreviewType();
292             switch (j) {
293             case 0:
294             {
295                 _fillable->setStyle(Inkscape::ICON_SIZE_DECORATION, curr_type);
296             }
297             break;
298             case 1:
299             {
300                 _fillable->setStyle(Inkscape::ICON_SIZE_MENU, curr_type);
301             }
302             break;
303             case 2:
304             {
305                 _fillable->setStyle(Inkscape::ICON_SIZE_SMALL_TOOLBAR, curr_type);
306             }
307             break;
308             case 3:
309             {
310                 _fillable->setStyle(Inkscape::ICON_SIZE_BUTTON, curr_type);
311             }
312             break;
313             case 4:
314             {
315                 _fillable->setStyle(Inkscape::ICON_SIZE_DIALOG, curr_type);
316             }
317             break;
318             default:
319                 ;
320             }
321         }
322         break;
323     case PANEL_SETTING_MODE:
324         if (_prefs_path) {
325             prefs_set_int_attribute (_prefs_path, "panel_mode", j);
326         }
327         if (_fillable) {
328             Inkscape::IconSize curr_size = _fillable->getPreviewSize();
329             switch (j) {
330             case 0:
331             {
332                 _fillable->setStyle(curr_size, VIEW_TYPE_LIST);
333             }
334             break;
335             case 1:
336             {
337                 _fillable->setStyle(curr_size, VIEW_TYPE_GRID);
338             }
339             break;
340             default:
341                 break;
342             }
343         }
344         break;
345     case PANEL_SETTING_WRAP:
346         if (_prefs_path) {
347             prefs_set_int_attribute (_prefs_path, "panel_wrap", j ? 1 : 0);
348         }
349         if ( _fillable ) {
350             _fillable->setWrap(j);
351         }
352         break;
353     default:
354         _handleAction(i - PANEL_SETTING_NEXTFREE, j);
355     }
359 void Panel::_wrapToggled(Gtk::CheckMenuItem* toggler)
361     if (toggler) {
362         _bounceCall(PANEL_SETTING_WRAP, toggler->get_active() ? 1 : 0);
363     }
366 gchar const *Panel::getPrefsPath() const
368     return _prefs_path;
371 Glib::ustring const &Panel::getLabel() const
373     return _label;
376 int const &Panel::getVerb() const
378     return _verb_num;
381 Glib::ustring const &Panel::getApplyLabel() const
383     return _apply_label;
386 void Panel::_setTargetFillable(PreviewFillable *target)
388     _fillable = target;
391 void Panel::_regItem(Gtk::MenuItem* item, int group, int id)
393     _menu->append(*item);
394     item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), group + PANEL_SETTING_NEXTFREE, id));
395     item->show();
398 void Panel::_handleAction(int set_id, int item_id)
400 // for subclasses to override
403 void
404 Panel::_apply()
406     g_warning("Apply button clicked for panel [Panel::_apply()]");
409 Gtk::Button * 
410 Panel::addResponseButton(const Glib::ustring &button_text, int response_id)
412     Gtk::Button *button = new Gtk::Button(button_text);
413     _addResponseButton(button, response_id);
414     return button;
417 Gtk::Button *
418 Panel::addResponseButton(const Gtk::StockID &stock_id, int response_id)
420     Gtk::Button *button = new Gtk::Button(stock_id);
421     _addResponseButton(button, response_id);
422     return button;
425 void
426 Panel::_addResponseButton(Gtk::Button *button, int response_id)
428     // Create a button box for the response buttons if it's the first button to be added
429     if (!_action_area) {
430         _action_area = new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 6);
431         _action_area->set_border_width(4);
432         pack_end(*_action_area, Gtk::PACK_SHRINK, 0);
433     }
435     _action_area->pack_end(*button);
437     if (response_id != 0) {
438         // Re-emit clicked signals as response signals
439         button->signal_clicked().connect(sigc::bind(_signal_response.make_slot(), response_id));
440         _response_map[response_id] = button;
441     }
444 void
445 Panel::setDefaultResponse(int response_id)
447     ResponseMap::iterator widget_found;
448     widget_found = _response_map.find(response_id);
450     if (widget_found != _response_map.end()) {
451         widget_found->second->activate();
452         widget_found->second->property_can_default() = true;
453         widget_found->second->grab_default();
454     }
457 void
458 Panel::setResponseSensitive(int response_id, bool setting)
460     if (_response_map[response_id])
461         _response_map[response_id]->set_sensitive(setting);
464 void
465 Panel::_handleResponse(int response_id)
467     switch (response_id) {
468         case Gtk::RESPONSE_APPLY: {
469             _apply();
470             break;
471         }
472     }
475 Inkscape::Selection *Panel::_getSelection()
477     return sp_desktop_selection(SP_ACTIVE_DESKTOP);
480 } // namespace Widget
481 } // namespace UI
482 } // namespace Inkscape
484 /*
485   Local Variables:
486   mode:c++
487   c-file-style:"stroustrup"
488   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
489   indent-tabs-mode:nil
490   fill-column:99
491   End:
492 */
493 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :