initial commit
[goodguy/history.git] / cinelerra-5.0 / guicast / bcwidgetgrid.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2005 Pierre Dumuid
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "clip.h"
23 #include "bctitle.h"
24 #include "bcpot.h"
25 #include "bcslider.h"
26 #include "bcwidgetgrid.h"
27
28
29 BC_WidgetGrid::BC_WidgetGrid(int x1, int y1, int x2, int y2,int cgs,int rgs){
30         x_l = x1;  // x position
31         y_t = y1;  // y position
32         x_r = x2;  // right margin (used only in get_w_wm)
33         y_b = y2;  // left margin (used only in get_w_wm)
34         rowgaps = rgs; 
35         colgaps = cgs;
36
37         for (int r = 0; r < BC_WG_Rows; r++)
38           minh[r] = 0;
39
40         for (int c = 0; c < BC_WG_Cols; c++) 
41           minw[c] = 0;
42
43         for (int r = 0; r < BC_WG_Rows; r++)
44                 for (int c = 0; c < BC_WG_Cols; c++) {
45                         widget_types[r][c] = BC_WT_NONE;
46                         widget_valign[r][c] = VALIGN_CENTER;
47                         widget_halign[r][c] = HALIGN_LEFT;
48                         widget_colspan[r][c] = 1;
49                         widget_rowspan[r][c] = 1;
50                 }
51 }
52
53 BC_RelocatableWidget * BC_WidgetGrid::add(BC_RelocatableWidget *h, int row, int column) {
54         widget_types[row][column] = BC_WT_RelocatableWidget;
55         widget_widgs[row][column] = h;
56         return(h);
57 }
58
59
60
61 void BC_WidgetGrid::calculate_maxs(){
62         int r,c;
63         for (r = 0; r < BC_WG_Rows; r++) {
64                 maxh[r] = minh[r];
65                 for (c = 0; c < BC_WG_Cols; c++) {
66                         if ((widget_rowspan[r][c] == 1) && (getw_h(r,c) > maxh[r]))
67                                 maxh[r] = getw_h(r,c);
68                 }
69         }
70
71         for (c = 0; c < BC_WG_Cols; c++) {
72                 maxw[c] = minw[c];
73                 for (r = 0; r < BC_WG_Rows; r++) {
74                         if ((widget_colspan[r][c] == 1) && (getw_w(r,c) > maxw[c]))
75                                 maxw[c] = getw_w(r,c);
76                 }
77         }
78
79         // Fix up for row & colspans:
80         for (c = 0; c < BC_WG_Cols; c++) {
81                 for (r = 0; r < BC_WG_Rows; r++) {
82                         int c_cs = MIN(BC_WG_Cols - c + 1, widget_colspan[r][c]);
83                         int c_rs = MIN(BC_WG_Rows - c + 1, widget_rowspan[r][c]);
84
85                         if ((widget_colspan[r][c] > 1)) {
86                                 int csw = 0;
87                                 int c2;
88                                 for (c2 = c; c2 < c + c_cs; c2++) {
89                                         csw += maxw[c2];
90                                 }
91                                 if (csw < getw_w(r,c)) {
92                                         for (c2 = c; c2 < c + c_cs; c2++) {
93                                                 maxw[c2] += (csw - getw_w(r,c))/c_cs;
94                                         }
95                                 }
96                         }
97
98                         if ((widget_rowspan[r][c] > 1)) {
99                                 int csh = 0;
100                                 int r2;
101                                 for (r2 = c; r2 < r + c_rs; r2++) {
102                                         csh += maxh[r2];
103                                 }
104                                 if (csh < getw_h(r,c)) {
105                                         for (r2 = c; r2 < r + c_rs; r2++) {
106                                                 maxh[r2] += (csh - getw_h(r,c))/c_rs;
107                                         }
108                                 }
109                         }
110                 }
111         }
112 }
113
114 void BC_WidgetGrid::clear_widget(int row, int column){
115         widget_types[row][column] = BC_WT_NONE;
116 }
117
118 int BC_WidgetGrid::get_h(){
119         calculate_maxs();
120         int y = 0;
121         for (int i = 0; i < BC_WG_Rows; i++)
122                 if (maxh[i] > 0)
123                         y += maxh[i] + rowgaps;
124         return (y);
125 }
126
127 int BC_WidgetGrid::get_h_wm(){
128         return (y_t + get_h() + y_b);
129 }
130
131 int BC_WidgetGrid::get_w(){
132         calculate_maxs();
133         int x = 0;
134         for (int i = 0; i < BC_WG_Cols; i++)
135                 if (maxw[i] > 0)
136                         x += maxw[i] + colgaps;
137         return (x);
138 }
139
140 int BC_WidgetGrid::get_w_wm(){
141         return (x_l + get_w() + x_r);
142 }
143
144 int BC_WidgetGrid::getw_h(int row, int column) {
145         switch (widget_types[row][column]) {
146         case BC_WT_RelocatableWidget: 
147                 return(widget_widgs[row][column]->get_h());
148         default: break;
149         }
150         return 0;
151 }
152
153 int BC_WidgetGrid::getw_w(int row, int column) {
154         switch (widget_types[row][column]) {
155         case BC_WT_RelocatableWidget: 
156                 return(widget_widgs[row][column]->get_w());
157         default: break;
158         }
159         return 0;
160 }
161
162 int BC_WidgetGrid::guess_x(int colno){
163         calculate_maxs();
164         int x = x_l;
165         for (int i = 0; i < colno; i++)
166                 x += maxw[i] + colgaps;
167         return (x);
168 }
169
170 int BC_WidgetGrid::guess_y(int colno){
171         calculate_maxs();
172         int y = y_t;
173         for (int i = 0; i < colno; i++)
174                 y += maxh[i] + rowgaps;
175         return (y);
176 }
177
178 void BC_WidgetGrid::move_widgets(){
179         calculate_maxs();
180         int r,c,x,y;
181         int xn,yn;
182         y = y_t;
183         for (r = 0; r < BC_WG_Rows; r++) {
184                 x = x_l;
185                 for (c = 0; c < BC_WG_Cols; c++) {
186                         switch (widget_valign[r][c]){
187                         default:
188                         case VALIGN_TOP:
189                                 yn = y;
190                                 break;
191                         case VALIGN_CENTER:
192                                 yn = y + (maxh[r] - getw_h(r,c))/2;
193                                 break;
194                         case VALIGN_BOTTOM:
195                                 yn = y + (maxh[r] - getw_h(r,c));
196                                 break;
197                         }
198                                 
199                         switch (widget_halign[r][c]){
200                         default:
201                         case HALIGN_LEFT:
202                                 xn = x;
203                                 break;
204                         case HALIGN_CENTER:
205                                 xn = x + (maxw[c] - getw_w(r,c))/2;
206                                 break;
207                         case HALIGN_RIGHT:
208                                 xn = x + (maxw[c] - getw_w(r,c));
209                                 break;
210                         }
211                         setw_position(r,c,xn,yn); // + (maxh[r] - getw_h(r,c))/2);
212                         x += colgaps + maxw[c];
213                 }
214                 y += rowgaps + maxh[r];
215         }
216 }
217
218 void BC_WidgetGrid::print(){
219         printf("\nWidget Grid: Widths: x_l=%d y_t=%d x_r=%d y_b=%d\n",x_l,y_t,x_r,y_b);
220         calculate_maxs();
221         for (int r = 0; r < BC_WG_Rows; r++) {
222                 for (int c = 0; c < BC_WG_Cols; c++) {
223                         printf("%d,%d\t",getw_w(r,c),getw_h(r,c));
224                 }
225                 printf("MAX: %d\n",maxh[r]);
226         }
227         printf("---------------------------------------------\n");
228         for (int c = 0; c < BC_WG_Cols; c++) 
229                 printf("%d\t",maxw[c]);
230         printf("\n\n");
231
232 }
233
234 int BC_WidgetGrid::reposition_widget(int x, int y, int w1, int h){
235         x_l = x;
236         y_t = y;
237         move_widgets();
238         return(0);
239 }
240
241 void BC_WidgetGrid::set_align(int r,int c,int va, int ha){
242         widget_valign[r][c] = va;
243         widget_halign[r][c] = ha;
244 }
245
246 void BC_WidgetGrid::set_crspan(int r,int c,int cs, int rs){
247         widget_colspan[r][c] = cs;
248         widget_rowspan[r][c] = rs;
249 }
250
251 void BC_WidgetGrid::set_minw(int c,int w){
252         minw[c] = w;
253 }
254
255 void BC_WidgetGrid::set_minh(int c,int h){
256         minh[c] = h;
257 }
258
259 void BC_WidgetGrid::setw_position(int row,int column,int x, int y) {
260         switch (widget_types[row][column]) {
261         case BC_WT_NONE:
262                 break;
263         case BC_WT_RelocatableWidget: 
264                 widget_widgs[row][column]->reposition_widget(x,y);
265                 break;
266         }
267 }
268
269
270 BC_WidgetGridList::BC_WidgetGridList()
271  : ArrayList<BC_WidgetGrid*>()
272 {
273 }
274
275 BC_WidgetGridList::~BC_WidgetGridList()
276 {
277 }
278