|
1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013 Santeri Piippo |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include <QBoxLayout> |
|
20 #include <QRadioButton> |
|
21 #include <QButtonGroup> |
|
22 #include <QCheckBox> |
|
23 #include <map> |
|
24 |
|
25 #include "widgets.h" |
|
26 |
|
27 RadioBox::RadioBox (const QString& title, QWidget* parent) : QGroupBox (title, parent) { |
|
28 init (Qt::Vertical); |
|
29 } |
|
30 |
|
31 QBoxLayout::Direction makeDirection (Qt::Orientation orient, bool invert = false) { |
|
32 return (orient == (invert ? Qt::Vertical : Qt::Horizontal)) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom; |
|
33 } |
|
34 |
|
35 bool RadioBox::isChecked (int n) const { |
|
36 return m_buttonGroup->checkedId () == n; |
|
37 } |
|
38 |
|
39 void RadioBox::init (Qt::Orientation orient) { |
|
40 m_vert = orient == Qt::Vertical; |
|
41 |
|
42 m_buttonGroup = new QButtonGroup; |
|
43 m_oldId = m_curId = 0; |
|
44 m_coreLayout = null; |
|
45 |
|
46 m_coreLayout = new QBoxLayout ((orient == Qt::Vertical) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); |
|
47 setLayout (m_coreLayout); |
|
48 |
|
49 // Init the first row with a break |
|
50 rowBreak (); |
|
51 |
|
52 connect (m_buttonGroup, SIGNAL (buttonPressed (int)), this, SLOT (slot_buttonPressed (int))); |
|
53 connect (m_buttonGroup, SIGNAL (buttonReleased (int)), this, SLOT (slot_buttonReleased (int))); |
|
54 } |
|
55 |
|
56 RadioBox::RadioBox (const QString& title, initlist<char const*> entries, int const defaultId, |
|
57 const Qt::Orientation orient, QWidget* parent) : QGroupBox (title, parent), m_defId (defaultId) |
|
58 { |
|
59 init (orient); |
|
60 m_oldId = m_defId; |
|
61 |
|
62 for (char const* entry : entries) |
|
63 addButton (entry); |
|
64 } |
|
65 |
|
66 void RadioBox::rowBreak () { |
|
67 QBoxLayout* newLayout = new QBoxLayout (m_vert ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); |
|
68 m_currentLayout = newLayout; |
|
69 m_layouts.push_back (newLayout); |
|
70 |
|
71 m_coreLayout->addLayout (newLayout); |
|
72 } |
|
73 |
|
74 void RadioBox::addButton (const char* entry) { |
|
75 QRadioButton* button = new QRadioButton (entry); |
|
76 addButton (button); |
|
77 } |
|
78 |
|
79 void RadioBox::addButton (QRadioButton* button) { |
|
80 bool const selectThis = (m_curId == m_defId); |
|
81 |
|
82 m_objects.push_back (button); |
|
83 m_buttonGroup->addButton (button, m_curId++); |
|
84 m_currentLayout->addWidget (button); |
|
85 |
|
86 if (selectThis) |
|
87 button->setChecked (true); |
|
88 } |
|
89 |
|
90 RadioBox& RadioBox::operator<< (QRadioButton* button) { |
|
91 addButton (button); |
|
92 return *this; |
|
93 } |
|
94 |
|
95 RadioBox& RadioBox::operator<< (const char* entry) { |
|
96 addButton (entry); |
|
97 return *this; |
|
98 } |
|
99 |
|
100 void RadioBox::setCurrentRow (uint row) { |
|
101 m_currentLayout = m_layouts[row]; |
|
102 } |
|
103 |
|
104 int RadioBox::value () const { |
|
105 return m_buttonGroup->checkedId (); |
|
106 } |
|
107 |
|
108 void RadioBox::setValue (int val) { |
|
109 m_buttonGroup->button (val)->setChecked (true); |
|
110 } |
|
111 |
|
112 QRadioButton* RadioBox::operator[] (uint n) const { |
|
113 return m_objects[n]; |
|
114 } |
|
115 |
|
116 void RadioBox::slot_buttonPressed (int btn) { |
|
117 emit buttonPressed (btn); |
|
118 |
|
119 m_oldId = m_buttonGroup->checkedId (); |
|
120 } |
|
121 |
|
122 void RadioBox::slot_buttonReleased (int btn) { |
|
123 emit buttonReleased (btn); |
|
124 int newid = m_buttonGroup->checkedId (); |
|
125 |
|
126 if (m_oldId != newid) |
|
127 emit valueChanged (newid); |
|
128 } |
|
129 |
|
130 RadioBox::iter RadioBox::begin() { |
|
131 return m_objects.begin (); |
|
132 } |
|
133 |
|
134 RadioBox::iter RadioBox::end() { |
|
135 return m_objects.end (); |
|
136 } |
|
137 |
|
138 CheckBoxGroup::CheckBoxGroup (const char* label, Qt::Orientation orient, QWidget* parent) : QGroupBox (parent) { |
|
139 m_layout = new QBoxLayout (makeDirection (orient)); |
|
140 setTitle (label); |
|
141 setLayout (m_layout); |
|
142 } |
|
143 |
|
144 void CheckBoxGroup::addCheckBox (const char* label, int key, bool checked) { |
|
145 if (m_vals.find (key) != m_vals.end ()) |
|
146 return; |
|
147 |
|
148 QCheckBox* box = new QCheckBox (label); |
|
149 box->setChecked (checked); |
|
150 |
|
151 m_vals[key] = box; |
|
152 m_layout->addWidget (box); |
|
153 |
|
154 connect (box, SIGNAL (stateChanged (int)), this, SLOT (buttonChanged ())); |
|
155 } |
|
156 |
|
157 std::vector<int> CheckBoxGroup::checkedValues () const { |
|
158 std::vector<int> vals; |
|
159 |
|
160 for (const auto& kv : m_vals) |
|
161 if (kv.second->isChecked ()) |
|
162 vals.push_back (kv.first); |
|
163 |
|
164 return vals; |
|
165 } |
|
166 |
|
167 QCheckBox* CheckBoxGroup::getCheckBox (int key) { |
|
168 return m_vals[key]; |
|
169 } |
|
170 |
|
171 void CheckBoxGroup::buttonChanged () { |
|
172 emit selectionChanged (); |
|
173 } |
|
174 |
|
175 bool CheckBoxGroup::buttonChecked (int key) { |
|
176 return m_vals[key]->isChecked (); |
|
177 } |