chiark / gitweb /
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 }