Use one less loop
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / item / button.c
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, focusEnter, void(entity))
12         ATTRIB(Button, onClick, void(entity, entity), SUB_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, pressed, float, 0)
22         ATTRIB(Button, clickTime, float, 0)
23         ATTRIB(Button, disabled, float, 0)
24         ATTRIB(Button, disabledAlpha, float, 0.3)
25         ATTRIB(Button, forcePressed, float, 0)
26         ATTRIB(Button, color, vector, '1 1 1')
27         ATTRIB(Button, colorC, vector, '1 1 1')
28         ATTRIB(Button, colorF, vector, '1 1 1')
29         ATTRIB(Button, colorD, vector, '1 1 1')
30         ATTRIB(Button, color2, vector, '1 1 1')
31         ATTRIB(Button, alpha2, float, 1)
32
33         ATTRIB(Button, origin, vector, '0 0 0')
34         ATTRIB(Button, size, vector, '0 0 0')
35 ENDCLASS(Button)
36 #endif
37
38 #ifdef IMPLEMENTATION
39 void Button_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
40 {
41         if(me.srcMulti)
42                 me.keepspaceLeft = 0;
43         else
44                 me.keepspaceLeft = min(0.8, absSize_y / absSize_x);
45         SUPER(Button).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
46 }
47 void Button_configureButton(entity me, string txt, float sz, string gfx)
48 {
49         SUPER(Button).configureLabel(me, txt, sz, me.srcMulti ? 0.5 : 0);
50         me.src = gfx;
51 }
52 float Button_keyDown(entity me, float key, float ascii, float shift)
53 {
54         if(key == K_ENTER || key == K_SPACE || key == K_KP_ENTER)
55         {
56                 me.clickTime = 0.1; // delayed for effect
57                 return 1;
58         }
59         return 0;
60 }
61 float Button_mouseDrag(entity me, vector pos)
62 {
63         me.pressed = 1;
64         if(pos_x < 0) me.pressed = 0;
65         if(pos_y < 0) me.pressed = 0;
66         if(pos_x >= 1) me.pressed = 0;
67         if(pos_y >= 1) me.pressed = 0;
68         return 1;
69 }
70 float Button_mousePress(entity me, vector pos)
71 {
72         me.mouseDrag(me, pos); // verify coordinates
73         return 1;
74 }
75 float Button_mouseRelease(entity me, vector pos)
76 {
77         if(cvar("menu_sounds"))
78                 localsound("sound/misc/menu2.wav");
79         me.mouseDrag(me, pos); // verify coordinates
80         if(me.pressed)
81         {
82                 if not(me.disabled)
83                         me.onClick(me, me.onClickEntity);
84                 me.pressed = 0;
85         }
86         return 1;
87 }
88 void Button_showNotify(entity me)
89 {
90         me.focusable = !me.disabled;
91 }
92 void Button_focusEnter(entity me)
93 {
94         if(cvar("menu_sounds") > 1)
95                 localsound("sound/misc/menu1.wav");
96         SUPER(Button).focusEnter(me);
97 }
98 void Button_draw(entity me)
99 {
100         vector bOrigin, bSize;
101         float save;
102
103         me.focusable = !me.disabled;
104
105         save = draw_alpha;
106         if(me.disabled)
107                 draw_alpha *= me.disabledAlpha;
108
109         if(me.src)
110         {
111                 if(me.srcMulti)
112                 {
113                         bOrigin = '0 0 0';
114                         bSize = '1 1 0';
115                         if(me.disabled)
116                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1);
117                         else if(me.forcePressed || me.pressed || me.clickTime > 0)
118                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1);
119                         else if(me.focused)
120                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1);
121                         else
122                                 draw_ButtonPicture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1);
123                 }
124                 else
125                 {
126                         if(me.realFontSize_y == 0)
127                         {
128                                 bOrigin = '0 0 0';
129                                 bSize = '1 1 0';
130                         }
131                         else
132                         {
133                                 bOrigin = eY * (0.5 * (1 - me.realFontSize_y)) + eX * (0.5 * (me.keepspaceLeft - me.realFontSize_x));
134                                 bSize = me.realFontSize;
135                         }
136                         if(me.disabled)
137                                 draw_Picture(bOrigin, strcat(me.src, "_d", me.srcSuffix), bSize, me.colorD, 1);
138                         else if(me.forcePressed || me.pressed || me.clickTime > 0)
139                                 draw_Picture(bOrigin, strcat(me.src, "_c", me.srcSuffix), bSize, me.colorC, 1);
140                         else if(me.focused)
141                                 draw_Picture(bOrigin, strcat(me.src, "_f", me.srcSuffix), bSize, me.colorF, 1);
142                         else
143                                 draw_Picture(bOrigin, strcat(me.src, "_n", me.srcSuffix), bSize, me.color, 1);
144                 }
145         }
146         if(me.src2)
147         {
148                 bOrigin = me.keepspaceLeft * eX;
149                 bSize = eY + eX * (1 - me.keepspaceLeft);
150
151                 bOrigin += bSize * (0.5 - 0.5 * me.src2scale);
152                 bSize = bSize * me.src2scale;
153
154                 draw_Picture(bOrigin, me.src2, bSize, me.color2, me.alpha2);
155         }
156
157         draw_alpha = save;
158
159         SUPER(Button).draw(me);
160
161         if(me.clickTime > 0 && me.clickTime <= frametime)
162         {
163                 // keyboard click timer expired? Fire the event then.
164                 if not(me.disabled)
165                         me.onClick(me, me.onClickEntity);
166         }
167         me.clickTime -= frametime;
168 }
169 #endif