1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Inkflow-box widget.
4  * This widget allow pack widgets in a flowbox with a controller to show-hide
5  *
6  * Author:
7  *   Jabier Arraiza <jabier.arraiza@marker.es>
8  *
9  * Copyright (C) 2018 Jabier Arraiza
10  *
11  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12  */
13 
14 #include "preferences.h"
15 #include "ui/icon-loader.h"
16 #include "ui/widget/ink-flow-box.h"
17 #include <gtkmm/adjustment.h>
18 
19 namespace Inkscape {
20 namespace UI {
21 namespace Widget {
22 
InkFlowBox(const gchar * name)23 InkFlowBox::InkFlowBox(const gchar *name)
24 : Gtk::Box(Gtk::ORIENTATION_VERTICAL)
25 {
26     set_name(name);
27     this->pack_start(_controller, false, false, 0);
28     this->pack_start(_flowbox, true, true, 0);
29     _flowbox.set_activate_on_single_click(true);
30     Gtk::ToggleButton *tbutton = new Gtk::ToggleButton("", false);
31     tbutton->set_always_show_image(true);
32     _flowbox.set_selection_mode(Gtk::SelectionMode::SELECTION_NONE);
33     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
34     prefs->setBool(Glib::ustring("/dialogs/") + get_name() + Glib::ustring("/flowbox/lock"), false);
35     tbutton->set_active(prefs->getBool(Glib::ustring("/dialogs/") + get_name() + Glib::ustring("/flowbox/lock"), true));
36     Glib::ustring iconname = "object-unlocked";
37     if (tbutton->get_active()) {
38         iconname = "object-locked";
39     }
40     tbutton->set_image(*sp_get_icon_image(iconname, Gtk::ICON_SIZE_MENU));
41     tbutton->signal_toggled().connect(
42         sigc::bind<Gtk::ToggleButton *>(sigc::mem_fun(*this, &InkFlowBox::on_global_toggle), tbutton));
43     _controller.pack_start(*tbutton);
44     tbutton->hide();
45     tbutton->set_no_show_all(true);
46     showing = 0;
47     sensitive = true;
48 }
49 
50 InkFlowBox::~InkFlowBox() = default;
51 
getPrefsPath(gint pos)52 Glib::ustring InkFlowBox::getPrefsPath(gint pos)
53 {
54     return Glib::ustring("/dialogs/") + get_name() + Glib::ustring("/flowbox/index_") + std::to_string(pos);
55 }
56 
on_filter(Gtk::FlowBoxChild * child)57 bool InkFlowBox::on_filter(Gtk::FlowBoxChild *child)
58 {
59     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
60     if (prefs->getBool(getPrefsPath(child->get_index()), true)) {
61         showing++;
62         return true;
63     }
64     return false;
65 }
66 
on_toggle(gint pos,Gtk::ToggleButton * tbutton)67 void InkFlowBox::on_toggle(gint pos, Gtk::ToggleButton *tbutton)
68 {
69     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
70     bool global = prefs->getBool(Glib::ustring("/dialogs/") + get_name() + Glib::ustring("/flowbox/lock"), true);
71     if (global && sensitive) {
72         sensitive = false;
73         bool active = true;
74         for (auto child : tbutton->get_parent()->get_children()) {
75             if (tbutton != child) {
76                 static_cast<Gtk::ToggleButton *>(child)->set_active(active);
77                 active = false;
78             }
79         }
80         prefs->setBool(getPrefsPath(pos), true);
81         tbutton->set_active(true);
82         sensitive = true;
83     } else {
84         prefs->setBool(getPrefsPath(pos), tbutton->get_active());
85     }
86     showing = 0;
87     _flowbox.set_filter_func(sigc::mem_fun(*this, &InkFlowBox::on_filter));
88     _flowbox.set_max_children_per_line(showing);
89 }
90 
on_global_toggle(Gtk::ToggleButton * tbutton)91 void InkFlowBox::on_global_toggle(Gtk::ToggleButton *tbutton)
92 {
93     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
94     prefs->setBool(Glib::ustring("/dialogs/") + get_name() + Glib::ustring("/flowbox/lock"), tbutton->get_active());
95     sensitive = true;
96     if (tbutton->get_active()) {
97         sensitive = false;
98         bool active = true;
99         for (auto child : tbutton->get_parent()->get_children()) {
100             if (tbutton != child) {
101                 static_cast<Gtk::ToggleButton *>(child)->set_active(active);
102                 active = false;
103             }
104         }
105     }
106     Glib::ustring iconname = "object-unlocked";
107     if (tbutton->get_active()) {
108         iconname = "object-locked";
109     }
110     tbutton->set_image(*sp_get_icon_image(iconname, Gtk::ICON_SIZE_MENU));
111     sensitive = true;
112 }
113 
insert(Gtk::Widget * widget,Glib::ustring label,gint pos,bool active,int minwidth)114 void InkFlowBox::insert(Gtk::Widget *widget, Glib::ustring label, gint pos, bool active, int minwidth)
115 {
116     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
117     Gtk::ToggleButton *tbutton = new Gtk::ToggleButton(label, true);
118     tbutton->set_active(prefs->getBool(getPrefsPath(pos), active));
119     tbutton->signal_toggled().connect(
120         sigc::bind<gint, Gtk::ToggleButton *>(sigc::mem_fun(*this, &InkFlowBox::on_toggle), pos, tbutton));
121     _controller.pack_start(*tbutton);
122     tbutton->show();
123     prefs->setBool(getPrefsPath(pos), prefs->getBool(getPrefsPath(pos), active));
124     widget->set_size_request(minwidth, -1);
125     _flowbox.insert(*widget, pos);
126     showing = 0;
127     _flowbox.set_filter_func(sigc::mem_fun(*this, &InkFlowBox::on_filter));
128     _flowbox.set_max_children_per_line(showing);
129 }
130 
131 } // namespace Widget
132 } // namespace UI
133 } // namespace Inkscape
134 
135 /*
136   Local Variables:
137   mode:c++
138   c-file-style:"stroustrup"
139   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
140   indent-tabs-mode:nil
141   fill-column:99
142   End:
143 */
144 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
145