1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
4
5 /**
6 * @file cust.c
7 *
8 * @brief Custom widget.
9 */
10
11
12 #include "tk/toolkit_priv.h"
13
14 #include "opengl.h"
15
16
17 static void cst_render( Widget* cst, double bx, double by );
18 static void cst_renderOverlay( Widget* cst, double bx, double by );
19 static Widget *cst_getWidget( const unsigned int wid, const char *name );
20
21
22 /**
23 * @brief Adds a custom widget to a window.
24 *
25 * Position origin is 0,0 at bottom left. If you use negative X or Y
26 * positions. They actually count from the opposite side in.
27 *
28 * You are in charge of the rendering and handling mouse input for this widget.
29 * Mouse events outside the widget position won't be passed on.
30 *
31 * @param wid ID of the window to add the widget to.
32 * @param x X position within the window to use.
33 * @param y Y position within the window to use.
34 * @param w Width of the widget.
35 * @param h Height of the widget.
36 * @param name Name of the widget to use internally.
37 * @param border Whether or not it should have a border.
38 * @param render Render function, passes the position and dimensions of the
39 * widget as parameters.
40 * @param mouse Mouse function, passes the window id, event and position as
41 * parameters.
42 */
window_addCust(const unsigned int wid,const int x,const int y,const int w,const int h,char * name,const int border,void (* render)(double x,double y,double w,double h,void * data),int (* mouse)(unsigned int wid,SDL_Event * event,double x,double y,double w,double h,void * data),void * data)43 void window_addCust( const unsigned int wid,
44 const int x, const int y, /* position */
45 const int w, const int h, /* size */
46 char* name, const int border,
47 void (*render) (double x, double y, double w, double h, void *data),
48 int (*mouse) (unsigned int wid, SDL_Event* event,
49 double x, double y, double w, double h, void *data),
50 void *data )
51 {
52 Window *wdw = window_wget(wid);
53 Widget *wgt = window_newWidget(wdw, name);
54 if (wgt == NULL)
55 return;
56
57 /* generic */
58 wgt->type = WIDGET_CUST;
59
60 /* specific */
61 wgt->render = cst_render;
62 wgt->renderOverlay = cst_renderOverlay;
63 wgt->dat.cst.border = border;
64 wgt->dat.cst.render = render;
65 wgt->dat.cst.mouse = mouse;
66 wgt->dat.cst.clip = 1;
67 wgt->dat.cst.userdata = data;
68
69 /* position/size */
70 wgt->w = (double) w;
71 wgt->h = (double) h;
72 toolkit_setPos( wdw, wgt, x, y );
73 }
74
75
76 /**
77 * @brief Renders a custom widget.
78 *
79 * @param cst Custom widget to render.
80 * @param bx Base X position.
81 * @param by Base Y position.
82 */
cst_render(Widget * cst,double bx,double by)83 static void cst_render( Widget* cst, double bx, double by )
84 {
85 double x,y;
86
87 x = bx + cst->x;
88 y = by + cst->y;
89
90 if (cst->dat.cst.border) {
91 /* inner outline */
92 toolkit_drawOutline( x, y+1, cst->w+1, cst->h+1, 0.,
93 toolkit_colLight, toolkit_col );
94 /* outer outline */
95 toolkit_drawOutline( x, y, cst->w+1, cst->h+1, 1.,
96 toolkit_colDark, NULL );
97 }
98
99 if (cst->dat.cst.clip != 0)
100 gl_clipRect( x, y, cst->w, cst->h );
101 cst->dat.cst.render ( x, y, cst->w, cst->h, cst->dat.cst.userdata );
102 if (cst->dat.cst.clip != 0)
103 gl_unclipRect();
104 }
105
106
107 /**
108 * @brief Renders the widget overlay.
109 */
cst_renderOverlay(Widget * cst,double bx,double by)110 static void cst_renderOverlay( Widget* cst, double bx, double by )
111 {
112 double x,y;
113
114 x = bx + cst->x;
115 y = by + cst->y;
116
117 if (cst->dat.cst.clip != 0)
118 gl_clipRect( x, y, cst->w, cst->h );
119 if (cst->dat.cst.renderOverlay != NULL)
120 cst->dat.cst.renderOverlay ( x, y, cst->w, cst->h, cst->dat.cst.userdata );
121 if (cst->dat.cst.clip != 0)
122 gl_unclipRect();
123 }
124
125
126 /**
127 * @brief Gets a custom widget.
128 */
cst_getWidget(const unsigned int wid,const char * name)129 static Widget *cst_getWidget( const unsigned int wid, const char *name )
130 {
131 Widget *wgt;
132
133 /* Get widget. */
134 wgt = window_getwgt(wid,name);
135 if (wgt == NULL)
136 return NULL;
137
138 /* Make sure it is a custom widget. */
139 if (wgt->type != WIDGET_CUST) {
140 DEBUG("Widget is not a custom widget: '%s'", name);
141 return NULL;
142 }
143
144 return wgt;
145 }
146
147
148 /**
149 * @brief Changes clipping settings on a custom widget.
150 *
151 * @param wid Window to which widget belongs.
152 * @param name Name of the widget.
153 * @param clip If 0 disables clipping, otherwise enables clipping.
154 */
window_custSetClipping(const unsigned int wid,const char * name,int clip)155 void window_custSetClipping( const unsigned int wid, const char *name, int clip )
156 {
157 Widget *wgt = cst_getWidget( wid, name );
158 if (wgt == NULL)
159 return;
160
161 /* Set the clipping. */
162 wgt->dat.cst.clip = clip;
163 }
164
165
166 /**
167 * @brief Sets the widget overlay.
168 *
169 * @param wid Window to which widget belongs.
170 * @param name Name of the widget.
171 * @param renderOverlay Function to render widget overlay, NULL disables.
172 */
window_custSetOverlay(const unsigned int wid,const char * name,void (* renderOverlay)(double bx,double by,double bw,double bh,void * data))173 void window_custSetOverlay( const unsigned int wid, const char *name,
174 void (*renderOverlay) (double bx, double by, double bw, double bh, void *data) )
175 {
176 Widget *wgt = cst_getWidget( wid, name );
177 if (wgt == NULL)
178 return;
179
180 wgt->dat.cst.renderOverlay = renderOverlay;
181 }
182
183
184 /**
185 * @brief Gets the widget user data.
186 *
187 * @param wid Window to which widget belongs.
188 * @param name Name of the widget.
189 * @return A pointer to the widget user data.
190 */
window_custGetData(const unsigned int wid,const char * name)191 void* window_custGetData( const unsigned int wid, const char *name )
192 {
193 Widget *wgt = cst_getWidget( wid, name );
194 if (wgt == NULL)
195 return NULL;
196
197 return wgt->dat.cst.userdata;
198 }
199
200
201