Initial revision
[ssr] / StraySrc / Glass / !Glass / c / colSelect
1 /*
2 * colSelect.c
3 *
4 * Handling of a colour button
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Glass.
12 *
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31 * ANSI standard headers
32 */
33
34 #include <stdlib.h>
35
36 /*
37 * Steel headers
38 */
39
40 #define _STDAPP
41 #include "steel/Steel.h"
42 #include "steel/akbd.h"
43 #include "steel/colourtran.h"
44
45 /*
46 * Glass headers
47 */
48
49 #include "gIcons.h"
50
51 #include "glass.h"
52 #include "colSelect.h"
53
54 /*----- Support routines --------------------------------------------------*/
55
56 /*
57 * void colSelect__addBorder(dbox d,int colour)
58 *
59 * Use
60 * Adds a border to an icon in the colour dbox. It chooses the most
61 * suitable colour for the border as being the nearest colour available in
62 * the WIMP palette to either black or white, whichever contrasts most
63 * with the colour to border.
64 *
65 * Parameters
66 * dbox d == the colour dbox handle
67 * int colour == the colour to border
68 */
69
70 static void colSelect__addBorder(dbox d,int colour)
71 {
72 static wimp_paletteword blacknwhite[]={0,0,0,0, 0,255,255,255,};
73 static wimp_palettestr wimppal;
74 int col;
75 wimpt_noerr(wimp_readpalette(&wimppal));
76 wimpt_noerr(colourtran_return_Oppcolourformode(wimppal.c[colour],0,
77 blacknwhite,&col));
78 wimpt_noerr(colourtran_return_colourformode(blacknwhite[col],12,
79 wimppal.c,&col));
80 /* --- We now have the correctly contrasting colour in col --- */
81 wimpt_noerr(wimp_set_icon_state(dbox_syshandle(d),
82 colour+glass_CSCOLOURS,5+(col<<24),0x0f000005));
83 }
84
85 /*
86 * void colSelect__removeBorder(dbox d,int colour)
87 *
88 * Use
89 * Removes the 'selected' border from the colour specified.
90 *
91 * Parameters
92 * dbox d == the colour dbox handle
93 * int colour == the colour to unborder
94 */
95
96 static void colSelect__removeBorder(dbox d,int colour)
97 {
98 wimpt_noerr(wimp_set_icon_state(dbox_syshandle(d),
99 colour+glass_CSCOLOURS,0,0x0f000005));
100 }
101
102 /*----- External routines -------------------------------------------------*/
103
104 /*
105 * void colSelect_setColourButton(dbox d,dbox_field f,int colour)
106 *
107 * Use
108 * Sets a colour button to show a colour
109 *
110 * Parameters
111 * dbox d == dbox containing button
112 * dbox_field f == the icon which is the button
113 * int colour == colour to set the button. 255 means transparent
114 */
115
116 void colSelect_setColourButton(dbox d,dbox_field f,int colour)
117 {
118 if (colour==255)
119 {
120 wimpt_noerr(wimp_set_icon_state(dbox_syshandle(d),f,
121 0x10000003,0xf0000003));
122 }
123 else
124 {
125 wimpt_noerr(wimp_set_icon_state(dbox_syshandle(d),f,
126 0x00000001+(colour<<28),0xf0000003));
127 }
128 }
129
130 /*
131 * BOOL colSelect__raw(dbox d,wimp_eventstr *e,void *handle)
132 *
133 * Use
134 * Handles raw events (keypresses in particular) in the Glass colour box.
135 *
136 * Parameters
137 * dbox d == the dialogue box handle in question
138 * wimp_eventstr *e == the wimp event block
139 * void *handle == pointer to colour value
140 *
141 * Returns
142 * Whether the event was interesting or not.
143 */
144
145 static BOOL colSelect__raw(dbox d,wimp_eventstr *e,void *handle)
146 {
147 int *c = handle;
148 BOOL handled = FALSE;
149 switch (e->e)
150 {
151 case wimp_EKEY: {
152 unsigned mask = 0;
153 int offset = 0;
154 int ncol;
155 if (dbox_selecticon(d,glass_CSTRANS,dbox_READSTATE))
156 break;
157 switch (e->data.key.chcode)
158 {
159 case key_Left:
160 mask = 0xC;
161 offset = -1;
162 break;
163 case key_Right:
164 mask = 0xC;
165 offset = 1;
166 break;
167 case key_Up:
168 mask = ~0xC;
169 offset = -4;
170 break;
171 case key_Down:
172 mask = ~0xC;
173 offset = 4;
174 break;
175 }
176 if (!mask)
177 break;
178 handled = TRUE;
179 ncol = *c + offset;
180 if ((ncol ^ *c) & mask)
181 break;
182 colSelect__removeBorder(d,*c);
183 colSelect__addBorder(d,ncol);
184 *c = ncol;
185 break;
186 }
187 }
188 return (handled);
189 }
190
191 /*
192 * void colSelect(dbox d,dbox_field f,wimp_bbits bbits,char *editing,
193 * BOOL allowTrans,colSelect_proc proc,void *handle)
194 *
195 * Use
196 * Handles mouse events on a colour button.
197 *
198 * Parameters
199 * dbox d == the dialogue containing the colour button
200 * dbox_field f == the icon which is the colour button
201 * wimp_bbits bbits == button status that prompted this
202 * char *editing == what we're editing (for dialogue)
203 * BOOL allowTrans == whether we're allowed transparent colour
204 * colSelect_proc proc == routine to take notice of any changes
205 * void *handle == pointer to pass to the proc
206 */
207
208 void colSelect(dbox d,dbox_field f,wimp_bbits bbits,char *editing,
209 BOOL allowTrans,colSelect_proc proc,void *handle)
210 {
211 int curcol;
212 wimp_icon ic;
213 dbox cs;
214 dbox_field cf;
215 BOOL done=FALSE;
216 wimpt_noerr(wimp_get_icon_info(dbox_syshandle(d),f,&ic));
217 curcol=(ic.flags>>28) & 15;
218 if (ic.flags & 2)
219 curcol=255;
220 switch (bbits)
221 {
222 case wimp_BLEFT:
223 switch (curcol)
224 {
225 case 255:
226 curcol=0;
227 break;
228 case 15:
229 curcol=(allowTrans ? 255 : 0);
230 break;
231 default:
232 curcol++;
233 break;
234 }
235 colSelect_setColourButton(d,f,curcol);
236 proc(d,f,curcol,handle);
237 break;
238 case wimp_BRIGHT:
239 switch (curcol)
240 {
241 case 255:
242 curcol=15;
243 break;
244 case 0:
245 curcol=(allowTrans ? 255 : 15);
246 break;
247 default:
248 curcol--;
249 break;
250 }
251 colSelect_setColourButton(d,f,curcol);
252 proc(d,f,curcol,handle);
253 break;
254 case wimp_BMID:
255 if (cs=dbox_create("colourSel"),!cs)
256 return;
257 if (!allowTrans)
258 wimpt_noerr(wimp_set_icon_state(dbox_syshandle(cs),glass_CSTRANS,
259 1<<23,1<<23));
260 if (curcol==255)
261 {
262 dbox_selecticon(cs,glass_CSTRANS,TRUE);
263 curcol=7;
264 }
265 else
266 {
267 dbox_selecticon(cs,glass_CSTRANS,FALSE);
268 colSelect__addBorder(cs,curcol);
269 }
270 dbox_setfield(cs,glass_CSEDITING,"%s",editing);
271 dbox_rawEventHandler(cs,colSelect__raw,&curcol);
272 dbox_display(cs,dbox_MENU_OVERPTR);
273 {
274 wimp_caretstr c;
275 c.w = dbox_syshandle(cs);
276 c.i = -1;
277 c.x = -500;
278 c.y = 0;
279 c.height = 40;
280 c.index = -1;
281 wimp_set_caret_pos(&c);
282 }
283 while (!done)
284 {
285 cf=dbox_fillin(cs);
286 switch (cf)
287 {
288 case dbox_CLOSE:
289 dbox_delete(cs);
290 done=TRUE;
291 break;
292 case dbox_HELP:
293 help_startHelp();
294 help_addLine(msgs_lookup("cshCSDB"));
295 help_readFromIcon();
296 help_endHelp();
297 break;
298 case glass_CSCANCEL:
299 dbox_clickicon(cs,cf);
300 dbox_hide(cs);
301 dbox_unclick();
302 dbox_delete(cs);
303 done=TRUE;
304 break;
305 case glass_CSOK:
306 dbox_clickicon(cs,cf);
307 if (dbox_selecticon(cs,glass_CSTRANS,dbox_READSTATE))
308 {
309 colSelect_setColourButton(d,f,255);
310 proc(d,f,255,handle);
311 }
312 else
313 {
314 colSelect_setColourButton(d,f,curcol);
315 proc(d,f,curcol,handle);
316 }
317 if (!dbox_wasAdjustClick())
318 dbox_hide(cs);
319 dbox_unclick();
320 if (!dbox_wasAdjustClick())
321 {
322 dbox_delete(cs);
323 done=TRUE;
324 }
325 break;
326 case glass_CSTRANS:
327 if (dbox_selecticon(cs,glass_CSTRANS,dbox_READSTATE))
328 colSelect__removeBorder(cs,curcol);
329 else
330 colSelect__addBorder(cs,curcol);
331 break;
332 default:
333 cf-=glass_CSCOLOURS;
334 if (cf>=0 && cf<=15 && (cf!=curcol ||
335 dbox_selecticon(cs,glass_CSTRANS,dbox_READSTATE)))
336 {
337 if (!dbox_selecticon(cs,glass_CSTRANS,FALSE))
338 colSelect__removeBorder(cs,curcol);
339 colSelect__addBorder(cs,cf);
340 curcol=cf;
341 }
342 break;
343 }
344 }
345 break;
346 }
347 }