Merge branch 'master' into Mario/qc_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / colorpicker.qc
1 #ifdef INTERFACE
2 CLASS(XonoticColorpicker) EXTENDS(Image)
3         METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity))
4         METHOD(XonoticColorpicker, mousePress, float(entity, vector))
5         METHOD(XonoticColorpicker, mouseRelease, float(entity, vector))
6         METHOD(XonoticColorpicker, mouseDrag, float(entity, vector))
7         ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL)
8         ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER)
9         ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER)
10         ATTRIB(XonoticColorpicker, focusable, float, 1)
11         METHOD(XonoticColorpicker, focusLeave, void(entity))
12         METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float))
13         METHOD(XonoticColorpicker, draw, void(entity))
14 ENDCLASS(XonoticColorpicker)
15 entity makeXonoticColorpicker(entity theTextbox);
16 #endif
17
18 #ifdef IMPLEMENTATION
19 entity makeXonoticColorpicker(entity theTextbox)
20 {
21         entity me;
22         me = spawnXonoticColorpicker();
23         me.configureXonoticColorpicker(me, theTextbox);
24         return me;
25 }
26
27 void XonoticColorpicker_configureXonoticColorpicker(entity me, entity theTextbox)
28 {
29         me.controlledTextbox = theTextbox;
30         me.configureImage(me, me.image);
31 }
32
33 float XonoticColorpicker_mousePress(entity me, vector coords)
34 {
35         me.mouseDrag(me, coords);
36         return 1;
37 }
38
39 // must match hslimage.c
40 vector hslimage_color(vector v, vector margin)
41 {
42     v_x = (v.x - margin.x) / (1 - 2 * margin.x);
43     v_y = (v.y - margin.y) / (1 - 2 * margin.y);
44     if(v.x < 0) v_x = 0;
45     if(v.y < 0) v_y = 0;
46     if(v.x > 1) v_x = 1;
47     if(v.y > 1) v_y = 1;
48     if(v.y > 0.875) // grey bar
49         return hsl_to_rgb(eZ * v.x);
50     else
51         return hsl_to_rgb(v.x * 6 * eX + eY + v.y / 0.875 * eZ);
52 }
53
54 vector color_hslimage(vector v, vector margin)
55 {
56         vector pos = '0 0 0';
57         v = rgb_to_hsl(v);
58         if (v.y)
59         {
60                 pos_x = v.x / 6;
61                 pos_y = v.z * 0.875;
62         }
63         else // grey scale
64         {
65                 pos_x = v.z;
66                 pos_y = 0.875 + 0.07;
67         }
68         pos_x = margin.x + pos.x * (1 - 2 * margin.x);
69         pos_y = margin.y + pos.y * (1 - 2 * margin.y);
70         return pos;
71 }
72
73 float XonoticColorpicker_mouseDrag(entity me, vector coords)
74 {
75         float i, carets;
76         for (;;)
77         {
78                 i = me.controlledTextbox.cursorPos;
79                 if(i >= 2)
80                 {
81                         if(substring(me.controlledTextbox.text, i-2, 1) == "^")
82                         {
83                                 carets = 1;
84                                 while (i - 2 - carets >= 0 && substring(me.controlledTextbox.text, i - 2 - carets, 1) == "^")
85                                         ++carets;
86                                 if (carets & 1)
87                                         if(strstrofs("0123456789", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0)
88                                         {
89                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
90                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
91                                                 continue;
92                                         }
93                         }
94                 }
95
96                 if(i >= 5)
97                 {
98                         if(substring(me.controlledTextbox.text, i-5, 2) == "^x")
99                         {
100                                 carets = 1;
101                                 while (i - 5 - carets >= 0 && substring(me.controlledTextbox.text, i - 5 - carets, 1) == "^")
102                                         ++carets;
103                                 if (carets & 1)
104                                         if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-3, 1), 0) >= 0)
105                                                 if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-2, 1), 0) >= 0)
106                                                         if(strstrofs("0123456789abcdefABCDEF", substring(me.controlledTextbox.text, i-1, 1), 0) >= 0)
107                                                         {
108                                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
109                                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
110                                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
111                                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
112                                                                 me.controlledTextbox.keyDown(me.controlledTextbox, K_BACKSPACE, 8, 0);
113                                                                 continue;
114                                                         }
115                         }
116                 }
117                 break;
118         }
119
120         if(substring(me.controlledTextbox.text, i-1, 1) == "^")
121         {
122                 carets = 1;
123                 while (i - 1 - carets >= 0 && substring(me.controlledTextbox.text, i - 1 - carets, 1) == "^")
124                         ++carets;
125                 if (carets & 1)
126                         me.controlledTextbox.enterText(me.controlledTextbox, "^"); // escape previous caret
127         }
128
129         vector margin;
130         margin = me.imagemargin;
131         if(coords.x >= margin.x)
132         if(coords.y >= margin.y)
133         if(coords.x <= 1 - margin.x)
134         if(coords.y <= 1 - margin.y)
135                 me.controlledTextbox.enterText(me.controlledTextbox, rgb_to_hexcolor(hslimage_color(coords, margin)));
136
137         return 1;
138 }
139
140 float XonoticColorpicker_mouseRelease(entity me, vector coords)
141 {
142         m_play_click_sound(MENU_SOUND_SLIDE);
143         me.mouseDrag(me, coords);
144         return 1;
145 }
146
147 void XonoticColorpicker_focusLeave(entity me)
148 {
149         me.controlledTextbox.saveCvars(me.controlledTextbox);
150 }
151 float XonoticColorpicker_keyDown(entity me, float key, float ascii, float shift)
152 {
153         return me.controlledTextbox.keyDown(me.controlledTextbox, key, ascii, shift);
154 }
155 void XonoticColorpicker_draw(entity me)
156 {
157         SUPER(XonoticColorpicker).draw(me);
158
159         float B, C, aC;
160         C = cvar("r_textcontrast");
161         B = cvar("r_textbrightness");
162
163         // for this to work, C/(1-B) must be in 0..1
164         // B must be < 1
165         // C must be < 1-B
166
167         B = bound(0, B, 1);
168         C = bound(0, C, 1-B);
169
170         aC = 1 - C / (1 - B);
171
172         draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, '0 0 0', aC);
173         draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, me.color, B);
174 }
175 #endif