/** * @brief Sets up the OSD window. * * @param x X position to render at. * @param y Y position to render at. * @param w Width to render. * @param h Height to render. */ int osd_setup( int x, int y, int w, int h ) { /* Set offsets. */ osd_x = x; osd_y = y; osd_w = w; osd_lines = h / (gl_smallFont.h+5); osd_h = h - h % (gl_smallFont.h+5); /* Calculate some font things. */ osd_tabLen = gl_printWidthRaw( &gl_smallFont, " " ); osd_hyphenLen = gl_printWidthRaw( &gl_smallFont, "- " ); return 0; }
/** * @brief Handles input for an input widget. * * @param inp Input widget to handle event. * @param key Key being handled. * @param mod Mods when key is being pressed. * @return 1 if the event was used, 0 if it wasn't. */ static int inp_key( Widget* inp, SDLKey key, SDLMod mod ) { (void) mod; int n; /* * Handle arrow keys. */ if ((key == SDLK_LEFT) || (key == SDLK_RIGHT)) { /* Move pointer. */ if (key == SDLK_LEFT) { if (inp->dat.inp.pos > 0) inp->dat.inp.pos -= 1; } else if (key == SDLK_RIGHT) { if ((inp->dat.inp.pos < inp->dat.inp.max-1) && (inp->dat.inp.input[inp->dat.inp.pos] != '\0')) inp->dat.inp.pos += 1; } return 1; } /* Only catch some keys. */ if ((key != SDLK_BACKSPACE) && (key != SDLK_RETURN) && (key != SDLK_KP_ENTER)) return 0; if (inp->dat.inp.oneline) { /* backspace -> delete text */ if ((key == SDLK_BACKSPACE) && (inp->dat.inp.pos > 0)) { inp->dat.inp.pos--; memmove( &inp->dat.inp.input[ inp->dat.inp.pos ], &inp->dat.inp.input[ inp->dat.inp.pos+1 ], sizeof(char)*(inp->dat.inp.max - inp->dat.inp.pos - 1) ); inp->dat.inp.input[ inp->dat.inp.max - 1 ] = '\0'; if (inp->dat.inp.view > 0) { n = gl_printWidthRaw( &gl_smallFont, inp->dat.inp.input + inp->dat.inp.view - 1 ); if (n+10 < inp->w) inp->dat.inp.view--; } return 1; } /* in limits. */ else if ((inp->dat.inp.pos < inp->dat.inp.max-1)) { if ((key==SDLK_RETURN || key==SDLK_KP_ENTER) && !inp->dat.inp.oneline) { inp->dat.inp.input[ inp->dat.inp.pos++ ] = '\n'; return 1; } } } return 0; }
/** * @brief Gets the size needed for the dialogue. * * @param title Title of the dialogue. * @param msg Message of the dialogue. * @param[out] width Gets the width needed. * @param[out] height Gets the height needed. * @return The font that matches the size. */ static glFont* dialogue_getSize( const char* title, const char* msg, int* width, int* height ) { glFont* font; double w, h, d; int i, titlelen, msglen; /* Get title length. */ titlelen = gl_printWidthRaw( &gl_defFont, title ); msglen = gl_printWidthRaw( &gl_smallFont, msg ); /* Try widths from 300 to 800 in 50 px increments. * Each subsequent width gets an additional line, following this table: * * 300 px: 2 lines, 540 px total * 350 px: 3 lines, 930 px total * ... * 800 px: 12 lines, 9600 px total */ for (i=0; i<11; i++) if (msglen < (260 + i * 50) * (2 + i)) break; w = 300 + i * 50; w = MAX(w, titlelen+40); /* Expand width if the title is long. */ /* Now we look at proportion. */ font = &gl_smallFont; h = gl_printHeightRaw( font, w-40, msg ); d = ((double)w/(double)h)*(3./4.); /* deformation factor. */ if (fabs(d) > 0.3) { if (h > w) w = h; h = gl_printHeightRaw( font, w-40, msg ); } /* Set values. */ (*width) = w; (*height) = h; return font; }
/** * @brief Adds a button 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. * * @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 ntabs Number of tabs in the widget. * @param tabnames Name of the tabs in the widget. * @return List of created windows. */ unsigned int* window_addTabbedWindow( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ const char* name, int ntabs, const char **tabnames ) { int i; Window *wdw, *wtmp; Widget *wgt; /* Create the Widget. */ wdw = window_wget(wid); wgt = window_newWidget(wdw, name); if (wgt == NULL) return NULL; /* generic */ wgt->type = WIDGET_TABBEDWINDOW; /* specific */ wgt_setFlag( wgt, WGT_FLAG_RAWINPUT ); wgt->rawevent = tab_raw; wgt->render = tab_render; wgt->renderOverlay = tab_renderOverlay; wgt->cleanup = tab_cleanup; wgt->dat.tab.ntabs = ntabs; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); /* Copy tab information. */ wgt->dat.tab.tabnames = malloc( sizeof(char*) * ntabs ); wgt->dat.tab.windows = malloc( sizeof(unsigned int) * ntabs ); wgt->dat.tab.namelen = malloc( sizeof(int) * ntabs ); for (i=0; i<ntabs; i++) { /* Hack to get around possible reallocs. */ wdw = window_wget(wid); /* Get name and length. */ wgt->dat.tab.tabnames[i] = strdup( tabnames[i] ); wgt->dat.tab.namelen[i] = gl_printWidthRaw( &gl_defFont, wgt->dat.tab.tabnames[i] ); /* Create windows. */ wgt->dat.tab.windows[i] = window_create( tabnames[i], wdw->x + x, wdw->y + y + TAB_HEIGHT, wdw->w, wdw->h - TAB_HEIGHT ); wtmp = window_wget( wgt->dat.tab.windows[i] ); /* Set flags. */ window_setFlag( wtmp, WINDOW_NOFOCUS ); window_setFlag( wtmp, WINDOW_NORENDER ); window_setFlag( wtmp, WINDOW_NOINPUT ); window_setFlag( wtmp, WINDOW_NOBORDER ); } /* Return list of windows. */ return wgt->dat.tab.windows; }
/** * @brief Gets the width that it would take to print some text. * * Does not display text on screen. * * @param ft_font Font to use (NULL defaults to gl_defFont). * @param fmt Text to calculate the length of. * @return The length of the text in pixels. */ int gl_printWidth( const glFont *ft_font, const char *fmt, ... ) { char text[256]; /* holds the string */ va_list ap; if (fmt == NULL) return 0; else { /* convert the symbols to text */ va_start(ap, fmt); vsnprintf(text, 256, fmt, ap); va_end(ap); } return gl_printWidthRaw( ft_font, text ); }
/** * @brief Gets the size needed for the dialogue. * * @param title Title of the dialogue. * @param msg Message of the dialogue. * @param[out] width Gets the width needed. * @param[out] height Gets the height needed. * @return The font that matches the size. */ static glFont* dialogue_getSize( const char* title, const char* msg, int* width, int* height ) { glFont* font; double w, h, d; int titlelen; #if 0 int len; len = strlen(msg); #endif /* Get title length. */ titlelen = gl_printWidthRaw( &gl_defFont, title ); w = MAX(300, titlelen+40); /* Default width to try. */ /* First we split by text length. */ #if 0 if (len < 50) { font = &gl_defFont; h = gl_printHeightRaw( font, w-40, msg ); } else { #endif /* Now we look at proportion. */ font = &gl_smallFont; /* font = &gl_defFont; */ h = gl_printHeightRaw( font, w-40, msg ); d = ((double)w/(double)h)*(3./4.); /* deformation factor. */ if (fabs(d) > 0.3) { if (h > w) w = h; h = gl_printHeightRaw( font, w-40, msg ); } #if 0 } #endif /* Set values. */ (*width) = w; (*height) = h; return font; }
/** * @brief Renders a input widget. * * @param inp Input widget to render. * @param bx Base X position. * @param by Base Y position. */ static void inp_render( Widget* inp, double bx, double by ) { double x, y, ty; char buf[ PATH_MAX ]; int w; int m; x = bx + inp->x; y = by + inp->y; /* main background */ toolkit_drawRect( x, y, inp->w, inp->h, &cWhite, NULL ); /* center vertically */ if (inp->dat.inp.oneline) ty = y - (inp->h - gl_smallFont.h)/2.; else { WARN("Multi-line input widgets unsupported atm."); return; } /* Draw text. */ gl_printTextRaw( inp->dat.inp.font, inp->w-10., inp->h, x+5., ty, &cBlack, &inp->dat.inp.input[ inp->dat.inp.view ] ); /* Draw cursor. */ if (wgt_isFlag( inp, WGT_FLAG_FOCUSED )) { m = MIN( inp->dat.inp.pos - inp->dat.inp.view, PATH_MAX-1 ); strncpy( buf, &inp->dat.inp.input[ inp->dat.inp.view ], m ); buf[ m ] = '\0'; w = gl_printWidthRaw( inp->dat.inp.font, buf ); toolkit_drawRect( x+5.+w, y + (inp->h - inp->dat.inp.font->h - 4.)/2., 1., inp->dat.inp.font->h + 4., &cBlack, &cBlack ); } /* inner outline */ toolkit_drawOutline( x, y, inp->w, inp->h, 0., toolkit_colLight, toolkit_col ); /* outter outline */ toolkit_drawOutline( x, y, inp->w, inp->h, 1., toolkit_colDark, NULL ); }
/** * @brief Adds a single key to the input. * * @param inp Input widget recieving the key. * @param key Key to recieve. * @return 1 if key was used. */ static int inp_addKey( Widget* inp, SDLKey key ) { int i; int n; char c; /* * Handle arrow keys. * @todo finish implementing, no cursor makes it complicated to see where you are. */ /* Only catch some keys. */ if (!nstd_isgraph(key) && (key != ' ')) return 0; /* No sense to use SDLKey below this. */ c = key; if (inp->dat.inp.oneline) { /* Make sure it's not full. */ if (strlen(inp->dat.inp.input) >= (size_t)inp->dat.inp.max-1) return 0; /* Check to see if is in filter to ignore. */ if (inp->dat.inp.filter != NULL) for (i=0; inp->dat.inp.filter[i] != '\0'; i++) if (inp->dat.inp.filter[i] == c) return 0; /* Ignored. */ /* Add key. */ memmove( &inp->dat.inp.input[ inp->dat.inp.pos+1 ], &inp->dat.inp.input[ inp->dat.inp.pos ], inp->dat.inp.max - inp->dat.inp.pos - 2 ); inp->dat.inp.input[ inp->dat.inp.pos++ ] = c; n = gl_printWidthRaw( inp->dat.inp.font, inp->dat.inp.input+inp->dat.inp.view ); if (n+10 > inp->w) inp->dat.inp.view++; return 1; } return 0; }
/** * @brief Gets the size of the text to print. * * @usage len = gfx.printDim( nil, "Hello World!" ) -- Length of string with normal font * @usage height = gfx.printDim( true, "Longer text", 20 ) -- Dimensions of text block * * @luaparam small Whether or not to use the small font. * @luaparam str Text to calculate length of. * @luaparam width Optional parameter to indicate it is a block of text and to use this width. * @luafunc printDim( small, str, width ) */ static int gfxL_printDim( lua_State *L ) { const char *str; int width; glFont *font; /* Parse parameters. */ font = lua_toboolean(L,1) ? &gl_smallFont : &gl_defFont; str = luaL_checkstring(L,2); if (lua_gettop(L) > 2) width = luaL_checkinteger(L,3); else width = 0; /* Print length. */ if (width == 0) lua_pushnumber( L, gl_printWidthRaw( font, str ) ); else lua_pushnumber( L, gl_printHeightRaw( font, width, str ) ); return 1; }
/** * @brief Opens the audio settings menu. */ static void opt_audio( unsigned int wid ) { (void) wid; int i, j; int cw; int w, h, y, x, l; char buf[32], **s; const char *str; /* Get size. */ window_dimWindow( wid, &w, &h ); /* Close button */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnClose", "Close", opt_close ); window_addButton( wid, -20 - 1*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnApply", "Apply", opt_audioSave ); window_addButton( wid, -20 - 2*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnDefaults", "Defaults", opt_audioDefaults ); /* General options. */ cw = (w-60)/2; x = 20; y = -60; window_addText( wid, x+20, y, cw, 20, 0, "txtSGeneral", NULL, &cDConsole, "General" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkNosound", "Disable all sound/music", NULL, conf.nosound ); y -= 30; str = "Backends"; l = gl_printWidthRaw( NULL, str ); window_addText( wid, x, y, l, 40, 0, "txtSBackends", NULL, NULL, str ); l += 10; i = 0; j = 0; s = malloc(sizeof(char*)*2); #if USE_OPENAL if (strcmp(conf.sound_backend,"openal")==0) j = i; s[i++] = strdup("openal"); #endif /* USE_OPENAL */ #if USE_SDLMIX if (strcmp(conf.sound_backend,"sdlmix")==0) j = i; s[i++] = strdup("sdlmix"); #endif /* USE_SDLMIX */ if (i==0) s[i++] = strdup("none"); window_addList( wid, x+l, y, cw-(x+l), 40, "lstSound", s, i, j, NULL ); y -= 50; /* OpenAL options. */ window_addText( wid, x+20, y, cw, 20, 0, "txtSOpenal", NULL, &cDConsole, "OpenAL" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkEFX", "EFX (More CPU)", NULL, conf.al_efx ); y -= 20; /* Sound levels. */ x = 20 + cw + 20; y = -60; window_addText( wid, x+20, y, 100, 20, 0, "txtSVolume", NULL, &cDConsole, "Volume Levels" ); y -= 30; /* Sound fader. */ opt_audioLevelStr( buf, sizeof(buf), 0, sound_getVolume() ); window_addText( wid, x, y, cw, 20, 1, "txtSound", NULL, NULL, buf ); y -= 20; window_addFader( wid, x, y, cw, 20, "fadSound", 0., 1., sound_getVolume(), opt_setAudioLevel ); window_faderScrollDone( wid, "fadSound", opt_beep ); y -= 40; /* Music fader. */ opt_audioLevelStr( buf, sizeof(buf), 1, music_getVolume() ); window_addText( wid, x, y, cw, 20, 1, "txtMusic", NULL, NULL, buf ); y -= 20; window_addFader( wid, x, y, cw, 20, "fadMusic", 0., 1., music_getVolume(), opt_setAudioLevel ); y -= 20; /* Restart text. */ window_addText( wid, 20, 10, 3*(BUTTON_WIDTH + 20), 30, 0, "txtRestart", &gl_smallFont, &cBlack, NULL ); }
/** * @brief Opens the gameplay menu. */ static void opt_gameplay( unsigned int wid ) { (void) wid; char buf[PATH_MAX]; const char *path; int cw; int w, h, y, x, by, l; char *s; /* Get size. */ window_dimWindow( wid, &w, &h ); /* Close button */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnClose", "Close", opt_close ); window_addButton( wid, -20 - 1*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnApply", "Apply", opt_gameplaySave ); window_addButton( wid, -20 - 2*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnDefaults", "Defaults", opt_gameplayDefaults ); /* Information. */ cw = (w-40); x = 20; y = -60; window_addText( wid, x, y, cw, 20, 1, "txtVersion", NULL, NULL, naev_version(1) ); y -= 20; #ifdef GIT_COMMIT window_addText( wid, x, y, cw, 20, 1, "txtCommit", NULL, NULL, "Commit: "GIT_COMMIT ); #endif /* GIT_COMMIT */ y -= 20; path = ndata_getPath(); if (path == NULL) snprintf( buf, sizeof(buf), "not using ndata" ); else snprintf( buf, sizeof(buf), "ndata: %s", path); window_addText( wid, x, y, cw, 20, 1, "txtNdata", NULL, NULL, buf ); y -= 40; by = y; /* Compiletime stuff. */ cw = (w-60)/2; y = by; x = 20; window_addText( wid, x+20, y, cw, 20, 0, "txtCompile", NULL, &cDConsole, "Compilation Flags" ); y -= 30; window_addText( wid, x, y, cw, h+y-20, 0, "txtFlags", NULL, NULL, "" #ifdef DEBUGGING #ifdef DEBUG_PARANOID "Debug Paranoid\n" #else /* DEBUG_PARANOID */ "Debug\n" #endif /* DEBUG_PARANOID */ #endif /* DEBUGGING */ #if defined(LINUX) "Linux\n" #elif defined(FREEBSD) "FreeBSD\n" #elif defined(MACOSX) "Mac OS X\n" #elif defined(WIN32) "Windows\n" #else "Unknown OS\n" #endif #ifdef USE_OPENAL "With OpenAL\n" #endif /* USE_OPENAL */ #ifdef USE_SDLMIX "With SDL_mixer\n" #endif #ifdef HAVE_LUAJIT "Using Lua JIT\n" #endif #ifdef NDATA_DEF "ndata: "NDATA_DEF"\n" #endif /* NDATA_DEF */ #ifdef PREFSDIR_DEF "preference directory: "PREFSDIR_DEF"\n" #endif /* PREFSDIR_DEF */ ); /* Options. */ y = by; x += cw; /* Autonav abort. */ x = 20 + cw + 20; window_addText( wid, x+65, y, 150, 150, 0, "txtAAutonav", NULL, &cDConsole, "Abort Autonav At:" ); y -= 20; /* Autonav abort fader. */ opt_getAutonavAbortStr( buf, sizeof(buf) ); window_addText( wid, x, y, cw, 20, 1, "txtAutonav", NULL, NULL, buf ); y -= 20; window_addFader( wid, x, y, cw, 20, "fadAutonav", 0., 1., conf.autonav_abort, opt_setAutonavAbort ); y -= 40; window_addText( wid, x+20, y, cw, 20, 0, "txtSettings", NULL, &cDConsole, "Settings" ); y -= 25; window_addCheckbox( wid, x, y, cw, 20, "chkZoomManual", "Enable manual zoom control", NULL, conf.zoom_manual ); y -= 25; window_addCheckbox( wid, x, y, cw, 20, "chkAfterburn", "Enable double-tap afterburn", NULL, conf.afterburn_sens ); y -= 25; window_addCheckbox( wid, x, y, cw, 20, "chkMouseThrust", "Enable mouse-flying thrust control", NULL, conf.mouse_thrust ); y -= 25; window_addCheckbox( wid, x, y, cw, 20, "chkCompress", "Enable savegame compression", NULL, conf.save_compress ); y -= 30; s = "Visible Messages"; l = gl_printWidthRaw( NULL, s ); window_addText( wid, -100, y, l, 20, 1, "txtSMSG", NULL, &cBlack, s ); window_addInput( wid, -50, y, 40, 20, "inpMSG", 4, 1, NULL ); y -= 30; s = "Max Time Compression Factor"; l = gl_printWidthRaw( NULL, s ); window_addText( wid, -100, y, l, 20, 1, "txtTMax", NULL, &cBlack, s ); window_addInput( wid, -50, y, 40, 20, "inpTMax", 4, 1, NULL ); y -= 30; /* Restart text. */ window_addText( wid, 20, 10, 3*(BUTTON_WIDTH + 20), 30, 0, "txtRestart", &gl_smallFont, &cBlack, NULL ); /* Update. */ opt_gameplayUpdate( wid, NULL ); }
/** * @brief Initializes the video window. */ static void opt_video( unsigned int wid ) { (void) wid; int i, j, nres, res_def; char buf[16]; int cw; int w, h, y, x, l; SDL_Rect** modes; char **res; const char *s; /* Get size. */ window_dimWindow( wid, &w, &h ); /* Close button */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnClose", "Close", opt_close ); window_addButton( wid, -20 - 1*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnApply", "Apply", opt_videoSave ); window_addButton( wid, -20 - 2*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnDefaults", "Defaults", opt_videoDefaults ); /* Resolution bits. */ cw = (w-60)/2; x = 20; y = -60; window_addText( wid, x+20, y, 100, 20, 0, "txtSRes", NULL, &cDConsole, "Resolution" ); y -= 40; window_addInput( wid, x, y, 100, 20, "inpRes", 16, 1, NULL ); snprintf( buf, sizeof(buf), "%dx%d", conf.width, conf.height ); window_setInput( wid, "inpRes", buf ); window_setInputFilter( wid, "inpRes", "abcdefghijklmnopqrstuvwyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]{}()-=*/\\'\"~<>!@#$%^&|_`" ); window_addCheckbox( wid, x+20+100, y, 100, 20, "chkFullscreen", "Fullscreen", NULL, conf.fullscreen ); y -= 30; modes = SDL_ListModes( NULL, SDL_OPENGL | SDL_FULLSCREEN ); j = 1; for (i=0; modes[i]; i++) { if ((modes[i]->w == conf.width) && (modes[i]->h == conf.height)) j = 0; } res = malloc( sizeof(char*) * (i+j) ); nres = 0; if (j) { res[0] = malloc(16); snprintf( res[0], 16, "%dx%d", conf.width, conf.height ); res_def = 0; nres = 1; } for (i=0; modes[i]; i++) { res[ nres ] = malloc(16); snprintf( res[ nres ], 16, "%dx%d", modes[i]->w, modes[i]->h ); if ((modes[i]->w == conf.width) && (modes[i]->h == conf.height)) res_def = i; nres++; } window_addList( wid, x, y, 140, 100, "lstRes", res, nres, -1, opt_videoRes ); y -= 150; /* FPS stuff. */ window_addText( wid, x+20, y, 100, 20, 0, "txtFPSTitle", NULL, &cDConsole, "FPS Control" ); y -= 30; s = "FPS Limit"; l = gl_printWidthRaw( NULL, s ); window_addText( wid, x, y, l, 20, 1, "txtSFPS", NULL, &cBlack, s ); window_addInput( wid, x+l+20, y, 40, 20, "inpFPS", 4, 1, NULL ); toolkit_setListPos( wid, "lstRes", res_def); window_setInputFilter( wid, "inpFPS", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]{}()-=*/\\'\"~<>!@#$%^&|_`" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkFPS", "Show FPS", NULL, conf.fps_show ); y -= 40; /* OpenGL options. */ x = 20+cw+20; y = -60; window_addText( wid, x+20, y, 100, 20, 0, "txtSGL", NULL, &cDConsole, "OpenGL" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkVSync", "Vertical Sync", NULL, conf.vsync ); y -= 20; window_addCheckbox( wid, x, y, cw, 20, "chkVBO", "Vertex Buffer Objects*", NULL, conf.vbo ); y -= 20; window_addCheckbox( wid, x, y, cw, 20, "chkMipmaps", "Mipmaps*", NULL, conf.mipmaps ); y -= 20; window_addCheckbox( wid, x, y, cw, 20, "chkInterpolate", "Interpolation*", NULL, conf.interpolate ); y -= 20; window_addCheckbox( wid, x, y, cw, 20, "chkNPOT", "NPOT Textures*", NULL, conf.npot ); y -= 30; window_addText( wid, x, y, cw, 20, 1, "txtSCompat", NULL, &cBlack, "*Disable for compatibility." ); y -= 40; /* Features. */ window_addText( wid, x+20, y, 100, 20, 0, "txtSFeatures", NULL, &cDConsole, "Features" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkEngineGlow", "Engine Glow (More RAM)", NULL, conf.engineglow ); y -= 20; /* Restart text. */ window_addText( wid, 20, 10, 3*(BUTTON_WIDTH + 20), 30, 0, "txtRestart", &gl_smallFont, &cBlack, NULL ); }
/** * @brief Renders an image array. * * @param iar Image array widget to render. * @param bx Base X position. * @param by Base Y position. */ static void iar_render( Widget* iar, double bx, double by ) { int i,j, pos; double x,y, w,h, xcurs,ycurs; double scroll_pos; int xelem, yelem; double xspace; glColour *c, *dc, *lc, tc, fontcolour; int is_selected; int tw; double d; /* * Calculations. */ /* position */ x = bx + iar->x; y = by + iar->y; /* element dimensions */ iar_getDim( iar, &w, &h ); /* number of elements */ xelem = iar->dat.iar.xelem; yelem = iar->dat.iar.yelem; xspace = (double)(((int)iar->w - 10) % (int)w) / (double)(xelem + 1); /* background */ toolkit_drawRect( x, y, iar->w, iar->h, &cBlack, NULL ); /* * Scrollbar. */ d = h * (yelem - (int)(iar->h / h)); if (fabs(d) < 1e-05) scroll_pos = 0.; else scroll_pos = iar->dat.iar.pos / d; toolkit_drawScrollbar( x + iar->w - 10., y, 10., iar->h, scroll_pos ); /* * Main drawing loop. */ gl_clipRect( x, y, iar->w, iar->h ); ycurs = y + iar->h - h + iar->dat.iar.pos; for (j=0; j<yelem; j++) { xcurs = x + xspace; for (i=0; i<xelem; i++) { /* Get position. */ pos = j*xelem + i; /* Out of elements. */ if ((pos) >= iar->dat.iar.nelements) break; is_selected = (iar->dat.iar.selected == pos) ? 1 : 0; fontcolour = cWhite; /* Draw background. */ if (is_selected) toolkit_drawRect( xcurs + 2., ycurs + 2., w - 5., h - 5., &cDConsole, NULL ); else if (iar->dat.iar.background != NULL) { toolkit_drawRect( xcurs + 2., ycurs + 2., w - 5., h - 5., &iar->dat.iar.background[pos], NULL ); tc = iar->dat.iar.background[pos]; if (((tc.r + tc.g + tc.b) / 3) > 0.5) fontcolour = cBlack; } /* image */ if (iar->dat.iar.images[pos] != NULL) gl_blitScale( iar->dat.iar.images[pos], xcurs + 5., ycurs + gl_smallFont.h + 7., iar->dat.iar.iw, iar->dat.iar.ih, NULL ); /* caption */ if (iar->dat.iar.captions[pos] != NULL) gl_printMidRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + 5., (is_selected) ? &cBlack : &fontcolour, iar->dat.iar.captions[pos] ); /* quantity. */ if (iar->dat.iar.quantity != NULL) { if (iar->dat.iar.quantity[pos] != NULL) { /* Rectangle to highlight better. */ tw = gl_printWidthRaw( &gl_smallFont, iar->dat.iar.quantity[pos] ); if (is_selected) tc = cDConsole; else if (iar->dat.iar.background != NULL) tc = iar->dat.iar.background[pos]; else tc = cBlack; tc.a = 0.75; toolkit_drawRect( xcurs + 2., ycurs + 5. + iar->dat.iar.ih, tw + 4., gl_smallFont.h + 4., &tc, NULL ); /* Quantity number. */ gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + 5., ycurs + iar->dat.iar.ih + 7., &fontcolour, iar->dat.iar.quantity[pos] ); } } /* Slot type. */ if (iar->dat.iar.slottype != NULL) { if (iar->dat.iar.slottype[pos] != NULL) { /* Rectangle to highlight better. Width is a hack due to lack of monospace font. */ tw = gl_printWidthRaw( &gl_smallFont, "M" ); if (is_selected) tc = cDConsole; else if (iar->dat.iar.background != NULL) tc = iar->dat.iar.background[pos]; else tc = cBlack; tc.a = 0.75; toolkit_drawRect( xcurs + iar->dat.iar.iw - 6., ycurs + 5. + iar->dat.iar.ih, tw + 2., gl_smallFont.h + 4., &tc, NULL ); /* Slot size letter. */ gl_printMaxRaw( &gl_smallFont, iar->dat.iar.iw, xcurs + iar->dat.iar.iw - 4., ycurs + iar->dat.iar.ih + 7., &fontcolour, iar->dat.iar.slottype[pos] ); } } /* outline */ if (is_selected) { lc = &cWhite; c = &cGrey80; dc = &cGrey60; } else { lc = toolkit_colLight; c = toolkit_col; dc = toolkit_colDark; } toolkit_drawOutline( xcurs + 2., ycurs + 2., w - 4., h - 4., 1., lc, c ); toolkit_drawOutline( xcurs + 2., ycurs + 2., w - 4., h - 4., 2., dc, NULL ); xcurs += w + xspace; } ycurs -= h; } gl_unclipRect(); /* * Final outline. */ toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 1., toolkit_colLight, toolkit_col ); toolkit_drawOutline( x+1, y+1, iar->w-2, iar->h-2, 2., toolkit_colDark, NULL ); }
/** * @brief Creates a list dialogue with OK and Cancel buttons, with a fixed message, * as well as a small extra area for the list to react to item selected events. * * @param title Title of the dialogue. * @param items Items in the list (should be all malloced, automatically freed). * @param nitems Number of items. * @param extrawidth Width of area to add for select_call callback. * @param minheight Minimum height for the window. * @param add_widgets This function is called with the new window as an argument * allowing for initial population of the extra area. * @param select_call (optional) This function is called when a new item in the list * is selected, receiving the window's id and the selected widgets name as * arguments. * @param msg string with text to display. */ int dialogue_listPanelRaw( const char* title, char **items, int nitems, int extrawidth, int minheight, void (*add_widgets) (unsigned int wid, int x, int y, int w, int h), void (*select_call) (unsigned int wid, char* wgtname, int x, int y, int w, int h), const char *msg ) { int i; int w, h, winw, winh; glFont* font; unsigned int wid; int list_width, list_height; int text_height, text_width; int done; if (input_dialogue.input_wid) return -1; font = dialogue_getSize( title, msg, &text_width, &text_height ); /* Calculate size stuff. */ list_width = 0; list_height = 0; for (i=0; i<nitems; i++) { list_width = MAX( list_width, gl_printWidthRaw( &gl_defFont, items[i] ) ); list_height += gl_defFont.h + 5; } list_height += 100; if (list_height > 500) h = (list_height*8)/10; else h = MAX( 300, list_height ); h = MIN( (SCREEN_H*2)/3, h ); w = MAX( list_width + 60, 200 ); winw = w + extrawidth; winh = MAX( h, minheight ); h = winh; /* Create the window. */ wid = window_create( title, -1, -1, winw, winh ); window_setData( wid, &done ); window_addText( wid, 20, -40, w-40, text_height, 0, "txtMsg", font, &cDConsole, msg ); window_setAccept( wid, dialogue_listClose ); window_setCancel( wid, dialogue_listCancel ); if(add_widgets) add_widgets(wid, w, 0, winw, winh); if(select_call) { input_dialogue.x = w; input_dialogue.y = 0; input_dialogue.w = winw; input_dialogue.h = winh; input_dialogue.item_select_cb = select_call; } /* Create the list. */ window_addList( wid, 20, -40-text_height-20, w-40, h - (40+text_height+20) - (20+30+20), "lstDialogue", items, nitems, 0, select_call_wrapper ); /* Create the buttons. */ window_addButton( wid, -20, 20, 60, 30, "btnOK", "OK", dialogue_listClose ); window_addButton( wid, -20-60-20, 20, 60, 30, "btnCancel", "Cancel", dialogue_listCancel ); dialogue_open++; toolkit_loop( &done ); /* cleanup */ input_dialogue.x = 0; input_dialogue.y = 0; input_dialogue.w = 0; input_dialogue.h = 0; input_dialogue.item_select_cb = NULL; return dialogue_listSelected; }
/** * @brief Opens the gameplay menu. */ static void opt_gameplay( unsigned int wid ) { (void) wid; char buf[PATH_MAX]; const char *path; int cw; int w, h, y, x, by, l; char *s; /* Get size. */ window_dimWindow( wid, &w, &h ); /* Close button */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnClose", "Close", opt_close ); window_addButton( wid, -20 - 1*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnApply", "Apply", opt_gameplaySave ); window_addButton( wid, -20 - 2*(BUTTON_WIDTH+20), 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnDefaults", "Defaults", opt_gameplayDefaults ); /* Information. */ cw = (w-40); x = 20; y = -60; window_addText( wid, x, y, cw, 20, 1, "txtVersion", NULL, NULL, naev_version(1) ); y -= 20; #ifdef GIT_COMMIT window_addText( wid, x, y, cw, 20, 1, "txtCommit", NULL, NULL, "Commit: "GIT_COMMIT ); #endif /* GIT_COMMIT */ y -= 20; path = ndata_getPath(); if (path == NULL) snprintf( buf, sizeof(buf), "not using ndata" ); else snprintf( buf, sizeof(buf), "ndata: %s", path); window_addText( wid, x, y, cw, 20, 1, "txtNdata", NULL, NULL, buf ); y -= 50; by = y; /* Compiletime stuff. */ cw = (w-60)/2; y = by; x = 20; window_addText( wid, x+20, y, cw, 20, 0, "txtCompile", NULL, &cDConsole, "Compilation Flags" ); y -= 30; window_addText( wid, x, y, cw, h+y-20, 0, "txtFlags", NULL, NULL, "" #ifdef DEBUGGING #ifdef DEBUG_PARANOID "Debug Paranoid\n" #else /* DEBUG_PARANOID */ "Debug\n" #endif /* DEBUG_PARANOID */ #endif /* DEBUGGING */ #if defined(LINUX) "Linux\n" #elif defined(FREEBSD) "FreeBSD\n" #elif defined(MACOSX) "Mac OS X\n" #elif defined(WIN32) "Windows\n" #else "Unknown OS\n" #endif #ifdef USE_OPENAL "With OpenAL\n" #endif /* USE_OPENAL */ #ifdef USE_SDLMIX "With SDL_mixer\n" #endif #ifdef NDATA_DEF "ndata: "NDATA_DEF"\n" #endif /* NDATA_DEF */ ); /* Options. */ y = by; x += cw; window_addText( wid, x+20, y, cw, 20, 0, "txtSettings", NULL, &cDConsole, "Settings" ); y -= 30; window_addCheckbox( wid, x, y, cw, 20, "chkAfterburn", "Enable doubletap afterburn", NULL, conf.afterburn_sens ); y -= 20; window_addCheckbox( wid, x, y, cw, 20, "chkCompress", "Enable savegame compression", NULL, conf.save_compress ); y -= 50; s = "Visible messages"; l = gl_printWidthRaw( NULL, s ); window_addText( wid, x, y, l, 20, 1, "txtSMSG", NULL, &cBlack, s ); window_addInput( wid, x+l+20, y, 40, 20, "inpMSG", 4, 1 ); y -= 20; /* Restart text. */ window_addText( wid, -20, 20+BUTTON_HEIGHT+20, 3*(BUTTON_WIDTH + 20), 30, 1, "txtRestart", &gl_smallFont, &cBlack, NULL ); /* Update. */ opt_gameplayUpdate( wid, NULL ); }