]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/xonotic/crosshairpicker.qc
9236e61ebaaf5309d76b2895939f273a6651f0bf
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / crosshairpicker.qc
1 #ifdef INTERFACE
2 CLASS(XonoticCrosshairPicker) EXTENDS(Item)
3         METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity))
4         METHOD(XonoticCrosshairPicker, mousePress, float(entity, vector))
5         METHOD(XonoticCrosshairPicker, mouseRelease, float(entity, vector))
6         METHOD(XonoticCrosshairPicker, mouseMove, float(entity, vector))
7         METHOD(XonoticCrosshairPicker, mouseDrag, float(entity, vector))
8         METHOD(XonoticCrosshairPicker, keyDown, float(entity, float, float, float))
9         METHOD(XonoticCrosshairPicker, draw, void(entity))
10         ATTRIB(XonoticCrosshairPicker, focusable, float, 1)
11         ATTRIB(XonoticCrosshairPicker, disabled, float, 0)
12         ATTRIB(XonoticCrosshairPicker, alpha, float, 1)
13         ATTRIB(XonoticCrosshairPicker, disabledAlpha, float, SKINALPHA_DISABLED)
14
15         METHOD(XonoticCrosshairPicker, moveFocus, void(entity, vector, vector))
16         METHOD(XonoticCrosshairPicker, setCrosshair, void(entity))
17         ATTRIB(XonoticCrosshairPicker, realCellSize, vector, '0 0 0')
18         ATTRIB(XonoticCrosshairPicker, focusedCell, vector, '-1 -1 0')
19         ATTRIB(XonoticCrosshairPicker, focusedCellTime, float, 0)
20         ATTRIB(XonoticCrosshairPicker, pressedCell, vector, '-1 -1 0')
21 ENDCLASS(XonoticCrosshairPicker)
22 entity makeXonoticCrosshairPicker();
23 #endif
24
25 #ifdef IMPLEMENTATION
26
27 const float CROSSHAIRPICKER_COLS = 12;
28 const float CROSSHAIRPICKER_ROWS = 3;
29
30 string crosshairpicker_cellToCrosshair(vector cell)
31 {
32         float crosshair = 31 + cell.y * CROSSHAIRPICKER_COLS + cell.x;
33
34         if (crosshair >= 31 && crosshair < 31 + CROSSHAIRPICKER_COLS * CROSSHAIRPICKER_ROWS)
35                 return ftos(crosshair);
36         else
37                 return "";
38 }
39
40 entity makeXonoticCrosshairPicker()
41 {
42         entity me;
43         me = spawnXonoticCrosshairPicker();
44         me.configureXonoticCrosshairPicker(me);
45         return me;
46 }
47
48 void XonoticCrosshairPicker_configureXonoticCrosshairPicker(entity me)
49 {
50         me.realCellSize = eX / CROSSHAIRPICKER_COLS + eY / CROSSHAIRPICKER_ROWS;
51 }
52
53 float XonoticCrosshairPicker_mouseMove(entity me, vector coords)
54 {
55         vector prevFocusedCell = me.focusedCell;
56         me.focusedCell_x = floor(coords.x * CROSSHAIRPICKER_COLS);
57         me.focusedCell_y = floor(coords.y * CROSSHAIRPICKER_ROWS);
58
59         if(me.focusedCell.x < 0 || me.focusedCell.y < 0 ||
60            me.focusedCell.x >= CROSSHAIRPICKER_COLS || me.focusedCell.y >= CROSSHAIRPICKER_ROWS)
61         {
62                 me.focusedCell = '-1 -1 0';
63                 return 0;
64         }
65
66         if(me.focusedCell != prevFocusedCell)
67                 me.focusedCellTime = time;
68
69         return 1;
70 }
71
72 float XonoticCrosshairPicker_mouseDrag(entity me, vector coords)
73 {
74         return me.mouseMove(me, coords);
75 }
76
77 float XonoticCrosshairPicker_mousePress(entity me, vector coords)
78 {
79         me.mouseMove(me, coords);
80
81         if(me.focusedCell.x >= 0)
82         {
83                 me.pressed = 1;
84                 me.pressedCell = me.focusedCell;
85         }
86
87         return 1;
88 }
89
90 float XonoticCrosshairPicker_mouseRelease(entity me, vector coords)
91 {
92         if(!me.pressed)
93                 return 0;
94
95         me.mouseMove(me, coords);
96
97         if(me.focusedCell == me.pressedCell)
98                 me.setCrosshair(me);
99
100         me.pressed = 0;
101         return 1;
102 }
103
104 float XonoticCrosshairPicker_keyDown(entity me, float key, float ascii, float shift)
105 {
106         switch(key)
107         {
108                 case K_LEFTARROW:
109                 case K_KP_LEFTARROW:
110                         me.moveFocus(me, me.focusedCell, '-1 0 0');
111                         return 1;
112                 case K_RIGHTARROW:
113                 case K_KP_RIGHTARROW:
114                         me.moveFocus(me, me.focusedCell, '1 0 0');
115                         return 1;
116                 case K_UPARROW:
117                 case K_KP_UPARROW:
118                         me.moveFocus(me, me.focusedCell, '0 -1 0');
119                         return 1;
120                 case K_DOWNARROW:
121                 case K_KP_DOWNARROW:
122                         me.moveFocus(me, me.focusedCell, '0 1 0');
123                         return 1;
124                 case K_HOME:
125                 case K_KP_HOME:
126                         me.focusedCell = '0 0 0';
127                         return 1;
128                 case K_END:
129                 case K_KP_END:
130                         me.focusedCell_x = CROSSHAIRPICKER_COLS - 1;
131                         me.focusedCell_y = CROSSHAIRPICKER_ROWS - 1;
132                         return 1;
133                 case K_ENTER:
134                 case K_KP_ENTER:
135                 case K_INS:
136                 case K_KP_INS:
137                         me.setCrosshair(me);
138                         return 1;
139         }
140         return 0;
141 }
142
143 void XonoticCrosshairPicker_moveFocus(entity me, vector initialCell, vector step)
144 {
145         me.focusedCell_x = mod(me.focusedCell.x + step.x + CROSSHAIRPICKER_COLS, CROSSHAIRPICKER_COLS);
146         me.focusedCell_y = mod(me.focusedCell.y + step.y + CROSSHAIRPICKER_ROWS, CROSSHAIRPICKER_ROWS);
147
148         if(me.focusedCell != initialCell) // Recursion break
149                 if(crosshairpicker_cellToCrosshair(me.focusedCell) == "")
150                         me.moveFocus(me, initialCell, step);
151 }
152
153 void XonoticCrosshairPicker_setCrosshair(entity me)
154 {
155         cvar_set("crosshair", crosshairpicker_cellToCrosshair(me.focusedCell));
156 }
157
158 void XonoticCrosshairPicker_draw(entity me)
159 {
160         vector sz, rgb;
161         float save;
162
163         me.focusable = !me.disabled;
164
165         save = draw_alpha;
166         if(me.disabled)
167                 draw_alpha *= me.disabledAlpha;
168
169         string crosshair;
170         vector cell, cellPos, crosshairPos;
171         cell = '0 0 0';
172         cellPos = '0 0 0';
173         crosshairPos = '0 0 0';
174
175
176         for(cell_y = 0; cell.y < CROSSHAIRPICKER_ROWS; ++cell.y)
177         {
178                 crosshairPos_y = cell.y / CROSSHAIRPICKER_ROWS + 0.5 * me.realCellSize.y;
179                 for(cell_x = 0; cell.x < CROSSHAIRPICKER_COLS; ++cell.x)
180                 {
181                         crosshair = crosshairpicker_cellToCrosshair(cell);
182
183                         if(crosshair == "")
184                                 continue;
185
186                         // Draw focused cell
187                         if(cell == me.focusedCell && me.focused)
188                         {
189                                 if(!me.pressed || me.focusedCell == me.pressedCell)
190                                 {
191                                         cellPos_x = mod(me.focusedCell.x, CROSSHAIRPICKER_COLS) / CROSSHAIRPICKER_COLS;
192                                         cellPos_y = mod(me.focusedCell.y, CROSSHAIRPICKER_ROWS) / CROSSHAIRPICKER_ROWS;
193                                         draw_Fill(cellPos, me.realCellSize, SKINCOLOR_LISTBOX_FOCUSED, getHighlightAlpha(SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED, me.focusedCellTime));
194                                 }
195                         }
196
197                         // Draw crosshair
198                         crosshairPos_x = cell.x / CROSSHAIRPICKER_COLS + 0.5 * me.realCellSize.x;
199                         string cross = strcat("/gfx/crosshair", crosshairpicker_cellToCrosshair(cell));
200                         sz = draw_PictureSize(cross);
201                         sz = globalToBoxSize(sz, me.size);
202
203                         float ar = sz.x / sz.y;
204                         sz.x = me.realCellSize.x;
205                         sz.y = sz.x / ar;
206
207                         sz = sz * 0.95;
208
209                         rgb = '1 1 1';
210                         draw_Picture(crosshairPos - 0.5 * sz, cross, sz, rgb, me.alpha);
211                         if(cvar("crosshair_dot"))
212                         {
213                                 if(cvar("crosshair_dot_color_custom") && (cvar_string("crosshair_dot_color") != "0"))
214                                         rgb = stov(cvar_string("crosshair_dot_color"));
215
216                                 draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), rgb, me.alpha);
217                         }
218                 }
219         }
220
221         draw_alpha = save;
222
223         SUPER(XonoticCrosshairPicker).draw(me);
224 }
225 #endif