/* * The Mana World * Copyright 2004 The Mana World Development Team * * This file is part of The Mana World. * * The Mana World is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * The Mana World is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id$ */ #include "gui.h" #include #include #include #include "../log.h" #include "../sound/sound.h" #include "allegroinput.h" #ifndef WIN32 #define __cdecl __attribute__((cdecl)) #endif #define GUI_BMP_COUNT 11 #define GUI_BMP_OFS_BUTTON 0 #define GUI_BMP_OFS_SLIDER 4 #define GUI_BMP_OFS_CHECKBOX 5 #define GUI_BMP_OFS_RADIOBUTTON 6 #define GUI_BMP_OFS_TEXTBOX 7 #define GUI_BMP_OFS_LISTBOX 8 #define GUI_BMP_OFS_DIALOG 9 #define GUI_CALL_BUTTONCALLBACK(d) static BITMAP *gui__repository[GUI_BMP_COUNT]; /* The currently active skin */ LexSkin gui_skin; BITMAP *gui_bitmap; DATAFILE *gui_gfx; // Guichan Allegro stuff gcn::AllegroGraphics* guiGraphics; // Graphics driver // Guichan stuff Gui* gui; gcn::Container* guiTop; // The top container Gui::Gui(BITMAP *screen) { gui = new gcn::Gui(); // Set graphics guiGraphics = new gcn::AllegroGraphics(); guiGraphics->setTarget(screen); gui->setGraphics(guiGraphics); // Set input guiInput = new AllegroInput(); gui->setInput(guiInput); // Set image loader imageLoader = new gcn::AllegroImageLoader(); gcn::Image::setImageLoader(imageLoader); // Initialize top GUI widget guiTop = new gcn::Container(); guiTop->setDimension(gcn::Rectangle(0, 0, SCREEN_W, SCREEN_H)); guiTop->setOpaque(false); gui->setTop(guiTop); // Set global font guiFont = new gcn::ImageFont("./data/graphic/fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:@" "!\"$%&/=?^+*#[]{}()<>_;'.,\\|-~`" ); gcn::Widget::setGlobalFont(guiFont); } Gui::~Gui() { delete guiFont; delete guiTop; delete imageLoader; delete guiInput; delete guiGraphics; delete gui; } void Gui::update() { gui->logic(); gui->draw(); // Draw the mouse draw_sprite(gui_bitmap, mouse_sprite, mouse_x, mouse_y); } void init_gui(BITMAP *bitmap, const char *skin) { gui = new Gui(bitmap); gui_bitmap = bitmap; gui_load_skin(skin); show_mouse(NULL); } void loadButtonSkin() { char **tokens; int tokenCount; int gridx[4]; int gridy[4]; int a = 0; int x, y, mode; tokens = get_config_argv("button", "gridx", &tokenCount); for (a = 0; a < 4; a++) { gridx[a] = atoi(tokens[a]); } tokens = get_config_argv("button", "gridy", &tokenCount); for (a = 0; a < 4; a++) { gridy[a] = atoi(tokens[a]); } tokens = get_config_argv("button", "textcol_norm", &tokenCount); gui_skin.button.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("button", "textcol_hilite", &tokenCount); gui_skin.button.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("button", "textcol_pressed", &tokenCount); gui_skin.button.textcolor[2] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("button", "textcol_disabled", &tokenCount); gui_skin.button.textcolor[3] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); gui__repository[GUI_BMP_OFS_BUTTON + 0] = (BITMAP *)gui_gfx[0].dat; gui__repository[GUI_BMP_OFS_BUTTON + 1] = (BITMAP *)gui_gfx[2].dat; gui__repository[GUI_BMP_OFS_BUTTON + 2] = (BITMAP *)gui_gfx[3].dat; gui__repository[GUI_BMP_OFS_BUTTON + 3] = (BITMAP *)gui_gfx[1].dat; for (mode = 0; mode < 4; mode++) { a = 0; for (y = 0; y < 3; y++) { for (x = 0; x < 3; x++) { gui_skin.button.background[mode].grid[a] = create_sub_bitmap( gui__repository[GUI_BMP_OFS_BUTTON + mode], gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y]+1 ); a++; } } } } void loadSliderSkin() { int x, y, w, h,o1,o2; char **tokens; int tokenCount; gui__repository[GUI_BMP_OFS_SLIDER] = (BITMAP *)gui_gfx[8].dat; if (!gui__repository[GUI_BMP_OFS_SLIDER])alert("","","","","",0,0); tokens = get_config_argv("slider", "slider_h", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); tokens = get_config_argv("slider", "slider_h_ofs", &tokenCount); o1 = atoi(tokens[0]); o2 = atoi(tokens[1]); gui_skin.slider.hSlider[0] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x , y, o1-x, h); gui_skin.slider.hSlider[1] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], o1, y, o2-o1, h); gui_skin.slider.hSlider[2] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], o2, y, w-(o2-x), h); tokens = get_config_argv("slider", "slider_v", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); tokens = get_config_argv("slider", "slider_v_ofs", &tokenCount); o1 = atoi(tokens[0]); o2 = atoi(tokens[1]); gui_skin.slider.vSlider[0] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, o1 - y); gui_skin.slider.vSlider[1] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, o1, w, o2 - o1); gui_skin.slider.vSlider[2] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, o2, w, h - (o2-y)); tokens = get_config_argv("slider", "handle_v", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.slider.vGrip = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, h); tokens = get_config_argv("slider", "handle_h", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.slider.hGrip = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, h); } void loadCheckboxSkin() { int x, y, w,h; char **tokens; int tokenCount; gui__repository[GUI_BMP_OFS_CHECKBOX] = (BITMAP *)gui_gfx[4].dat; tokens = get_config_argv("checkbox", "normal", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.checkbox.normal = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); tokens = get_config_argv("checkbox", "checked", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.checkbox.checked = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); tokens = get_config_argv("checkbox", "disabled", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.checkbox.disabled = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); tokens = get_config_argv("checkbox", "disabled_check", &tokenCount); x = atoi(tokens[0]); y = atoi(tokens[1]); w = atoi(tokens[2]); h = atoi(tokens[3]); gui_skin.checkbox.disabled_checked = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); tokens = get_config_argv("button", "textcol_norm", &tokenCount); gui_skin.checkbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("button", "textcol_disabled", &tokenCount); gui_skin.checkbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); } void loadTextboxSkin() { char **tokens; int tokenCount; int gridx[4]; int gridy[4]; int a = 0; int x, y; tokens = get_config_argv("textbox", "gridx", &tokenCount); for (a = 0; a < 4; a++) { gridx[a] = atoi(tokens[a]); } tokens = get_config_argv("textbox", "gridy", &tokenCount); for (a = 0; a < 4; a++) { gridy[a] = atoi(tokens[a]); } tokens = get_config_argv("textbox", "textcol_norm", &tokenCount); gui_skin.textbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("textbox", "textcol_disabled", &tokenCount); gui_skin.textbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); gui__repository[GUI_BMP_OFS_TEXTBOX] = (BITMAP *)gui_gfx[9].dat; a = 0; for (y = 0; y < 3; y++) { for (x = 0; x < 3; x++) { gui_skin.textbox.bg.grid[a] = create_sub_bitmap( gui__repository[GUI_BMP_OFS_TEXTBOX], gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y] + 1 ); a++; } } } void loadListboxSkin() { char **tokens; int tokenCount; int gridx[4]; int gridy[4]; int a = 0; int x, y; tokens = get_config_argv("listbox", "gridx", &tokenCount); for (a = 0; a < 4; a++) { gridx[a] = atoi(tokens[a]); } tokens = get_config_argv("listbox", "gridy", &tokenCount); for (a = 0; a < 4; a++) { gridy[a] = atoi(tokens[a]); } tokens = get_config_argv("listbox", "textcol_norm", &tokenCount); gui_skin.listbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("listbox", "textcol_selected", &tokenCount); gui_skin.listbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("listbox", "textbg_selected", &tokenCount); gui_skin.listbox.textcolor[2] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); tokens = get_config_argv("listbox", "textcol_disabled", &tokenCount); gui_skin.listbox.textcolor[3] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); gui__repository[GUI_BMP_OFS_LISTBOX + 0] = (BITMAP*)gui_gfx[6].dat; gui__repository[GUI_BMP_OFS_LISTBOX + 1] = (BITMAP*)gui_gfx[10].dat; a = 0; for (y = 0; y < 3; y++) { for (x = 0; x < 3; x++) { gui_skin.listbox.bg.grid[a] = create_sub_bitmap( gui__repository[GUI_BMP_OFS_LISTBOX], gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y] + 1 ); a++; } } tokens = get_config_argv("listbox", "vscroll_gridx", &tokenCount); for (a = 0; a < 4; a++) { gridx[a] = atoi(tokens[a]); } tokens = get_config_argv("listbox", "vscroll_gridy", &tokenCount); for (a = 0; a < 4; a++) { gridy[a] = atoi(tokens[a]); } a = 0; for (y = 0; y < 3; y++) { for (x = 0; x < 3; x++) { gui_skin.listbox.vscroll.grid[a] = create_sub_bitmap( gui__repository[GUI_BMP_OFS_LISTBOX+1], gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y] + 1 ); a++; } } } void loadBarSkin() { BITMAP *temp1 = load_bitmap("data/bar.bmp", NULL); BITMAP *temp2 = load_bitmap("data/bar_filled.bmp", NULL); gui_skin.bar.bg.grid[0] = create_bitmap(3,11); gui_skin.bar.bg.grid[1] = create_bitmap(1,11); gui_skin.bar.bg.grid[2] = create_bitmap(3,11); blit(temp1, gui_skin.bar.bg.grid[0], 0, 0, 0, 0, 3, 11); blit(temp1, gui_skin.bar.bg.grid[1], 4, 0, 0, 0, 1, 11); blit(temp1, gui_skin.bar.bg.grid[2], 13, 0, 0, 0, 3, 11); gui_skin.bar.bg.grid[3] = create_bitmap(3,11); gui_skin.bar.bg.grid[4] = create_bitmap(1,11); gui_skin.bar.bg.grid[5] = create_bitmap(3,11); blit(temp2, gui_skin.bar.bg.grid[3], 0, 0, 0, 0, 3, 11); blit(temp2, gui_skin.bar.bg.grid[4], 4, 0, 0, 0, 1, 11); blit(temp2, gui_skin.bar.bg.grid[5], 13, 0, 0, 0, 3, 11); } void loadRadioSkin() { gui_skin.radiobutton.normal = load_bitmap("data/Skin/radioout.bmp", NULL); gui_skin.radiobutton.checked = load_bitmap("data/Skin/radioin.bmp", NULL); gui_skin.radiobutton.disabled = load_bitmap("data/Skin/radioout.bmp", NULL); gui_skin.radiobutton.disabled_checked = load_bitmap("data/Skin/radioin.bmp", NULL); } void loadPlusSkin() { //BITMAP *temp1 = load_bitmap("data/bar.bmp", NULL); //BITMAP *temp2 = load_bitmap("data/bar_filled.bmp", NULL); gui_skin.plus.bg.grid[0] = load_bitmap("data/plus.bmp", NULL); gui_skin.plus.bg.grid[1] = load_bitmap("data/plus_sel.bmp", NULL); gui_skin.plus.bg.grid[2] = load_bitmap("data/plus_dis.bmp", NULL); //blit(temp1, gui_skin.bar.bg.grid[0], 0, 0, 0, 0, 3, 11); //blit(temp1, gui_skin.bar.bg.grid[1], 4, 0, 0, 0, 1, 11); //blit(temp1, gui_skin.bar.bg.grid[2], 13, 0, 0, 0, 3, 11); } void loadDialogSkin() { char **tokens; int tokenCount; int gridx[4]; int gridy[4]; int a = 0; int x, y; tokens = get_config_argv("dialog", "gridx", &tokenCount); for (a = 0; a < 4; a++) { gridx[a] = atoi(tokens[a]); } tokens = get_config_argv("dialog", "gridy", &tokenCount); for (a = 0; a < 4; a++) { gridy[a] = atoi(tokens[a]); } gui__repository[GUI_BMP_OFS_DIALOG] = (BITMAP *)gui_gfx[5].dat; a = 0; for (y = 0; y < 3; y++) { for (x = 0; x < 3; x++) { gui_skin.dialog.bg.grid[a] = create_sub_bitmap( gui__repository[GUI_BMP_OFS_DIALOG], gridx[x] , gridy[y], gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 ); a++; } } } void draw_skinned_rect(BITMAP*dst, LexSkinnedRect *skin, int x, int y, int w, int h) { BITMAP **grid = skin->grid; int w0 = grid[0]->w; int w1 = w - grid[0]->w -grid[2]->w; int w2 = grid[2]->w; int h0 = grid[0]->h; int h1 = h - grid[0]->h - grid[6]->h; int h2 = grid[6]->h; int cx,cy; cx = x; cy = y; masked_blit(grid[0], dst, 0, 0, cx, cy,grid[0]->w,grid[0]->h); cy += h0; masked_stretch_blit(grid[3], dst, 0, 0, grid[3]->w,grid[3]->h,cx, cy,w0,h1); cy += h1; masked_blit(grid[6], dst, 0, 0, cx, cy,grid[6]->w,grid[6]->h); cx += w0; cy = y; masked_stretch_blit(grid[1], dst, 0, 0, grid[1]->w,grid[1]->h,cx, cy,w1,h0); cy += h0; masked_stretch_blit(grid[4], dst, 0, 0, grid[4]->w,grid[4]->h,cx, cy,w1,h1); cy += h1; masked_stretch_blit(grid[7], dst, 0, 0, grid[7]->w,grid[7]->h,cx, cy,w1,h2); cx += w1; cy = y; masked_blit(grid[2], dst, 0, 0, cx, cy,grid[2]->w,grid[2]->h); cy += h0; masked_stretch_blit(grid[5], dst, 0, 0, grid[5]->w,grid[5]->h,cx, cy,w2,h1); cy += h1; masked_blit(grid[8], dst, 0, 0, cx, cy,grid[8]->w,grid[7]->h); } int gui_load_skin(const char* skinname) { push_config_state(); set_config_file(skinname); gui_gfx = load_datafile(get_config_string("skin", "gfx", 0)); loadButtonSkin(); loadSliderSkin(); loadCheckboxSkin(); loadRadioSkin(); loadTextboxSkin(); loadListboxSkin(); loadDialogSkin(); loadBarSkin(); loadPlusSkin(); pop_config_state(); set_mouse_sprite((BITMAP *)gui_gfx[7].dat); return TRUE; } void gui_exit() { delete gui; gui_shutdown(); } void gui_shutdown(void) { int a, b; /* Button */ for (a = 0; a < 3; a++) { for (b = 0; b < 9 ; b++) { destroy_bitmap(gui_skin.button.background[a].grid[b]); } } /* Slider */ for (a = 0; a < 3; a++) { destroy_bitmap(gui_skin.slider.hSlider[a]); destroy_bitmap(gui_skin.slider.vSlider[a]); } destroy_bitmap(gui_skin.slider.hGrip); destroy_bitmap(gui_skin.slider.vGrip); /* Checkbox */ destroy_bitmap(gui_skin.checkbox.normal); destroy_bitmap(gui_skin.checkbox.checked); destroy_bitmap(gui_skin.checkbox.disabled); destroy_bitmap(gui_skin.checkbox.disabled_checked); /* Radiobutton */ destroy_bitmap(gui_skin.radiobutton.normal); destroy_bitmap(gui_skin.radiobutton.checked); destroy_bitmap(gui_skin.radiobutton.disabled); destroy_bitmap(gui_skin.radiobutton.disabled_checked); for (a = 0; a < GUI_BMP_COUNT; a++) { destroy_bitmap(gui__repository[a]); } } int gui_text(BITMAP *bmp, AL_CONST char *s, int x, int y, int color, int centre) { char tmp[1024]; int hline_pos = -1; int len = 0; int in_pos = 0; int out_pos = 0; int pix_len, c; while (((c = ugetc(s+in_pos)) != 0) && (out_pos<(int)(sizeof(tmp)-ucwidth(0)))) { if (c == '&') { in_pos += uwidth(s+in_pos); c = ugetc(s+in_pos); if (c == '&') { out_pos += usetc(tmp+out_pos, '&'); in_pos += uwidth(s+in_pos); len++; } else hline_pos = len; } else { out_pos += usetc(tmp+out_pos, c); in_pos += uwidth(s+in_pos); len++; } } usetc(tmp+out_pos, 0); pix_len = text_length(font, tmp); if (centre)x -= pix_len / 2; if (bmp) { textprintf_ex(bmp, font, x, y, color, -1, tmp); if (hline_pos >= 0) { c = ugetat(tmp, hline_pos); usetat(tmp, hline_pos, 0); hline_pos = text_length(font, tmp); c = usetc(tmp, c); usetc(tmp+c, 0); c = text_length(font, tmp); hline(bmp, x+hline_pos, y+text_height(font)-gui_font_baseline, x+hline_pos+c-1, color); } } return pix_len; } int tmw_text_proc(int msg, DIALOG *d, int c) { if (msg == MSG_DRAW) { gui_text(gui_bitmap, (char *)d->dp, d->x, d->y, d->fg, FALSE); } return D_O_K; } int tmw_button_proc(int msg, DIALOG *d, int c) { int col = 0; int ofs = 0; int ret = D_O_K; if (msg == MSG_DRAW) { rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, makecol(255,255,255)); if (d->flags & D_DISABLED) { draw_skinned_rect(gui_bitmap, &gui_skin.button.background[3], d->x, d->y, d->w, d->h); col = gui_skin.button.textcolor[3]; } else if (d->flags & D_SELECTED) { draw_skinned_rect(gui_bitmap, &gui_skin.button.background[2], d->x, d->y, d->w, d->h); col = gui_skin.button.textcolor[2]; ofs = 1; } else if (d->flags & D_GOTMOUSE) { draw_skinned_rect(gui_bitmap, &gui_skin.button.background[1], d->x, d->y, d->w, d->h); col = gui_skin.button.textcolor[1]; } else { draw_skinned_rect(gui_bitmap, &gui_skin.button.background[0], d->x, d->y, d->w, d->h); col = gui_skin.button.textcolor[0]; } gui_text(gui_bitmap, (const char *)d->dp, d->x+d->w/2+ofs, d->y+d->h/2-text_height(font)/2+ofs, col, TRUE); ret = D_O_K; } else { /* if (msg == MSG_CLICK) { if (d->d1 == 1) ((int)d->dp2) + 1; else if (d->d1 == 2) ((int)d->dp2) - 1; } */ ret = d_button_proc(msg,d,c); } return ret; } int tmw_dialog_proc(int msg, DIALOG *d, int c) { int x, y; switch (msg) { case MSG_CLICK: if (mouse_yy + gui_skin.dialog.bg.grid[1]->h) { d->d1 = mouse_x - d->x; d->d2 = mouse_y - d->y; } break; case MSG_DRAW: if((mouse_b & 1) && (d->d1 >= 0) && (d->d2 >= 0)) { x = mouse_x - d->d1; y = mouse_y - d->d2; if (x < 15) { x = 0; position_mouse(d->d1, mouse_y); } if (y < 15) { y = 0; position_mouse(mouse_x, d->d2); } if (x + d->w >= SCREEN_W - 15) { x = SCREEN_W - d->w; position_mouse(x+d->d1, mouse_y); } if (y + d->h >= SCREEN_H - 15) { y = SCREEN_H - d->h; position_mouse(mouse_x, y + d->d2); } position_dialog(d, x, y); } else { d->d1 = -1; d->d2 = -1; } draw_skinned_rect(gui_bitmap, &gui_skin.dialog.bg, d->x, d->y, d->w, d->h); textprintf_centre_ex(gui_bitmap, font, d->x + d->w / 2, d->y + (gui_skin.dialog.bg.grid[1]->h - text_height(font)) / 2, d->fg, -1, "%s", (char*)d->dp); break; } return D_O_K; } void ok(const char *title, const char *message) { DIALOG alert_dialog[] = { /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ { tmw_dialog_proc, 0, 0, 0, 60, 0, -1, 0, 0, 0, 0, (void *)title, NULL, NULL }, { tmw_text_proc, 2, 22, 0, 0, 0, 0, 0, 0, 0, 0, (void *)message, NULL, NULL }, { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&Ok", NULL, NULL }, { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } }; BITMAP *temp = gui_bitmap; gui_bitmap = screen; show_mouse(screen); alert_dialog[0].w = text_length(font, message) + 4; alert_dialog[1].w = text_length(font, message); alert_dialog[1].h = text_height(font); alert_dialog[2].x = text_length(font, message) / 2 - 22; position_dialog(alert_dialog, 400 - alert_dialog[0].w / 2, 270); do_dialog(alert_dialog, 2); show_mouse(NULL); gui_bitmap = temp; } unsigned int yes_no(const char *title, const char *message) { unsigned int ret; DIALOG alert_dialog[] = { /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ { tmw_dialog_proc, 0, 0, 0, 60, 0, -1, 0, 0, 0, 0, (void *)title, NULL, NULL }, { tmw_text_proc, 2, 22, 0, 0, 0, 0, 0, 0, 0, 0, (void *)message, NULL, NULL }, { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&Yes", NULL, NULL }, { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&No", NULL, NULL }, { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } }; BITMAP *temp = gui_bitmap; gui_bitmap = screen; show_mouse(screen); int width = text_length(font, message) + 4; if (width < 100) width = 100; alert_dialog[0].w = width; alert_dialog[1].w = text_length(font, message); alert_dialog[1].h = text_height(font); alert_dialog[2].x = width / 2 - 46; alert_dialog[2].x = width / 2 + 2; position_dialog(alert_dialog, 400 - width / 2, 270); ret = do_dialog(alert_dialog, 3); show_mouse(NULL); gui_bitmap = temp; return ret - 2; }