1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: n:/project/cit/src/RCS/mfdgadg.c $
21 * $Revision: 1.5 $
22 * $Author: mahk $
23 * $Date: 1994/02/16 09:26:50 $
24 *
25 * $Log: mfdgadg.c $
26 * Revision 1.5 1994/02/16 09:26:50 mahk
27 * Hey, fixed my goofy bugs.
28 *
29 * Revision 1.4 1994/02/16 09:19:57 mahk
30 * Wrote goofy resizing code.
31 *
32 * Revision 1.3 1994/01/15 15:12:04 mahk
33 * Changed buttonarray spacing.
34 *
35 * Revision 1.2 1993/10/20 05:41:33 mahk
36 * Added a slider gadget.
37 *
38 * Revision 1.1 1993/09/15 10:54:30 mahk
39 * Initial revision
40 *
41 *
42 */
43
44 #include <stdlib.h>
45
46 #include "mfdgadg.h"
47
48 extern void mouse_unconstrain(void);
49 uchar mfd_buttonarray_handlerproc(MFD *mfd, uiEvent *ev, MFDhandler *h);
50 uchar mfd_slider_handler(MFD *mfd, uiEvent *ev, MFDhandler *h);
51
52 // =======================
53 // BUTTON ARRAYS
54 // =======================
55
56 // ---------
57 // INTERNALS
58 // ---------
59
60 typedef struct _mfd_bttnarray {
61 LGPoint bdims; // Diminsions of button array
62 LGPoint bspace; // pixel spacing between buttons.
63 LGPoint bsize; // pixel size of buttons.
64 MFDBttnCallback cb;
65 void *cbdata;
66 } MFDBttnArray;
67
mfd_buttonarray_handlerproc(MFD * mfd,uiEvent * ev,MFDhandler * h)68 uchar mfd_buttonarray_handlerproc(MFD *mfd, uiEvent *ev, MFDhandler *h) {
69 MFDBttnArray *ba = (MFDBttnArray *)(h->data);
70 LGPoint bttn;
71 LGPoint pos;
72 if (ev->type != UI_EVENT_MOUSE || !(ev->subtype & ~MOUSE_MOTION))
73 return FALSE;
74 pos.x = ev->pos.x - mfd->rect.ul.x - h->r.ul.x;
75 pos.y = ev->pos.y - mfd->rect.ul.y - h->r.ul.y;
76 // Make sure its on a button, not a space.
77 if (pos.x % (ba->bspace.x + ba->bsize.x) >= ba->bsize.x || pos.y % (ba->bspace.y + ba->bsize.y) >= ba->bsize.y)
78 return FALSE;
79 bttn.x = lg_min(pos.x / (ba->bspace.x + ba->bsize.x), ba->bdims.x - 1);
80 bttn.y = lg_min(pos.y / (ba->bspace.y + ba->bsize.y), ba->bdims.y - 1);
81 return ba->cb(mfd, bttn, ev, ba->cbdata);
82 }
83
84 // ---------
85 // EXTERNALS
86 // ---------
87
MFDBttnArrayInit(MFDhandler * h,LGRect * r,LGPoint bdims,LGPoint bsize,MFDBttnCallback cb,void * cbdata)88 errtype MFDBttnArrayInit(MFDhandler *h, LGRect *r, LGPoint bdims, LGPoint bsize, MFDBttnCallback cb, void *cbdata) {
89 if (bsize.x < 1 || bsize.y < 1)
90 return ERR_RANGE;
91 MFDBttnArray *ba = (MFDBttnArray *)malloc(sizeof(MFDBttnArray));
92 if (ba == NULL)
93 return ERR_NOMEM;
94 h->r = *r;
95 h->data = ba;
96 h->proc = mfd_buttonarray_handlerproc;
97 ba->bdims = bdims;
98 ba->bsize = bsize;
99 if (bdims.x > 1)
100 ba->bspace.x = (RectWidth(r) - bsize.x) / (bdims.x - 1) - bsize.x;
101 else
102 ba->bspace.x = RectWidth(r) - bsize.x;
103 if (bdims.y > 1)
104 ba->bspace.y = (RectHeight(r) - bsize.y) / (bdims.y - 1) - bsize.y;
105 else
106 ba->bspace.y = RectHeight(r) - bsize.y;
107 ba->cb = cb;
108 ba->cbdata = cbdata;
109 return OK;
110 }
111
MFDBttnArrayShutdown(MFDhandler * h)112 errtype MFDBttnArrayShutdown(MFDhandler *h) {
113 free(h->data);
114 h->proc = NULL;
115 return OK;
116 }
117
MFDBttnArrayResize(MFDhandler * h,LGRect * r,LGPoint bdims,LGPoint bsize)118 errtype MFDBttnArrayResize(MFDhandler *h, LGRect *r, LGPoint bdims, LGPoint bsize) {
119 MFDBttnArray *ba = (MFDBttnArray *)h->data;
120 if (bsize.x < 1 || bsize.y < 1)
121 return ERR_RANGE;
122 h->r = *r;
123 ba->bdims = bdims;
124 ba->bsize = bsize;
125 if (bdims.x > 1)
126 ba->bspace.x = (RectWidth(r) - bsize.x) / (bdims.x - 1) - bsize.x;
127 else
128 ba->bspace.x = RectWidth(r) - bsize.x;
129 if (bdims.y > 1)
130 ba->bspace.y = (RectHeight(r) - bsize.y) / (bdims.y - 1) - bsize.y;
131 else
132 ba->bspace.y = RectHeight(r) - bsize.y;
133 return OK;
134 }
135
136 // ======================
137 // SLIDERS
138 // ======================
139
140 // ---------
141 // INTERNALS
142 // ---------
143
144 typedef struct _mfd_slider {
145 MFDSliderCallback cb;
146 void *data;
147 uchar bttndown;
148 } MFDSlider;
149
mfd_slider_handler(MFD * mfd,uiEvent * ev,MFDhandler * h)150 uchar mfd_slider_handler(MFD *mfd, uiEvent *ev, MFDhandler *h) {
151 short x = mfd->rect.ul.x + h->r.ul.x;
152 short y = mfd->rect.ul.y + h->r.ul.y;
153 uchar retval = TRUE;
154 MFDSlider *sl = (MFDSlider *)(h->data);
155 LGPoint pos = ev->pos;
156 pos.x -= x;
157 pos.y -= y;
158 if (ev->type != UI_EVENT_MOUSE && ev->type != UI_EVENT_MOUSE_MOVE)
159 return FALSE;
160 if (ev->mouse_data.action & MOUSE_LDOWN) {
161 mouse_constrain_xy(x, y, x + RectWidth(&h->r) - 1, y + RectHeight(&h->r) - 1);
162 sl->bttndown = TRUE;
163 }
164 if (sl->bttndown) {
165 retval = sl->cb(mfd, pos.x, (uiEvent *)ev, sl->data);
166 }
167 if (!(ev->mouse_data.buttons & (1 << MOUSE_LBUTTON))) {
168 sl->bttndown = FALSE;
169 mouse_unconstrain();
170 }
171 return retval;
172 }
173
174 // ---------
175 // EXTERNALS
176 // ---------
177
MFDSliderInit(MFDhandler * h,LGRect * r,MFDSliderCallback cb,void * data)178 errtype MFDSliderInit(MFDhandler *h, LGRect *r, MFDSliderCallback cb, void *data) {
179 MFDSlider *sl = (MFDSlider *)malloc(sizeof(MFDSlider));
180 if (sl == NULL)
181 return ERR_NOMEM;
182 h->r = *r;
183 h->data = sl;
184 h->proc = (MFD_handlerProc)mfd_slider_handler;
185 sl->cb = cb;
186 sl->data = data;
187 sl->bttndown = FALSE;
188 return OK;
189 }
190