]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/item/dialog.qc
fc14d9222b1a76f1bd8535333da563d1cc54626c
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / dialog.qc
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 #ifndef ITEM_DIALOG_H
17         #define ITEM_DIALOG_H
18         #include "inputcontainer.qc"
19         CLASS(Dialog, InputContainer)
20                 METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code!
21                 METHOD(Dialog, fill, void(entity));            // to be overridden by user to fill the dialog with controls
22                 METHOD(Dialog, keyDown, float(entity, float, float, float));
23                 METHOD(Dialog, close, void(entity));
24                 METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector));
25
26                 METHOD(Dialog, TD, void(entity, float, float, entity));
27                 METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector));
28                 METHOD(Dialog, TDempty, void(entity, float));
29                 METHOD(Dialog, setFirstColumn, void(entity, float));
30                 METHOD(Dialog, TR, void(entity));
31                 METHOD(Dialog, gotoRC, void(entity, float, float));
32
33                 ATTRIB(Dialog, isTabRoot, float, 1)
34                 ATTRIB(Dialog, closeButton, entity, NULL)
35                 ATTRIB(Dialog, intendedHeight, float, 0)
36                 ATTRIB(Dialog, itemOrigin, vector, '0 0 0')
37                 ATTRIB(Dialog, itemSize, vector, '0 0 0')
38                 ATTRIB(Dialog, itemSpacing, vector, '0 0 0')
39                 ATTRIB(Dialog, currentRow, float, 0)
40                 ATTRIB(Dialog, currentColumn, float, 0)
41                 ATTRIB(Dialog, firstColumn, float, 0)
42
43                 // to be customized
44                 ATTRIB(Dialog, closable, float, 1)
45                 ATTRIB(Dialog, title, string, "Form1")  // ;)
46                 ATTRIB(Dialog, color, vector, '1 0.5 1')
47                 ATTRIB(Dialog, intendedWidth, float, 0)
48                 ATTRIB(Dialog, rows, float, 3)
49                 ATTRIB(Dialog, columns, float, 2)
50
51                 ATTRIB(Dialog, marginTop, float, 0)     // pixels
52                 ATTRIB(Dialog, marginBottom, float, 0)  // pixels
53                 ATTRIB(Dialog, marginLeft, float, 0)    // pixels
54                 ATTRIB(Dialog, marginRight, float, 0)   // pixels
55                 ATTRIB(Dialog, columnSpacing, float, 0) // pixels
56                 ATTRIB(Dialog, rowSpacing, float, 0)    // pixels
57                 ATTRIB(Dialog, rowHeight, float, 0)     // pixels
58                 ATTRIB(Dialog, titleHeight, float, 0)   // pixels
59                 ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin
60                 ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0)
61                 ATTRIB(Dialog, zoomedOutTitleBar, float, 0)
62
63                 ATTRIB(Dialog, requiresConnection, float, 0)  // set to true if the dialog requires a connection to be opened
64
65                 ATTRIB(Dialog, backgroundImage, string, string_null)
66                 ATTRIB(Dialog, borderLines, float, 1)
67                 ATTRIB(Dialog, closeButtonImage, string, string_null)
68
69                 ATTRIB(Dialog, frame, entity, NULL)
70         ENDCLASS(Dialog)
71 #endif
72
73 #ifdef IMPLEMENTATION
74         void Dialog_Close(entity button, entity me)
75         {
76                 me.close(me);
77         }
78
79         void Dialog_fill(entity me)
80         {}
81
82         void Dialog_addItemSimple(entity me, float row, float col, float rowspan, float colspan, entity e, vector v)
83         {
84                 vector o, s;
85                 o = me.itemOrigin + eX * (col          * me.itemSpacing.x) + eY * (row          * me.itemSpacing.y);
86                 s = me.itemSize   + eX * ((colspan - 1) * me.itemSpacing.x) + eY * ((rowspan - 1) * me.itemSpacing.y);
87                 o.x -= 0.5 * (me.itemSpacing.x - me.itemSize.x) * v.x;
88                 s.x +=       (me.itemSpacing.x - me.itemSize.x) * v.x;
89                 o.y -= 0.5 * (me.itemSpacing.y - me.itemSize.y) * v.y;
90                 s.y +=       (me.itemSpacing.y - me.itemSize.y) * v.y;
91                 me.addItem(me, e, o, s, 1);
92         }
93
94         void Dialog_gotoRC(entity me, float row, float col)
95         {
96                 me.currentRow = row;
97                 me.currentColumn = col;
98         }
99
100         void Dialog_TR(entity me)
101         {
102                 me.currentRow += 1;
103                 me.currentColumn = me.firstColumn;
104         }
105
106         void Dialog_TD(entity me, float rowspan, float colspan, entity e)
107         {
108                 me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, '0 0 0');
109                 me.currentColumn += colspan;
110         }
111
112         void Dialog_TDNoMargin(entity me, float rowspan, float colspan, entity e, vector v)
113         {
114                 me.addItemSimple(me, me.currentRow, me.currentColumn, rowspan, colspan, e, v);
115                 me.currentColumn += colspan;
116         }
117
118         void Dialog_setFirstColumn(entity me, float col)
119         {
120                 me.firstColumn = col;
121         }
122
123         void Dialog_TDempty(entity me, float colspan)
124         {
125                 me.currentColumn += colspan;
126         }
127
128         void Dialog_configureDialog(entity me)
129         {
130                 float absWidth, absHeight;
131
132                 if (me.isTabRoot)
133                 {
134                         me.frame = NEW(BorderImage);
135                         me.frame.configureBorderImage(me.frame, me.title, me.titleFontSize, me.color, me.backgroundImage, me.borderLines * me.titleHeight);
136                         me.frame.zoomedOutTitleBarPosition = me.zoomedOutTitleBarPosition;
137                         me.frame.zoomedOutTitleBar = me.zoomedOutTitleBar;
138                         me.frame.alpha = me.alpha;
139                         me.addItem(me, me.frame, '0 0 0', '1 1 0', 1);
140                 }
141
142                 if (!me.titleFontSize) me.titleHeight = 0;  // no title bar
143
144                 absWidth = me.intendedWidth * conwidth;
145                 absHeight = me.borderLines * me.titleHeight + me.marginTop + me.rows * me.rowHeight + (me.rows - 1) * me.rowSpacing + me.marginBottom;
146                 me.itemOrigin  = eX * (me.marginLeft / absWidth)
147                     + eY * ((me.borderLines * me.titleHeight + me.marginTop) / absHeight);
148                 me.itemSize    = eX * ((1 - (me.marginLeft + me.marginRight + me.columnSpacing * (me.columns - 1)) / absWidth) / me.columns)
149                     + eY * (me.rowHeight / absHeight);
150                 me.itemSpacing = me.itemSize
151                     + eX * (me.columnSpacing / absWidth)
152                     + eY * (me.rowSpacing / absHeight);
153                 me.intendedHeight = absHeight / conheight;
154                 me.currentRow = -1;
155                 me.currentColumn = -1;
156
157                 me.fill(me);
158
159                 if (me.isTabRoot && me.closable && me.borderLines > 0)
160                 {
161                         entity closebutton;
162                         closebutton = me.closeButton = me.frame.closeButton = NEW(Button);
163                         closebutton.configureButton(closebutton, "", 0, me.closeButtonImage);
164                         closebutton.onClick = Dialog_Close;
165                         closebutton.onClickEntity = me;
166                         closebutton.srcMulti = 0;
167                         me.addItem(me, closebutton, '0 0 0', '1 1 0', 1);  // put it as LAST
168                 }
169         }
170
171         void Dialog_close(entity me)
172         {
173                 if (me.parent.instanceOfNexposee) ExposeeCloseButton_Click(me, me.parent);
174                 else if (me.parent.instanceOfModalController) DialogCloseButton_Click(me, me);
175         }
176
177         float Dialog_keyDown(entity me, float key, float ascii, float shift)
178         {
179                 if (me.closable)
180                 {
181                         if (key == K_ESCAPE)
182                         {
183                                 m_play_click_sound(MENU_SOUND_CLOSE);
184                                 me.close(me);
185                                 return 1;
186                         }
187                 }
188                 return SUPER(Dialog).keyDown(me, key, ascii, shift);
189         }
190 #endif