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