Listbox: highlight item under the cursor
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / button.qc
1 #ifdef INTERFACE
2 CLASS(Button) EXTENDS(Label)
3         METHOD(Button, configureButton, void(entity, string, float, string))
4         METHOD(Button, draw, void(entity))
5         METHOD(Button, showNotify, void(entity))
6         METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector))
7         METHOD(Button, keyDown, float(entity, float, float, float))
8         METHOD(Button, mousePress, float(entity, vector))
9         METHOD(Button, mouseDrag, float(entity, vector))
10         METHOD(Button, mouseRelease, float(entity, vector))
11         METHOD(Button, playClickSound, void(entity))
12         ATTRIB(Button, onClick, void(entity, entity), func_null)
13         ATTRIB(Button, onClickEntity, entity, NULL)
14         ATTRIB(Button, src, string, string_null)
15         ATTRIB(Button, srcSuffix, string, string_null)
16         ATTRIB(Button, src2, string, string_null) // is centered, same aspect, and stretched to label size
17         ATTRIB(Button, src2scale, float, 1)
18         ATTRIB(Button, srcMulti, float, 1) // 0: button square left, text right; 1: button stretched, text over it
19         ATTRIB(Button, buttonLeftOfText, float, 0)
20         ATTRIB(Button, focusable, float, 1)
21         ATTRIB(Button, allowFocusSound, float, 1)
22         ATTRIB(Button, pressed, float, 0)
23         ATTRIB(Button, clickTime, float, 0)
24         ATTRIB(Button, disabled, float, 0)
25         ATTRIB(Button, disabledAlpha, float, 0.3)
26         ATTRIB(Button, forcePressed, float, 0)
27         ATTRIB(Button, color, vector, '1 1 1')
28         ATTRIB(Button, colorC, vector, '1 1 1')
29         ATTRIB(Button, colorF, vector, '1 1 1')
30         ATTRIB(Button, colorD, vector, '1 1 1')
31         ATTRIB(Button, color2, vector, '1 1 1')
32         ATTRIB(Button, alpha2, float, 1)
33
34         ATTRIB(Button, origin, vector, '0 0 0')
35         ATTRIB(Button, size, vector, '0 0 0')
36 ENDCLASS(Button)
37 #endif
38
39 #ifdef IMPLEMENTATION
40 void Button_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
41 {
42         if(me.srcMulti)
43                 me.keepspaceLeft = 0;
44         else
45                 me.keepspaceLeft = min(0.8, absSize.y / absSize.x);
46         SUPER(Button).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
47 }
48 void Button_configureButton(entity me, string txt, float sz, string gfx)
49 {
50         SUPER(Button).configureLabel(me, txt, sz, me.srcMulti ? 0.5 : 0);
51         me.src = gfx;
52 }
53 float Button_keyDown(entity me, float key, float ascii, float shift)
54 {
55         if(key == K_ENTER || key == K_SPACE || key == K_KP_ENTER)
56         {
57                 me.playClickSound(me);
58                 me.clickTime = 0.1; // delayed for effect
59                 return 1;
60         }
61         return 0;
62 }
63 float Button_mouseDrag(entity me, vector pos)
64 {
65         me.pressed = 1;
66         if(pos.x < 0) me.pressed = 0;
67         if(pos.y < 0) me.pressed = 0;
68         if(pos.x >= 1) me.pressed = 0;
69         if(pos.y >= 1) me.pressed = 0;
70         return 1;
71 }
72 float Button_mousePress(entity me, vector pos)
73 {
74         me.mouseDrag(me, pos); // verify coordinates
75         return 1;
76 }
77 float Button_mouseRelease(entity me, vector pos)
78 {
79         me.mouseDrag(me, pos); // verify coordinates
80         if(me.pressed)
81         {
82                 if (!me.disabled)
83                 {
84                         me.playClickSound(me);
85                         if(me.onClick)
86                                 me.onClick(me, me.onClickEntity);
87                 }
88                 me.pressed = 0;
89         }
90         return 1;
91 }
92 void Button_showNotify(entity me)
93 {
94         me.focusable = !me.disabled;
95 }
96 void Button_draw(entity me)
97 {
98         vector bOrigin, bSize;
99         float save;
100
101         me.focusable = !me.disabled;
102
103         save = draw_alpha;
104         if(me.disabled)
105                 draw_alpha *= me.disabledAlpha;
106
107         if(me.src)
108         {
109                 if(me.srcMulti)
110                 {
111                         bOrigin = '0 0 0';
112                         bSize = '1 1 0';
113                         if(me.disabled)
114                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1);
115                         else if(me.forcePressed || me.pressed || me.clickTime > 0)
116                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1);
117                         else if(me.focused)
118                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1);
119                         else
120                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1);
121                 }
122                 else
123                 {
124                         if(me.realFontSize_y == 0)
125                         {
126                                 bOrigin = '0 0 0';
127                                 bSize = '1 1 0';
128                         }
129                         else
130                         {
131                                 bOrigin = eY * (0.5 * (1 - me.realFontSize.y)) + eX * (0.5 * (me.keepspaceLeft - me.realFontSize.x));
132                                 bSize = me.realFontSize;
133                         }
134                         if(me.disabled)
135                                 draw_Picture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1);
136                         else if(me.forcePressed || me.pressed || me.clickTime > 0)
137                                 draw_Picture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1);
138                         else if(me.focused)
139                                 draw_Picture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1);
140                         else
141                                 draw_Picture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1);
142                 }
143         }
144         if(me.src2)
145         {
146                 bOrigin = me.keepspaceLeft * eX;
147                 bSize = eY + eX * (1 - me.keepspaceLeft);
148
149                 bOrigin += bSize * (0.5 - 0.5 * me.src2scale);
150                 bSize = bSize * me.src2scale;
151
152                 draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2);
153         }
154
155         draw_alpha = save;
156
157         if(me.clickTime > 0 && me.clickTime <= frametime)
158         {
159                 // keyboard click timer expired? Fire the event then.
160                 if (!me.disabled)
161                         if(me.onClick)
162                                 me.onClick(me, me.onClickEntity);
163         }
164         me.clickTime -= frametime;
165
166         SUPER(Button).draw(me);
167 }
168 void Dialog_Close(entity button, entity me);
169 void Button_playClickSound(entity me)
170 {
171         if(me.onClick == DialogOpenButton_Click)
172                 m_play_click_sound(MENU_SOUND_OPEN);
173         else if(me.onClick == Dialog_Close)
174                 m_play_click_sound(MENU_SOUND_CLOSE);
175         else
176                 m_play_click_sound(MENU_SOUND_EXECUTE);
177 }
178 #endif