|
1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2014 Olaf Wintermann. All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 |
|
29 #include <stdio.h> |
|
30 #include "container.h" |
|
31 |
|
32 #include <QSpacerItem> |
|
33 #include <QStackedWidget> |
|
34 |
|
35 |
|
36 /* -------------------- UiBoxContainer -------------------- */ |
|
37 |
|
38 UiBoxContainer::UiBoxContainer(QBoxLayout* box) { |
|
39 this->current = NULL; |
|
40 this->menu = NULL; |
|
41 this->box = box; |
|
42 box->setContentsMargins(QMargins(0,0,0,0)); |
|
43 box->setSpacing(0); |
|
44 |
|
45 ui_reset_layout(layout); |
|
46 } |
|
47 |
|
48 void UiBoxContainer::add(QWidget* widget, bool fill) { |
|
49 if(layout.fill != UI_LAYOUT_UNDEFINED) { |
|
50 fill = ui_lb2bool(layout.fill); |
|
51 } |
|
52 |
|
53 if(hasStretchedWidget && fill) { |
|
54 fill = false; |
|
55 fprintf(stderr, "UiError: container has 2 filled widgets"); |
|
56 } |
|
57 |
|
58 box->addWidget(widget, fill); |
|
59 |
|
60 if(!hasStretchedWidget) { |
|
61 QSpacerItem *newspace = new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); |
|
62 box->removeItem(space); |
|
63 box->addSpacerItem(newspace); |
|
64 space = newspace; |
|
65 } |
|
66 |
|
67 if(fill) { |
|
68 hasStretchedWidget = true; |
|
69 } |
|
70 ui_reset_layout(layout); |
|
71 current = widget; |
|
72 } |
|
73 |
|
74 UIWIDGET ui_box(UiObject *obj, QBoxLayout::Direction dir) { |
|
75 UiContainer *ct = uic_get_current_container(obj); |
|
76 QWidget *widget = new QWidget(); |
|
77 QBoxLayout *box = new QBoxLayout(dir); |
|
78 widget->setLayout(box); |
|
79 ct->add(widget, true); |
|
80 |
|
81 UiObject *newobj = uic_object_new(obj, widget); |
|
82 newobj->container = new UiBoxContainer(box); |
|
83 uic_obj_add(obj, newobj); |
|
84 |
|
85 return widget; |
|
86 } |
|
87 |
|
88 UIWIDGET ui_vbox(UiObject *obj) { |
|
89 return ui_box(obj, QBoxLayout::TopToBottom); |
|
90 } |
|
91 |
|
92 UIWIDGET ui_hbox(UiObject *obj) { |
|
93 return ui_box(obj, QBoxLayout::LeftToRight); |
|
94 } |
|
95 |
|
96 |
|
97 |
|
98 /* -------------------- UiGridContainer -------------------- */ |
|
99 |
|
100 UiGridContainer::UiGridContainer(QGridLayout* grid, int margin, int columnspacing, int rowspacing) { |
|
101 this->current = NULL; |
|
102 this->menu = NULL; |
|
103 this->grid = grid; |
|
104 grid->setContentsMargins(QMargins(margin, margin, margin, margin)); |
|
105 grid->setHorizontalSpacing(columnspacing); |
|
106 grid->setVerticalSpacing(rowspacing); |
|
107 ui_reset_layout(layout); |
|
108 } |
|
109 |
|
110 void UiGridContainer::add(QWidget* widget, bool fill) { |
|
111 if(layout.newline) { |
|
112 x = 0; |
|
113 y++; |
|
114 } |
|
115 |
|
116 Qt::Alignment alignment = Qt::AlignTop; |
|
117 grid->setColumnStretch(x, layout.hexpand ? 1 : 0); |
|
118 if(layout.vexpand) { |
|
119 grid->setRowStretch(y, 1); |
|
120 alignment = 0; |
|
121 } else { |
|
122 grid->setRowStretch(y, 0); |
|
123 } |
|
124 |
|
125 int gwidth = layout.gridwidth > 0 ? layout.gridwidth : 1; |
|
126 |
|
127 grid->addWidget(widget, y, x, 1, gwidth, alignment); |
|
128 x += gwidth; |
|
129 |
|
130 ui_reset_layout(layout); |
|
131 current = widget; |
|
132 } |
|
133 |
|
134 UIWIDGET ui_grid(UiObject *obj) { |
|
135 return ui_grid_sp(obj, 0, 0, 0); |
|
136 } |
|
137 |
|
138 UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing) { |
|
139 UiContainer *ct = uic_get_current_container(obj); |
|
140 QWidget *widget = new QWidget(); |
|
141 QGridLayout *grid = new QGridLayout(); |
|
142 widget->setLayout(grid); |
|
143 ct->add(widget, true); |
|
144 |
|
145 UiObject *newobj = uic_object_new(obj, widget); |
|
146 newobj->container = new UiGridContainer(grid, margin, columnspacing, rowspacing); |
|
147 uic_obj_add(obj, newobj); |
|
148 |
|
149 return widget; |
|
150 } |
|
151 |
|
152 |
|
153 /* -------------------- UiTabViewContainer -------------------- */ |
|
154 |
|
155 UiTabViewContainer::UiTabViewContainer(QTabWidget* tabwidget) { |
|
156 this->current = NULL; |
|
157 this->menu = NULL; |
|
158 this->tabwidget = tabwidget; |
|
159 } |
|
160 |
|
161 void UiTabViewContainer::add(QWidget* widget, bool fill) { |
|
162 QString str = QString::fromUtf8(layout.label); |
|
163 tabwidget->addTab(widget, str); |
|
164 } |
|
165 |
|
166 |
|
167 /* -------------------- UiStackContainer -------------------- */ |
|
168 |
|
169 UiStackContainer::UiStackContainer(QStackedWidget *stack) { |
|
170 this->stack = stack; |
|
171 } |
|
172 |
|
173 void UiStackContainer::add(QWidget* widget, bool fill) { |
|
174 stack->addWidget(widget); |
|
175 current = widget; |
|
176 } |
|
177 |
|
178 UIWIDGET ui_tabview(UiObject *obj) { |
|
179 QStackedWidget *tabwidget = new QStackedWidget(); |
|
180 |
|
181 UiContainer *ct = uic_get_current_container(obj); |
|
182 ct->add(tabwidget, true); |
|
183 |
|
184 UiObject *tabviewobj = uic_object_new(obj, tabwidget); |
|
185 tabviewobj->container = new UiStackContainer(tabwidget); |
|
186 uic_obj_add(obj, tabviewobj); |
|
187 |
|
188 return tabwidget; |
|
189 } |
|
190 |
|
191 void ui_tab(UiObject *obj, char *title) { |
|
192 UiContainer *ct = uic_get_current_container(obj); |
|
193 ct->layout.label = title; |
|
194 ui_vbox(obj); |
|
195 } |
|
196 |
|
197 void ui_select_tab(UIWIDGET tabview, int tab) { |
|
198 QStackedWidget *w = (QStackedWidget*)tabview; |
|
199 w->setCurrentIndex(tab); |
|
200 } |
|
201 |
|
202 |
|
203 /* -------------------- UiSidebarContainer -------------------- */ |
|
204 |
|
205 UiSidebarContainer::UiSidebarContainer(QSplitter *splitter) { |
|
206 this->splitter = splitter; |
|
207 } |
|
208 |
|
209 UIWIDGET ui_sidebar(UiObject *obj) { |
|
210 QSplitter *splitter = new QSplitter(Qt::Horizontal); |
|
211 UiContainer *ct = uic_get_current_container(obj); |
|
212 ct->add(splitter, true); |
|
213 |
|
214 UiObject *left = uic_object_new(obj, splitter); |
|
215 left->container = new UiSidebarContainer(splitter); |
|
216 |
|
217 UiObject *right = uic_object_new(obj, splitter); |
|
218 right->container = new UiSidebarContainer(splitter); |
|
219 |
|
220 uic_obj_add(obj, right); |
|
221 uic_obj_add(obj, left); |
|
222 |
|
223 return splitter; |
|
224 } |
|
225 |
|
226 void UiSidebarContainer::add(QWidget *widget, bool fill) { |
|
227 splitter->addWidget(widget); |
|
228 } |
|
229 |
|
230 |
|
231 /* -------------------- layout functions -------------------- */ |
|
232 |
|
233 void ui_layout_fill(UiObject *obj, UiBool fill) { |
|
234 UiContainer *ct = uic_get_current_container(obj); |
|
235 ct->layout.fill = ui_bool2lb(fill); |
|
236 } |
|
237 |
|
238 void ui_layout_hexpand(UiObject *obj, UiBool expand) { |
|
239 UiContainer *ct = uic_get_current_container(obj); |
|
240 ct->layout.hexpand = expand; |
|
241 } |
|
242 |
|
243 void ui_layout_vexpand(UiObject *obj, UiBool expand) { |
|
244 UiContainer *ct = uic_get_current_container(obj); |
|
245 ct->layout.vexpand = expand; |
|
246 } |
|
247 |
|
248 void ui_layout_gridwidth(UiObject *obj, int width) { |
|
249 UiContainer *ct = uic_get_current_container(obj); |
|
250 ct->layout.gridwidth = width; |
|
251 } |
|
252 |
|
253 void ui_newline(UiObject *obj) { |
|
254 UiContainer *ct = uic_get_current_container(obj); |
|
255 ct->layout.newline = TRUE; |
|
256 } |