]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu/item/dialog.c
gotoXY -> gotoRC (misnaming)
[divverent/nexuiz.git] / data / qcsrc / menu / item / dialog.c
1 // Note: this class is called Dialog, but it can also handle a tab under the following conditions:
2 // - isTabRoot is 0
3 // - backgroundImage is the tab's background
4 // - closable is 0
5 // - rootDialog is 0
6 // - title is ""
7 // - marginTop is 
8 // - intendedHeight ends up to be the tab's actual height, or at least close
9 // - titleFontSize is 0
10 // - marginTop cancels out as much of titleHeight as needed (that is, it should be actualMarginTop - titleHeight)
11 // To ensure the latter, you best create all tabs FIRST and insert the tabbed
12 // control to your dialog THEN - with the right height
13 //
14 // a subclass may help with using this as a tab
15
16 #ifdef INTERFACE
17 CLASS(Dialog) EXTENDS(InputContainer)
18         METHOD(Dialog, configureDialog, void(entity)) // no runtime configuration, all parameters are given in the code!
19         METHOD(Dialog, fill, void(entity)) // to be overridden by user to fill the dialog with controls
20         METHOD(Dialog, keyDown, float(entity, float, float, float))
21         METHOD(Dialog, close, void(entity))
22         METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector))
23
24         METHOD(Dialog, TD, void(entity, float, float, entity))
25         METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector))
26         METHOD(Dialog, TDempty, void(entity, float))
27         METHOD(Dialog, setFirstColumn, void(entity, float))
28         METHOD(Dialog, TR, void(entity))
29         METHOD(Dialog, gotoRC, void(entity, float, float))
30
31         ATTRIB(Dialog, isTabRoot, float, 1)
32         ATTRIB(Dialog, closeButton, entity, NULL)
33         ATTRIB(Dialog, intendedHeight, float, 0)
34         ATTRIB(Dialog, itemOrigin, vector, '0 0 0')
35         ATTRIB(Dialog, itemSize, vector, '0 0 0')
36         ATTRIB(Dialog, itemSpacing, vector, '0 0 0')
37         ATTRIB(Dialog, currentRow, float, 0)
38         ATTRIB(Dialog, currentColumn, float, 0)
39         ATTRIB(Dialog, firstColumn, float, 0)
40
41         // to be customized
42         ATTRIB(Dialog, closable, float, 1)
43         ATTRIB(Dialog, title, string, "Form1") // ;)
44         ATTRIB(Dialog, color, vector, '1 0.5 1')
45         ATTRIB(Dialog, intendedWidth, float, 0)
46         ATTRIB(Dialog, rows, float, 3)
47         ATTRIB(Dialog, columns, float, 2)
48
49         ATTRIB(Dialog, marginTop, float, 0) // pixels
50         ATTRIB(Dialog, marginBottom, float, 0) // pixels
51         ATTRIB(Dialog, marginLeft, float, 0) // pixels
52         ATTRIB(Dialog, marginRight, float, 0) // pixels
53         ATTRIB(Dialog, columnSpacing, float, 0) // pixels
54         ATTRIB(Dialog, rowSpacing, float, 0) // pixels
55         ATTRIB(Dialog, rowHeight, float, 0) // pixels
56         ATTRIB(Dialog, titleHeight, float, 0) // pixels
57         ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin
58         ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0)
59         ATTRIB(Dialog, zoomedOutTitleBar, float, 0)
60
61         ATTRIB(Dialog, backgroundImage, string, string_null)
62         ATTRIB(Dialog, closeButtonImage, string, string_null)
63
64         ATTRIB(Dialog, frame, entity, NULL)
65 ENDCLASS(Dialog)
66 #endif
67
68 #ifdef IMPLEMENTATION
69 void Dialog_Close(entity button, entity me)
70 {
71         me.close(me);
72 }
73
74 void fillDialog(entity me)
75 {
76 }
77
78 void addItemSimpleDialog(entity me, float row, float col, float rowspan, float colspan, entity e, vector v)
79 {
80         //print(vtos(me.itemSpacing), " ", vtos(me.itemSize), "\n");
81         vector o, s;
82         o = me.itemOrigin + eX * ( col          * me.itemSpacing_x) + eY * ( row          * me.itemSpacing_y);
83         s = me.itemSize   + eX * ((colspan - 1) * me.itemSpacing_x) + eY * ((rowspan - 1) * me.itemSpacing_y);
84         o_x -= 0.5 * (me.itemSpacing_x - me.itemSize_x) * v_x;
85         s_x +=       (me.itemSpacing_x - me.itemSize_x) * v_x;
86         o_y -= 0.5 * (me.itemSpacing_y - me.itemSize_y) * v_y;
87         s_y +=       (me.itemSpacing_y - me.itemSize_y) * v_y;
88         me.addItem(me, e, o, s, 1);
89 }
90
91 void gotoRCDialog(entity me, float row, float col)
92 {
93         me.currentRow = row;
94         me.currentColumn = col;
95 }
96
97 void TRDialog(entity me)
98 {
99         me.currentRow += 1;
100         me.currentColumn = me.firstColumn;
101 }
102
103 void TDDialog(entity me, float rowspan, float colspan, entity e)
104 {
105         me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, '0 0 0');
106         me.currentColumn += colspan;
107 }
108
109 void TDNoMarginDialog(entity me, float rowspan, float colspan, entity e, vector v)
110 {
111         me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, v);
112         me.currentColumn += colspan;
113 }
114
115 void setFirstColumnDialog(entity me, float col)
116 {
117         me.firstColumn = col;
118 }
119
120 void TDemptyDialog(entity me, float colspan)
121 {
122         me.currentColumn += colspan;
123 }
124
125 void configureDialogDialog(entity me)
126 {
127         entity closebutton;
128         float absWidth, absHeight;
129
130         me.frame = spawnBorderImage();
131         me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.titleHeight);
132         me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition;
133         me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar;
134         me.addItem(me, me.frame, '0 0 0', '1 1 0', 1);
135
136         if not(me.titleFontSize)
137                 me.titleHeight = 0; // no title bar
138
139         absWidth = me.intendedWidth * conwidth;
140         absHeight = me.titleHeight + me.marginTop + me.rows * me.rowHeight + (me.rows - 1) * me.rowSpacing + me.marginBottom;
141         me.itemOrigin  = eX * (me.marginLeft / absWidth)
142                        + eY * ((me.titleHeight + me.marginTop) / absHeight);
143         me.itemSize    = eX * ((1 - (me.marginLeft + me.marginRight + me.columnSpacing * (me.columns - 1)) / absWidth) / me.columns)
144                        + eY * (me.rowHeight / absHeight);
145         me.itemSpacing = me.itemSize
146                        + eX * (me.columnSpacing / absWidth)
147                        + eY * (me.rowSpacing / absHeight);
148         me.intendedHeight = absHeight / conheight;
149         me.currentRow = -1;
150         me.currentColumn = -1;
151
152         me.fill(me);
153
154         if(me.closable)
155         {
156                 closebutton = me.closeButton = spawnButton();
157                 closebutton.configureButton(closebutton, "Close", 0, me.closeButtonImage);
158                 closebutton.onClick = Dialog_Close; closebutton.onClickEntity = me;
159                 closebutton.srcMulti = 0;
160                 me.addItem(me, closebutton, '0 0 0', '1 1 0', 1); // put it as LAST
161         }
162
163         me.frame.closeButton = closebutton;
164 }
165
166 void closeDialog(entity me)
167 {
168         if(me.parent.instanceOfNexposee)
169         {
170                 ExposeeCloseButton_Click(me, me.parent);
171         }
172         else if(me.parent.instanceOfModalController)
173         {
174                 DialogCloseButton_Click(me, me);
175         }
176 }
177
178 float keyDownDialog(entity me, float key, float ascii, float shift)
179 {
180         if(me.closable)
181         {
182                 if(key == K_ESCAPE)
183                 {
184                         me.close(me);
185                         return 1;
186                 }
187         }
188         return keyDownInputContainer(me, key, ascii, shift);
189 }
190 #endif