nuclear@3: #include nuclear@5: #include nuclear@5: #include nuclear@3: #include "theme.h" nuclear@3: #include "widget.h" nuclear@3: nuclear@3: #ifdef WIN32 nuclear@3: #include nuclear@5: nuclear@5: static void *dlopen(const char *name, int flags); nuclear@5: static void dlclose(void *so); nuclear@5: static void dlsym(void *so, const char *symbol); nuclear@5: #else nuclear@5: #include nuclear@5: #include nuclear@3: #endif nuclear@5: nuclear@3: #ifdef __APPLE__ nuclear@3: #include nuclear@3: #else nuclear@3: #include nuclear@3: #endif nuclear@3: nuclear@3: nuclear@4: namespace goatkit { nuclear@3: nuclear@3: Theme *theme; nuclear@5: static std::vector search_paths; nuclear@5: nuclear@5: nuclear@5: void add_theme_path(const char *path) nuclear@5: { nuclear@5: if(!path || !*path) return; nuclear@5: nuclear@5: std::string s = path; nuclear@5: int last = s.length() - 1; nuclear@5: if(s[last] == '/' || s[last] == '\\') { nuclear@5: s.erase(last); nuclear@5: } nuclear@5: nuclear@5: if(std::find(search_paths.begin(), search_paths.end(), s) != search_paths.end()) { nuclear@5: return; nuclear@5: } nuclear@5: nuclear@5: search_paths.push_back(s); nuclear@5: } nuclear@3: nuclear@3: Theme::Theme() nuclear@3: { nuclear@3: so = 0; nuclear@3: } nuclear@3: nuclear@5: Theme::~Theme() nuclear@5: { nuclear@5: unload(); nuclear@5: } nuclear@5: nuclear@5: typedef WidgetDrawFunc (*LookupFunc)(const char*); nuclear@5: nuclear@3: bool Theme::load(const char *name) nuclear@3: { nuclear@5: unload(); nuclear@5: nuclear@5: if(!(so = dlopen(name, RTLD_LAZY))) { nuclear@5: for(size_t i=0; i::const_iterator it = func_cache.find(type); nuclear@5: if(it == func_cache.end()) { nuclear@5: // don't have it cached, try to look it up nuclear@5: WidgetDrawFunc func; nuclear@5: if(lookup_theme_draw_func && (func = lookup_theme_draw_func(type))) { nuclear@5: func_cache[type] = func; nuclear@5: return func; nuclear@5: } nuclear@5: nuclear@5: // can't look it up, return the default nuclear@3: return default_draw_func; nuclear@3: } nuclear@3: return it->second; nuclear@3: } nuclear@3: nuclear@3: #define LERP(a, b, t) ((a) + ((b) - (a)) * t) nuclear@3: #define DEF_TEX_SZ 32 nuclear@3: void default_draw_func(const Widget *w) nuclear@3: { nuclear@3: static unsigned int tex; nuclear@3: nuclear@3: if(!tex) { nuclear@3: unsigned char *pixels = new unsigned char[DEF_TEX_SZ * DEF_TEX_SZ * 3]; nuclear@3: unsigned char *ptr = pixels; nuclear@3: for(int i=0; iget_position(); nuclear@3: Vec2 sz = w->get_size(); nuclear@3: float aspect = sz.x / sz.y; nuclear@3: nuclear@3: glPushAttrib(GL_ENABLE_BIT); nuclear@3: glEnable(GL_TEXTURE_2D); nuclear@3: glBindTexture(GL_TEXTURE_2D, tex); nuclear@3: nuclear@3: float offs = w->get_pressed() * 0.1 * sz.y; nuclear@3: glMatrixMode(GL_MODELVIEW); nuclear@3: glPushMatrix(); nuclear@3: glTranslatef(offs, -offs, 0); nuclear@3: nuclear@3: float active = w->get_active(); nuclear@3: float hover = w->get_under_mouse(); nuclear@3: nuclear@3: float rg = LERP(0.4, 1.0, hover); nuclear@3: float b = LERP(rg, 0, active); nuclear@3: glColor3f(rg, rg, b); nuclear@3: nuclear@3: glBegin(GL_QUADS); nuclear@3: glTexCoord2f(0, 1); nuclear@3: glVertex2f(pos.x, pos.y); nuclear@3: glTexCoord2f(aspect, 1); nuclear@3: glVertex2f(pos.x + sz.x, pos.y); nuclear@3: glTexCoord2f(aspect, 0); nuclear@3: glVertex2f(pos.x + sz.x, pos.y + sz.y); nuclear@3: glTexCoord2f(0, 0); nuclear@3: glVertex2f(pos.x, pos.y + sz.y); nuclear@3: glEnd(); nuclear@3: nuclear@3: glPopMatrix(); nuclear@3: nuclear@3: glPopAttrib(); nuclear@3: } nuclear@3: nuclear@4: } // namespace goatkit nuclear@5: nuclear@5: #ifdef WIN32 nuclear@5: // XXX untested nuclear@5: static void *dlopen(const char *name, int flags) nuclear@5: { nuclear@5: return LoadLibrary(name); nuclear@5: } nuclear@5: nuclear@5: static void dlclose(void *so) nuclear@5: { nuclear@5: // TODO nuclear@5: } nuclear@5: nuclear@5: static void dlsym(void *so, const char *symbol) nuclear@5: { nuclear@5: return GetProcAddress(so, symbol); nuclear@5: } nuclear@5: #endif