mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
This refactors FontManager to improve it in several ways: 1. Change all the dynamic memory management to use `new`, rather than mixing `new` and `vm_malloc` 2. Change the current font to use an index rather than a pointer 3. Take advantage of more C++11 features to avoid redundant lookups 4. Use case-insensitive name comparison 5. Avoid overflowing the `fnt->filename` field 6. Use `Warning` rather than `Error` in a non-critical error situation
823 lines
17 KiB
C++
823 lines
17 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include "bmpman/bmpman.h"
|
|
#include "cmdline/cmdline.h"
|
|
#include "globalincs/alphacolors.h"
|
|
#include "io/timer.h"
|
|
#include "localization/localize.h"
|
|
#include "osapi/osapi.h"
|
|
#include "parse/parselo.h"
|
|
#include "ui/ui.h"
|
|
#include "ui/uidefs.h"
|
|
|
|
|
|
|
|
// global xstr colors
|
|
color *Xstr_colors[UI_NUM_XSTR_COLORS][3] = {
|
|
{ // UI_XSTR_COLOR_GREEN
|
|
&Color_normal,
|
|
&Color_ui_light_green,
|
|
&Color_ui_green,
|
|
},
|
|
{ // UI_XSTR_COLOR_PINK
|
|
&Color_normal,
|
|
&Color_ui_light_pink,
|
|
&Color_ui_pink,
|
|
},
|
|
};
|
|
|
|
// --------------------------------------------------------------------
|
|
// UI_WINDOW constructor
|
|
//
|
|
//
|
|
UI_WINDOW::UI_WINDOW()
|
|
{
|
|
int idx;
|
|
|
|
mask_bmap_id = -1; // bitmap id of the mask bitmap to define hotspots
|
|
foreground_bmap_id = -1; // bitmap id of the foreground bitmap to display
|
|
mask_bmap_ptr = NULL; // pointer to bitmap of the mask
|
|
mask_data = NULL; // points to raw mask bitmap data
|
|
mask_w = -1; // bitmap width
|
|
mask_h = -1; // bitmap height
|
|
tooltip_handler = NULL; // pointer to function to handle custom tooltips
|
|
|
|
// NULL all the xstring structs
|
|
for(idx=0; idx<MAX_UI_XSTRS; idx++){
|
|
xstrs[idx] = NULL;
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// UI_WINDOW destructor
|
|
//
|
|
//
|
|
UI_WINDOW::~UI_WINDOW()
|
|
{
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// UI_WINDOW::set_mask_bmap()
|
|
//
|
|
// Specify the filename for the mask bitmap to use. This has the hotspots
|
|
// for all the different controls.
|
|
//
|
|
void UI_WINDOW::set_mask_bmap(const char *fname)
|
|
{
|
|
int bmap;
|
|
|
|
bmap = bm_load(fname);
|
|
|
|
if (bmap < 0) {
|
|
Error(LOCATION, "Could not load in %s!", fname);
|
|
|
|
} else {
|
|
set_mask_bmap(bmap, fname);
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::set_mask_bmap(int bmap, const char * /*name*/)
|
|
{
|
|
// int i;
|
|
|
|
// init_tooltips();
|
|
Assert(bmap >= 0);
|
|
|
|
if (bmap != mask_bmap_id) {
|
|
if (mask_bmap_id >= 0){
|
|
bm_unlock(mask_bmap_id);
|
|
}
|
|
|
|
mask_w = -1;
|
|
mask_h = -1;
|
|
|
|
mask_bmap_id = bmap;
|
|
mask_bmap_ptr = bm_lock(mask_bmap_id, 8, BMP_AABITMAP | BMP_MASK_BITMAP);
|
|
mask_data = (ubyte *) mask_bmap_ptr->data;
|
|
bm_get_info( bmap, &mask_w, &mask_h );
|
|
tt_group = -1;
|
|
/*
|
|
for (i=0; i<Num_tooltip_groups; i++){
|
|
if (!stricmp(Tooltip_groups[i].mask, name)){
|
|
tt_group = i;
|
|
}
|
|
}
|
|
*/
|
|
} else {
|
|
nprintf(("UI", "Warning: tried to switch bitmap mask to the same bitmap\n"));
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// UI_WINDOW::set_foreground_bmap()
|
|
//
|
|
// Specify the filename for the mask bitmap to display on the ui window as
|
|
// a background.
|
|
//
|
|
void UI_WINDOW::set_foreground_bmap(const char *fname)
|
|
{
|
|
// load in the background bitmap
|
|
foreground_bmap_id = bm_load(fname);
|
|
if (foreground_bmap_id < 0) {
|
|
Error(LOCATION,"Could not load in %s!",fname);
|
|
}
|
|
}
|
|
|
|
|
|
void UI_WINDOW::create( int _x, int _y, int _w, int _h, int _flags, int _f_id )
|
|
{
|
|
x = _x;
|
|
y = _y;
|
|
w = _w;
|
|
h = _h;
|
|
flags = _flags;
|
|
f_id = font::FontManager::isFontNumberValid(_f_id) ? _f_id : font::FONT1;
|
|
|
|
first_gadget = NULL;
|
|
selected_gadget = NULL;
|
|
tooltip_handler = NULL; // pointer to function to handle custom tooltips
|
|
ignore_gadgets = 0;
|
|
use_hack_to_get_around_stupid_problem_flag = 0;
|
|
|
|
if (_x < 0)
|
|
_x = 0;
|
|
if (_x + _w - 1 >= gr_screen.max_w_unscaled)
|
|
_x = gr_screen.max_w_unscaled - _w;
|
|
if (_y < 0)
|
|
_y = 0;
|
|
if (_y + _h - 1 >= gr_screen.max_h_unscaled)
|
|
_y = gr_screen.max_h_unscaled - _h;
|
|
|
|
game_flush();
|
|
}
|
|
|
|
void UI_WINDOW::release_bitmaps()
|
|
{
|
|
if (mask_bmap_ptr) {
|
|
// done with the mask bitmap, so unlock it
|
|
bm_unlock(mask_bmap_id);
|
|
|
|
// unload the bitmaps
|
|
if (mask_bmap_id >= 0) {
|
|
bm_release(mask_bmap_id);
|
|
mask_bmap_id = -1;
|
|
}
|
|
|
|
mask_data = NULL;
|
|
mask_bmap_ptr = NULL;
|
|
}
|
|
|
|
if (foreground_bmap_id >= 0) {
|
|
bm_release(foreground_bmap_id);
|
|
foreground_bmap_id = -1;
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::destroy()
|
|
{
|
|
UI_GADGET *cur;
|
|
int idx;
|
|
|
|
// free up any bitmaps
|
|
release_bitmaps();
|
|
|
|
// destroy all gadgets
|
|
if (first_gadget) {
|
|
cur = first_gadget;
|
|
do {
|
|
cur->destroy();
|
|
cur = cur->next;
|
|
|
|
} while (cur != first_gadget);
|
|
}
|
|
|
|
// free up all xstrs
|
|
for(idx=0; idx<MAX_UI_XSTRS; idx++){
|
|
// free up this struct
|
|
if(xstrs[idx] != NULL){
|
|
if(xstrs[idx]->xstr != NULL){
|
|
// This const_cast is safe since the string was allocated by vm_strdup
|
|
vm_free(const_cast<char*>(xstrs[idx]->xstr));
|
|
}
|
|
vm_free(xstrs[idx]);
|
|
xstrs[idx] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::draw()
|
|
{
|
|
UI_GADGET *tmp;
|
|
|
|
gr_reset_clip();
|
|
font::set_font(f_id);
|
|
|
|
if (foreground_bmap_id >= 0) {
|
|
gr_set_bitmap(foreground_bmap_id);
|
|
gr_bitmap(x, y, GR_RESIZE_MENU);
|
|
}
|
|
|
|
if (flags & WIN_FILLED) {
|
|
ui_draw_box_out(x, y, x+w-1, y+h-1);
|
|
}
|
|
|
|
if (flags & WIN_BORDER) {
|
|
ui_draw_frame(x-BORDER_WIDTH, y-BORDER_WIDTH, x+w+BORDER_WIDTH-1, y+h+BORDER_WIDTH-1);
|
|
}
|
|
|
|
if (first_gadget) {
|
|
tmp = first_gadget;
|
|
do {
|
|
if (!tmp->hidden)
|
|
tmp->draw();
|
|
|
|
tmp = tmp->next;
|
|
|
|
} while (tmp != first_gadget);
|
|
}
|
|
|
|
if (first_gadget) {
|
|
tmp = first_gadget;
|
|
do {
|
|
if (!tmp->hidden && (tmp->kind == UI_KIND_BUTTON) && ((UI_BUTTON *) tmp)->button_down()){
|
|
tmp->draw();
|
|
}
|
|
|
|
tmp = tmp->next;
|
|
} while (tmp != first_gadget);
|
|
}
|
|
|
|
// draw all xstrs
|
|
draw_xstrs();
|
|
|
|
// draw tooltips
|
|
draw_tooltip();
|
|
|
|
// convenient debug code for showing mouse coords
|
|
if(Cmdline_mouse_coords){
|
|
int mx, my;
|
|
mouse_get_pos(&mx, &my);
|
|
// mprintf(("MOUSE (%d, %d)\n", mx, my));
|
|
gr_set_color_fast(&Color_normal);
|
|
gr_printf_no_resize(mx, my - 12, "%d %d", mx, my);
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::draw_XSTR_forced(UI_GADGET *owner, int frame)
|
|
{
|
|
int idx;
|
|
|
|
// lookup the xstr and draw it if necessary
|
|
for(idx=0; idx<MAX_UI_XSTRS; idx++){
|
|
if((xstrs[idx] != NULL) && (xstrs[idx]->assoc == owner)){
|
|
draw_one_xstr(xstrs[idx], frame);
|
|
}
|
|
}
|
|
}
|
|
|
|
int UI_WINDOW::get_current_hotspot()
|
|
{
|
|
int offset, pixel_val;
|
|
|
|
if (!mask_data){
|
|
return -1;
|
|
}
|
|
|
|
// check the pixel value under the mouse
|
|
offset = ui_mouse.y * gr_screen.max_w_unscaled + ui_mouse.x;
|
|
pixel_val = *(mask_data + offset);
|
|
return pixel_val;
|
|
}
|
|
|
|
void UI_WINDOW::draw_tooltip()
|
|
{
|
|
// int i;
|
|
// tooltip_group *ptr;
|
|
int hotspot;
|
|
UI_GADGET *gadget;
|
|
|
|
if (tt_group < 0)
|
|
return;
|
|
|
|
// ptr = &Tooltip_groups[tt_group];
|
|
hotspot = get_current_hotspot();
|
|
|
|
// mprintf(("HOTSPOT: %d [%d]\n",hotspot, Framecount));
|
|
|
|
/*
|
|
if (hotspot != last_tooltip_hotspot) {
|
|
last_tooltip_hotspot = hotspot;
|
|
last_tooltip_time = timer_get_milliseconds();
|
|
ttx = tty = -1;
|
|
return;
|
|
|
|
} else if (timer_get_milliseconds() - last_tooltip_time < TOOLTIP_DELAY)
|
|
return;
|
|
*/
|
|
|
|
if (first_gadget) {
|
|
gadget = first_gadget;
|
|
do {
|
|
if (gadget->get_hotspot() == hotspot) {
|
|
if (gadget->hidden) // if control is hidden, don't draw tooltip for it.
|
|
return;
|
|
else
|
|
break;
|
|
}
|
|
|
|
gadget = gadget->next;
|
|
|
|
} while (gadget != first_gadget);
|
|
}
|
|
|
|
/*
|
|
for (i=ptr->start; i<ptr->end; i++) {
|
|
if (Tooltips[i].hotspot == hotspot) {
|
|
char *str;
|
|
int w, h;
|
|
|
|
str = Tooltips[i].text;
|
|
if (str[0] == '@') {
|
|
if (!tooltip_handler)
|
|
Error(LOCATION, "No tooltip handler for screen with mask \"%s\"", ptr->mask);
|
|
|
|
str = (*tooltip_handler)(str); // Let the screen handle the custom tooltips
|
|
if (!str)
|
|
return;
|
|
}
|
|
|
|
if (ttx < 0 || tty < 0) {
|
|
gr_get_string_size(&w, &h, str);
|
|
Assert(w < 320 && h < 100);
|
|
ttx = ui_mouse.x - w / 2;
|
|
tty = ui_mouse.y - h;
|
|
}
|
|
|
|
render_tooltip(str);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void UI_WINDOW::render_tooltip(char *str)
|
|
{
|
|
int str_w, str_h;
|
|
|
|
gr_get_string_size(&str_w, &str_h, str);
|
|
Assert(str_w < gr_screen.max_w_unscaled - 4 && str_h < gr_screen.max_h_unscaled - 4);
|
|
|
|
if (ttx < 2)
|
|
ttx = 2;
|
|
|
|
if (tty < 2)
|
|
tty = 2;
|
|
|
|
if (ttx + str_w + 2 > gr_screen.max_w_unscaled)
|
|
ttx = gr_screen.max_w_unscaled - str_w;
|
|
|
|
if (tty + str_h + 2 > gr_screen.max_h_unscaled)
|
|
tty = gr_screen.max_h_unscaled - str_h;
|
|
|
|
gr_set_color_fast(&Color_black);
|
|
gr_rect(ttx - 1, tty - 1, str_w + 2, str_h + 1, GR_RESIZE_MENU);
|
|
|
|
gr_set_color_fast(&Color_bright_white);
|
|
gr_string(ttx, tty, str, GR_RESIZE_MENU);
|
|
}
|
|
|
|
// key_in: If not -1, this means to use this key as input, and not call game_poll()
|
|
int UI_WINDOW::process(int key_in,int process_mouse)
|
|
{
|
|
UI_GADGET *tmp;
|
|
|
|
// only does stuff in non THREADED mode
|
|
os_poll();
|
|
|
|
if (process_mouse){
|
|
ui_mouse_process();
|
|
}
|
|
|
|
if (key_in == -1){
|
|
keypress = game_check_key();
|
|
} else {
|
|
keypress = key_in;
|
|
}
|
|
|
|
last_keypress = keypress;
|
|
do_dump_check();
|
|
if (mouse_captured_gadget && B1_RELEASED){
|
|
mouse_captured_gadget = NULL;
|
|
}
|
|
|
|
// The following code was commented out by NeilK on 4/15/99 to fix a problem we were having with
|
|
// the UI_SLIDER2 class not receiving the process event when the mouse was dragging the scroller
|
|
// but outside the mask region. I checked a handful of other screens and so no adverse affects
|
|
// of this change at the time.
|
|
|
|
/*
|
|
if (mouse_captured_gadget) {
|
|
mouse_captured_gadget->process(); // if a control has captured the mouse, only it gets processed
|
|
use_hack_to_get_around_stupid_problem_flag = 0;
|
|
return last_keypress;
|
|
}
|
|
*/
|
|
if (!first_gadget) {
|
|
use_hack_to_get_around_stupid_problem_flag = 0;
|
|
return last_keypress;
|
|
}
|
|
|
|
check_focus_switch_keys();
|
|
|
|
// run through all top level gadgets and process them (they are responsible for processing
|
|
// their children, which UI_GADGET will handle if you don't override process() or if you
|
|
// do, you call UI_GADGET::process()).
|
|
if ( !ignore_gadgets ) {
|
|
tmp = first_gadget;
|
|
do {
|
|
if ( !tmp->check_move() )
|
|
tmp->process();
|
|
|
|
tmp = tmp->next;
|
|
|
|
} while (tmp != first_gadget);
|
|
}
|
|
|
|
use_hack_to_get_around_stupid_problem_flag = 0;
|
|
return last_keypress;
|
|
}
|
|
|
|
void UI_WINDOW::check_focus_switch_keys()
|
|
{
|
|
return;
|
|
}
|
|
|
|
void UI_WINDOW::capture_mouse(UI_GADGET *gadget)
|
|
{
|
|
mouse_captured_gadget = gadget;
|
|
}
|
|
|
|
void UI_WINDOW::set_ignore_gadgets(int state)
|
|
{
|
|
ignore_gadgets = state;
|
|
}
|
|
|
|
void UI_WINDOW::add_XSTR(const char *string, int _xstr_id, int _x, int _y, UI_GADGET *_assoc, int _color_type, int _font_id)
|
|
{
|
|
int idx;
|
|
int found = -1;
|
|
UI_XSTR *ui_x;
|
|
|
|
// try and find a free xstr
|
|
for(idx=0; idx<MAX_UI_XSTRS; idx++){
|
|
if(xstrs[idx] == NULL){
|
|
found = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if we don't have a free spot
|
|
if(found < 0){
|
|
Int3(); // aieee! we need to up the max # of xstrs allowed in a window.
|
|
return;
|
|
}
|
|
|
|
// allocate a new struct
|
|
xstrs[idx] = (UI_XSTR*)vm_malloc(sizeof(UI_XSTR));
|
|
if(xstrs[idx] == NULL){
|
|
return;
|
|
}
|
|
ui_x = xstrs[idx];
|
|
|
|
// fill in the data
|
|
ui_x->xstr = vm_strdup(string);
|
|
if(ui_x->xstr == NULL){
|
|
vm_free(ui_x);
|
|
xstrs[idx] = NULL;
|
|
return;
|
|
}
|
|
ui_x->xstr_id = _xstr_id;
|
|
ui_x->x = _x;
|
|
ui_x->y = _y;
|
|
ui_x->assoc = _assoc;
|
|
ui_x->font_id = _font_id;
|
|
ui_x->clr = _color_type;
|
|
Assert((ui_x->clr >= 0) && (ui_x->clr < UI_NUM_XSTR_COLORS));
|
|
if((ui_x->clr < 0) || (ui_x->clr >= UI_NUM_XSTR_COLORS)){
|
|
ui_x->clr = 0;
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::add_XSTR(UI_XSTR *xstr)
|
|
{
|
|
int idx;
|
|
int found = -1;
|
|
UI_XSTR *ui_x;
|
|
|
|
// try and find a free xstr
|
|
for(idx=0; idx<MAX_UI_XSTRS; idx++){
|
|
if(xstrs[idx] == NULL){
|
|
found = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if we don't have a free spot
|
|
if(found < 0){
|
|
Int3(); // aieee! we need to up the max # of xstrs allowed in a window.
|
|
return;
|
|
}
|
|
|
|
// allocate a new struct
|
|
xstrs[idx] = (UI_XSTR*)vm_malloc(sizeof(UI_XSTR));
|
|
if(xstrs[idx] == NULL){
|
|
return;
|
|
}
|
|
ui_x = xstrs[idx];
|
|
|
|
// fill in the data
|
|
ui_x->xstr = vm_strdup(xstr->xstr);
|
|
if(ui_x->xstr == NULL){
|
|
vm_free(ui_x);
|
|
xstrs[idx] = NULL;
|
|
return;
|
|
}
|
|
ui_x->xstr_id = xstr->xstr_id;
|
|
ui_x->x = xstr->x;
|
|
ui_x->y = xstr->y;
|
|
ui_x->assoc = xstr->assoc;
|
|
ui_x->font_id = xstr->font_id;
|
|
ui_x->clr = xstr->clr;
|
|
Assert((ui_x->clr >= 0) && (ui_x->clr < UI_NUM_XSTR_COLORS));
|
|
if((ui_x->clr < 0) || (ui_x->clr >= UI_NUM_XSTR_COLORS)){
|
|
ui_x->clr = 0;
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::draw_one_xstr(UI_XSTR *xs, int frame)
|
|
{
|
|
int f_backup = -1;
|
|
char str[255] = "";
|
|
|
|
// sanity
|
|
if((xs == NULL) || (xs->xstr == NULL)){
|
|
return;
|
|
}
|
|
|
|
// if it has an associated gadet that is hidden, do nothing
|
|
if((xs->assoc != NULL) && (xs->assoc->hidden)){
|
|
return;
|
|
}
|
|
|
|
// maybe set the font
|
|
if(xs->font_id >= 0){
|
|
// backup the current font
|
|
f_backup = font::FontManager::getCurrentFontIndex();
|
|
Assert(f_backup >= 0);
|
|
|
|
// set the new font
|
|
font::set_font(xs->font_id);
|
|
}
|
|
|
|
// set the color
|
|
if(xs->assoc == NULL){
|
|
gr_set_color_fast(&Color_normal);
|
|
} else {
|
|
// just buttons for now
|
|
switch(xs->assoc->kind){
|
|
case UI_KIND_BUTTON:
|
|
// override case
|
|
if((frame != -1) && (frame < 3)){
|
|
gr_set_color_fast(Xstr_colors[xs->clr][frame]);
|
|
}
|
|
// normal checking
|
|
else {
|
|
// if the button is pressed
|
|
if(((UI_BUTTON*)xs->assoc)->button_down()){
|
|
gr_set_color_fast(Xstr_colors[xs->clr][2]);
|
|
}
|
|
// if the mouse is just over it
|
|
else if(xs->assoc->is_mouse_on()){
|
|
gr_set_color_fast(Xstr_colors[xs->clr][1]);
|
|
} else {
|
|
gr_set_color_fast(Xstr_colors[xs->clr][0]);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// all other controls just draw the normal frame
|
|
default :
|
|
if((frame != -1) && (frame < 3)){
|
|
gr_set_color_fast(Xstr_colors[xs->clr][frame]);
|
|
} else {
|
|
gr_set_color_fast(Xstr_colors[xs->clr][0]);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// if the gadget disabled, just draw the normal nonhighlighted frame
|
|
if(xs->assoc->disabled()){
|
|
gr_set_color_fast(Xstr_colors[xs->clr][0]);
|
|
}
|
|
}
|
|
|
|
// print this puppy out
|
|
int xoffset = lcl_get_xstr_offset(xs->xstr_id, gr_screen.res);
|
|
strncpy(str, XSTR(xs->xstr, xs->xstr_id), 254);
|
|
if(str[0] == '&'){
|
|
if(strlen(str) > 1){
|
|
gr_string((xs->x) + xoffset, xs->y, str + 1, GR_RESIZE_MENU);
|
|
}
|
|
} else {
|
|
gr_string((xs->x) + xoffset, xs->y, str, GR_RESIZE_MENU);
|
|
}
|
|
|
|
// maybe restore the old font
|
|
if(f_backup >= 0){
|
|
font::FontManager::setCurrentFontIndex(f_backup);
|
|
}
|
|
}
|
|
|
|
void UI_WINDOW::draw_xstrs()
|
|
{
|
|
int idx = 0;
|
|
|
|
// draw the xstrs
|
|
do {
|
|
draw_one_xstr(xstrs[idx], -1);
|
|
|
|
// next xstr
|
|
idx++;
|
|
} while(idx < MAX_UI_XSTRS);
|
|
}
|
|
|
|
// TEST CODE
|
|
|
|
void UI_WINDOW::do_dump_check()
|
|
{
|
|
#if 0
|
|
if ( keypress == KEY_SHIFTED+KEY_CTRLED+KEY_ALTED+KEY_F12 ) {
|
|
FILE *fp;
|
|
|
|
last_keypress = keypress = 0;
|
|
|
|
mprintf(( "\n========== WINDOW GADGETS =========\n" ));
|
|
mprintf(( "(Also dumped to ui.out)\n" ));
|
|
|
|
fp = fopen( "ui.out", "wt" );
|
|
tmp = first_gadget;
|
|
do {
|
|
if ( tmp->parent == NULL ) {
|
|
switch ( tmp->kind ) {
|
|
case UI_KIND_BUTTON:
|
|
mprintf(( "UI: Button at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Button at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_KEYTRAP:
|
|
mprintf(( "UI: Keytrap at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Keytrap at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_CHECKBOX:
|
|
mprintf(( "UI: Checkbox at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Checkbox at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_RADIO:
|
|
mprintf(( "UI: Radiobutton at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Radiobutton at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_SCROLLBAR:
|
|
mprintf(( "UI: Scrollbar at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Scrollbar at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_LISTBOX:
|
|
mprintf(( "UI: Listbox at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Listbox at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
case UI_KIND_INPUTBOX:
|
|
mprintf(( "UI: Inputbox at %d,%d\n", tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Inputbox at %d,%d\n", tmp->x, tmp->y );
|
|
break;
|
|
default:
|
|
mprintf(( "UI: Unknown type %d at %d,%d\n", tmp->kind, tmp->x, tmp->y ));
|
|
fprintf( fp, "UI: Unknown type %d at %d,%d\n", tmp->kind, tmp->x, tmp->y );
|
|
}
|
|
}
|
|
tmp = tmp->next;
|
|
} while( tmp != first_gadget );
|
|
fclose(fp);
|
|
mprintf(( "===================================\n" ));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
void parse_tooltip(int n)
|
|
{
|
|
char buf[MESSAGE_LENGTH];
|
|
|
|
stuff_int(&Tooltips[n].hotspot);
|
|
stuff_string(buf, F_MESSAGE, NULL);
|
|
Tooltips[n].text = vm_strdup(buf);
|
|
}
|
|
|
|
int parse_tooltips_group(int group, int n)
|
|
{
|
|
char buf[NAME_LENGTH];
|
|
|
|
Assert(group < MAX_TOOLTIP_GROUPS);
|
|
required_string("$Mask Filename:");
|
|
stuff_string(buf, F_NAME, NULL);
|
|
Tooltip_groups[group].mask = vm_strdup(buf);
|
|
Tooltip_groups[group].start = n;
|
|
|
|
while (1) {
|
|
if (check_for_string("#") || check_for_string("$")) {
|
|
Tooltip_groups[group].end = n;
|
|
return n;
|
|
}
|
|
|
|
Assert(n < MAX_TOOLTIPS);
|
|
parse_tooltip(n++);
|
|
}
|
|
}
|
|
|
|
void parse_ship_tooltip(int n)
|
|
{
|
|
}
|
|
|
|
void parse_weapon_tooltip(int n)
|
|
{
|
|
}
|
|
|
|
void parse_tooltips()
|
|
{
|
|
int n, rval;
|
|
|
|
// open localization
|
|
lcl_ext_open();
|
|
|
|
if ((rval = setjmp(parse_abort)) != 0) {
|
|
mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "tooltips.tbl", rval));
|
|
lcl_ext_close();
|
|
return;
|
|
}
|
|
|
|
read_file_text("tooltips.tbl");
|
|
|
|
n = Num_tooltip_groups = 0;
|
|
reset_parse();
|
|
|
|
if (optional_string("#UI"))
|
|
while (required_string_either("#", "$")) {
|
|
n = parse_tooltips_group(Num_tooltip_groups, n);
|
|
Num_tooltip_groups++;
|
|
}
|
|
|
|
if (optional_string("#Ships"))
|
|
while (required_string_either("#", "$")) {
|
|
parse_ship_tooltip(Num_ship_tooltips);
|
|
Num_ship_tooltips++;
|
|
}
|
|
|
|
if (optional_string("#Weapons"))
|
|
while (required_string_either("#", "$")) {
|
|
parse_ship_tooltip(Num_weapon_tooltips);
|
|
Num_weapon_tooltips++;
|
|
}
|
|
|
|
required_string("#End");
|
|
|
|
// close localization
|
|
lcl_ext_close();
|
|
}
|
|
|
|
void init_tooltips()
|
|
{
|
|
static int inited = 0;
|
|
|
|
if (!inited) {
|
|
parse_tooltips();
|
|
inited = 1;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void ok_clicked()
|
|
{
|
|
mprintf(( "OK Clicked!\n" ));
|
|
}
|
|
|
|
void do_help()
|
|
{
|
|
mprintf(( "Help!\n" ));
|
|
}
|