/* * See Licensing and Copyright notice in naev.h */ /** * @file cust.c * * @brief Custom widget. */ #include "tk/toolkit_priv.h" #include "opengl.h" static void cst_render( Widget* cst, double bx, double by ); static void cst_renderOverlay( Widget* cst, double bx, double by ); static Widget *cst_getWidget( const unsigned int wid, const char *name ); /** * @brief Adds a custom widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * You are in charge of the rendering and handling mouse input for this widget. * Mouse events outside the widget position won't be passed on. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param border Whether or not it should have a border. * @param render Render function, passes the position and dimensions of the * widget as parameters. * @param mouse Mouse function, passes the window id, event and position as * parameters. */ void window_addCust( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ 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 ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_CUST; /* specific */ wgt->render = cst_render; wgt->renderOverlay = cst_renderOverlay; wgt->dat.cst.border = border; wgt->dat.cst.render = render; wgt->dat.cst.mouse = mouse; wgt->dat.cst.clip = 1; wgt->dat.cst.userdata = data; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); } /** * @brief Renders a custom widget. * * @param cst Custom widget to render. * @param bx Base X position. * @param by Base Y position. */ static void cst_render( Widget* cst, double bx, double by ) { double x,y; x = bx + cst->x; y = by + cst->y; if (cst->dat.cst.border) { /* inner outline */ toolkit_drawOutline( x, y+1, cst->w+1, cst->h+1, 0., toolkit_colLight, toolkit_col ); /* outer outline */ toolkit_drawOutline( x, y, cst->w+1, cst->h+1, 1., toolkit_colDark, NULL ); } if (cst->dat.cst.clip != 0) gl_clipRect( x, y, cst->w, cst->h ); cst->dat.cst.render ( x, y, cst->w, cst->h, cst->dat.cst.userdata ); if (cst->dat.cst.clip != 0) gl_unclipRect(); } /** * @brief Renders the widget overlay. */ static void cst_renderOverlay( Widget* cst, double bx, double by ) { double x,y; x = bx + cst->x; y = by + cst->y; if (cst->dat.cst.clip != 0) gl_clipRect( x, y, cst->w, cst->h ); if (cst->dat.cst.renderOverlay != NULL) cst->dat.cst.renderOverlay ( x, y, cst->w, cst->h, cst->dat.cst.userdata ); if (cst->dat.cst.clip != 0) gl_unclipRect(); } /** * @brief Gets a custom widget. */ static Widget *cst_getWidget( const unsigned int wid, const char *name ) { Widget *wgt; /* Get widget. */ wgt = window_getwgt(wid,name); if (wgt == NULL) return NULL; /* Make sure it is a custom widget. */ if (wgt->type != WIDGET_CUST) { DEBUG("Widget is not a custom widget: '%s'", name); return NULL; } return wgt; } /** * @brief Changes clipping settings on a custom widget. * * @param wid Window to which widget belongs. * @param name Name of the widget. * @param clip If 0 disables clipping, otherwise enables clipping. */ void window_custSetClipping( const unsigned int wid, const char *name, int clip ) { Widget *wgt = cst_getWidget( wid, name ); if (wgt == NULL) return; /* Set the clipping. */ wgt->dat.cst.clip = clip; } /** * @brief Sets the widget overlay. * * @param wid Window to which widget belongs. * @param name Name of the widget. * @param renderOverlay Function to render widget overlay, NULL disables. */ void window_custSetOverlay( const unsigned int wid, const char *name, void (*renderOverlay) (double bx, double by, double bw, double bh, void *data) ) { Widget *wgt = cst_getWidget( wid, name ); if (wgt == NULL) return; wgt->dat.cst.renderOverlay = renderOverlay; } /** * @brief Gets the widget user data. * * @param wid Window to which widget belongs. * @param name Name of the widget. * @return A pointer to the widget user data. */ void* window_custGetData( const unsigned int wid, const char *name ) { Widget *wgt = cst_getWidget( wid, name ); if (wgt == NULL) return NULL; return wgt->dat.cst.userdata; }