]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/dialog.c
Make csqc turrets work. moving ones still do not
[xonotic/xonotic-data.pk3dir.git] / 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, borderLines, float, 1)
63         ATTRIB(Dialog, closeButtonImage, string, string_null)
64
65         ATTRIB(Dialog, frame, entity, NULL)
66 ENDCLASS(Dialog)
67 #endif
68
69 #ifdef IMPLEMENTATION
70 void Dialog_Close(entity button, entity me)
71 {
72         me.close(me);
73 }
74
75 void Dialog_fill(entity me)
76 {
77 }
78
79 void Dialog_addItemSimple(entity me, float row, float col, float rowspan, float colspan, entity e, vector v)
80 {
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 Dialog_gotoRC(entity me, float row, float col)
92 {
93         me.currentRow = row;
94         me.currentColumn = col;
95 }
96
97 void Dialog_TR(entity me)
98 {
99         me.currentRow += 1;
100         me.currentColumn = me.firstColumn;
101 }
102
103 void Dialog_TD(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 Dialog_TDNoMargin(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 Dialog_setFirstColumn(entity me, float col)
116 {
117         me.firstColumn = col;
118 }
119
120 void Dialog_TDempty(entity me, float colspan)
121 {
122         me.currentColumn += colspan;
123 }
124
125 void Dialog_configureDialog(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.borderLines * me.titleHeight);
132         me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition;
133         me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar;
134         me.frame.alpha = me.alpha;
135         me.addItem(me, me.frame, '0 0 0', '1 1 0', 1);
136
137         if not(me.titleFontSize)
138                 me.titleHeight = 0; // no title bar
139
140         absWidth = me.intendedWidth * conwidth;
141         absHeight = me.borderLines * me.titleHeight + me.marginTop + me.rows * me.rowHeight + (me.rows - 1) * me.rowSpacing + me.marginBottom;
142         me.itemOrigin  = eX * (me.marginLeft / absWidth)
143                        + eY * ((me.borderLines * me.titleHeight + me.marginTop) / absHeight);
144         me.itemSize    = eX * ((1 - (me.marginLeft + me.marginRight + me.columnSpacing * (me.columns - 1)) / absWidth) / me.columns)
145                        + eY * (me.rowHeight / absHeight);
146         me.itemSpacing = me.itemSize
147                        + eX * (me.columnSpacing / absWidth)
148                        + eY * (me.rowSpacing / absHeight);
149         me.intendedHeight = absHeight / conheight;
150         me.currentRow = -1;
151         me.currentColumn = -1;
152
153         me.fill(me);
154
155         if(me.closable)
156         {
157                 closebutton = me.closeButton = spawnButton();
158                 closebutton.configureButton(closebutton, "", 0, me.closeButtonImage);
159                 closebutton.onClick = Dialog_Close; closebutton.onClickEntity = me;
160                 closebutton.srcMulti = 0;
161                 me.addItem(me, closebutton, '0 0 0', '1 1 0', 1); // put it as LAST
162         }
163
164         me.frame.closeButton = closebutton;
165 }
166
167 void Dialog_close(entity me)
168 {
169         if(me.parent.instanceOfNexposee)
170         {
171                 ExposeeCloseButton_Click(me, me.parent);
172         }
173         else if(me.parent.instanceOfModalController)
174         {
175                 DialogCloseButton_Click(me, me);
176         }
177 }
178
179 float Dialog_keyDown(entity me, float key, float ascii, float shift)
180 {
181         if(me.closable)
182         {
183                 if(key == K_ESCAPE)
184                 {
185                         me.close(me);
186                         return 1;
187                 }
188         }
189         return SUPER(Dialog).keyDown(me, key, ascii, shift);
190 }
191 #endif