summaryrefslogtreecommitdiff
path: root/src/gui/gui.cpp
diff options
context:
space:
mode:
authorEugenio Favalli <elvenprogrammer@gmail.com>2004-09-26 13:08:46 +0000
committerEugenio Favalli <elvenprogrammer@gmail.com>2004-09-26 13:08:46 +0000
commit92bbeab96bf61edf9b7caa125ed67e634258383e (patch)
treea95dd426590c8e6208445290fa8b9b47c1a57bcb /src/gui/gui.cpp
parente46b2cdbf205d3d2e17266e3168fdbecd5f53222 (diff)
downloadmana-client-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.gz
mana-client-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.bz2
mana-client-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.xz
mana-client-92bbeab96bf61edf9b7caa125ed67e634258383e.zip
*** empty log message ***
Diffstat (limited to 'src/gui/gui.cpp')
-rw-r--r--src/gui/gui.cpp1471
1 files changed, 1471 insertions, 0 deletions
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
new file mode 100644
index 00000000..cb43c47b
--- /dev/null
+++ b/src/gui/gui.cpp
@@ -0,0 +1,1471 @@
+/**
+
+ 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
+
+*/
+
+#include "gui.h"
+#include "allegro/internal/aintern.h"
+#include <math.h>
+#include <alfont.h>
+#include "../Sound/sound.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;
+ALFONT_FONT *gui_font;
+bool drag;
+DATAFILE *gui_gfx;
+
+extern TmwSound sound;
+
+/* very internal update stuff */
+int (*gui__external_slider_callback)(void *, int);
+int reroute_slider_proc(void *dp3, int d2);
+
+/** Initialize gui system */
+void init_gui(BITMAP *bitmap, const char *skin) {
+ gui_bitmap = bitmap;
+ gui_load_skin(skin);
+ //alfont_init();
+ gui_font = alfont_load_font("./data/skin/arial.ttf");
+ alfont_set_font_size(gui_font, 14);
+ drag = false;
+ show_mouse(NULL);
+}
+
+int gui_update(DIALOG_PLAYER *player) {
+ dialog_message(player->dialog, MSG_DRAW, 0, 0);
+ int ret = update_dialog(player);
+ draw_sprite(gui_bitmap, mouse_sprite, mouse_x, mouse_y);
+ return ret;
+}
+
+
+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;
+
+ 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 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 drawSkinnedRect(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) {
+ gui__external_slider_callback = NULL;
+ push_config_state();
+ set_config_file(skinname);
+ gui_gfx = load_datafile(get_config_string("skin", "gfx", 0));
+ loadButtonSkin();
+ loadSliderSkin();
+ loadCheckboxSkin();
+ loadTextboxSkin();
+ loadListboxSkin();
+ loadDialogSkin();
+ pop_config_state();
+ set_mouse_sprite((BITMAP *)gui_gfx[7].dat);
+
+ return TRUE;
+}
+
+void gui_exit() {
+ //alfont_destroy_font(gui_font);
+ gui_shutdown();
+ //alfont_exit();
+}
+
+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]);
+ }
+}
+
+/** Draw text for gui widgets */
+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 = alfont_text_length(gui_font, tmp);
+
+ if (centre)x -= pix_len / 2;
+ if (bmp) {
+ alfont_textout_aa(bmp, gui_font, tmp, x, y, color);
+ if (hline_pos >= 0) {
+ c = ugetat(tmp, hline_pos);
+ usetat(tmp, hline_pos, 0);
+ hline_pos = alfont_text_length(gui_font, tmp);
+ c = usetc(tmp, c);
+ usetc(tmp+c, 0);
+ c = alfont_text_length(gui_font, tmp);
+ hline(bmp, x+hline_pos, y+alfont_text_height(gui_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) {
+ int rtm;
+ rtm = alfont_text_mode(-1);
+ gui_text(gui_bitmap, (char *)d->dp, d->x, d->y, d->fg, FALSE);
+ alfont_text_mode(rtm);
+ }
+ return D_O_K;
+}
+
+
+int tmw_button_proc(int msg, DIALOG *d, int c) {
+
+ int rtm = 0;
+ 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) {
+ drawSkinnedRect(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) {
+ drawSkinnedRect(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) {
+ drawSkinnedRect(gui_bitmap, &gui_skin.button.background[1], d->x, d->y, d->w, d->h);
+ col = gui_skin.button.textcolor[1];
+ } else {
+ drawSkinnedRect(gui_bitmap, &gui_skin.button.background[0], d->x, d->y, d->w, d->h);
+ col = gui_skin.button.textcolor[0];
+ }
+ rtm = alfont_text_mode(-1);
+ gui_text(gui_bitmap, (const char *)d->dp, d->x+d->w/2+ofs, d->y+d->h/2-alfont_text_height(gui_font)/2+ofs, col, TRUE);
+ alfont_text_mode(rtm);
+ ret = D_O_K;
+ } else {
+ ret = d_button_proc(msg,d,c);
+ }
+ return ret;
+}
+
+int tmw_slider_proc(int msg, DIALOG *d, int c) {
+ int w = 0;
+ int h = 0;
+ int x,y;
+
+ int ret = D_O_K;
+
+ static int watchdog = 0;
+
+ watchdog++;
+ if (watchdog == 1) {
+ gui__external_slider_callback = (int(__cdecl *)(void *, int))d->dp2;
+ d->dp2 = (void*)reroute_slider_proc;
+ }
+
+ if (msg == MSG_DRAW) {
+ if (d->w >= d->h) {
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ /* horiz */
+ x = d->x;
+ y = d->y + (d->h- gui_skin.slider.hSlider[0]->h)/2;
+ masked_blit(gui_skin.slider.hSlider[0], gui_bitmap, 0, 0, x, y, gui_skin.slider.hSlider[0]->w, gui_skin.slider.hSlider[0]->h);
+ w = d->w -gui_skin.slider.hSlider[0]->w - gui_skin.slider.hSlider[2]->w;
+ x+= gui_skin.slider.hSlider[0]->w;
+
+ masked_stretch_blit(
+ gui_skin.slider.hSlider[1], gui_bitmap,
+ 0, 0, gui_skin.slider.hSlider[1]->w, gui_skin.slider.hSlider[1]->h,
+ x, y, w, gui_skin.slider.hSlider[1]->h);
+
+ x+=w;
+ masked_blit(gui_skin.slider.hSlider[2], gui_bitmap, 0, 0, x, y, gui_skin.slider.hSlider[2]->w, gui_skin.slider.hSlider[2]->h);
+
+ x = d->x + ((d->w-gui_skin.slider.hGrip->w) * d->d2)/d->d1;
+ y = d->y + (d->h - gui_skin.slider.hGrip->h)/2;
+ masked_blit(gui_skin.slider.hGrip, gui_bitmap, 0, 0, x, y, gui_skin.slider.hGrip->w, gui_skin.slider.hGrip->h);
+ } else {
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ /* vertic */
+ x = d->x+ (d->w- gui_skin.slider.vSlider[0]->w)/2;
+ y = d->y;
+ masked_blit(gui_skin.slider.vSlider[0], gui_bitmap, 0, 0, x, y, gui_skin.slider.vSlider[0]->w, gui_skin.slider.vSlider[0]->h);
+ h = d->h - gui_skin.slider.vSlider[0]->h - gui_skin.slider.vSlider[2]->h;
+ y += gui_skin.slider.vSlider[0]->h;
+
+ masked_stretch_blit(
+ gui_skin.slider.vSlider[1], gui_bitmap,
+ 0, 0, gui_skin.slider.vSlider[1]->w, gui_skin.slider.vSlider[1]->h,
+ x, y, gui_skin.slider.vSlider[1]->w, h);
+
+ y+=h;
+ masked_blit(gui_skin.slider.vSlider[2], gui_bitmap, 0, 0, x, y, gui_skin.slider.vSlider[2]->w, gui_skin.slider.vSlider[2]->h);
+
+ y = d->y + d->h - (((d->h-gui_skin.slider.vGrip->h) * d->d2)/d->d1)-gui_skin.slider.vGrip->h;
+ x = d->x + (d->w - gui_skin.slider.vGrip->w)/2;
+ if (gui_skin.slider.vGrip->w % 2 !=0) {
+ x++;
+ }
+ masked_blit(gui_skin.slider.vGrip, gui_bitmap, 0, 0, x, y, gui_skin.slider.vGrip->w, gui_skin.slider.vGrip->h);
+ }
+ //textprintf(gui_bitmap, gui_font,10, 10, makecol(255,255,255), "%i", d->d2);
+ } else {
+ ret = d_slider_proc(msg,d,c);
+ }
+ if (watchdog == 1) {
+ d->dp2 = (void*)gui__external_slider_callback;
+ }
+ watchdog--;
+ return ret;
+}
+
+int tmw_check_proc(int msg, DIALOG *d, int c) {
+ BITMAP *box = NULL;
+ int x, y;
+ int tx, ty, l;
+ int rtm = 0;
+ int col = 0;
+ if (msg == MSG_DRAW) {
+// rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ if (d->flags & D_SELECTED) {
+ if (d->flags & D_DISABLED) {
+ box = gui_skin.checkbox.disabled_checked;
+ } else {
+ box = gui_skin.checkbox.checked;
+ }
+ } else if (d->flags & D_DISABLED) {
+ box = gui_skin.checkbox.disabled;
+ } else {
+ box = gui_skin.checkbox.normal;
+ }
+
+ if (d->flags & D_DISABLED) {
+ col = gui_skin.checkbox.textcolor[1];
+ } else {
+ col = gui_skin.checkbox.textcolor[0];
+ }
+
+ if (d->dp != NULL) {
+ l = gui_strlen((const char *)d->dp);
+ } else {
+ l = 0;
+ }
+
+ if (d->d1 != 0) {
+ x = d->x;
+ tx = x + box->w + box->w/2;
+ } else {
+ x = d->x + d->w - box->w;
+ tx = x - box->w/2 - l;
+ }
+ y = d->y + (d->h - box->h)/ 2;
+ ty = d->y + (d->h - alfont_text_height(gui_font)) / 2;
+
+ masked_blit(box, gui_bitmap, 0, 0, x, y, box->w, box->h);
+ if (d->dp != NULL) {
+ rtm = alfont_text_mode(-1);
+ gui_text(gui_bitmap, (const char *)d->dp, tx, ty, col, 0);
+ alfont_text_mode(rtm);
+ }
+
+
+ } else {
+ return d_check_proc(msg, d, c);
+ }
+ return D_O_K;
+}
+
+int tmw_radio_proc(int msg, DIALOG *d, int c) {
+ BITMAP *box = NULL;
+ int x, y;
+ int tx, ty, l;
+ int rtm = 0;
+ int col = 0;
+
+
+ if (msg == MSG_DRAW) {
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ if (d->flags & D_SELECTED) {
+ if (d->flags & D_DISABLED) {
+ box = gui_skin.radiobutton.disabled_checked;
+ } else {
+ box = gui_skin.radiobutton.checked;
+ }
+ } else if (d->flags & D_DISABLED) {
+ box = gui_skin.radiobutton.disabled;
+ } else {
+ box = gui_skin.radiobutton.normal;
+ }
+
+ if (d->flags & D_DISABLED) {
+ col = gui_skin.radiobutton.textcolor[1];
+ } else {
+ col = gui_skin.radiobutton.textcolor[0];
+ }
+
+ if (d->dp != NULL) {
+ l = gui_strlen((const char *)d->dp);
+ } else {
+ l = 0;
+ }
+
+ if (d->d2 != 0) {
+ x = d->x;
+ tx = x + box->w + box->w/2;
+ } else {
+ x = d->x + d->w - box->w;
+ tx = x - box->w/2 - l;
+ }
+ y = d->y + (d->h - box->h)/ 2;
+ ty = d->y + (d->h - alfont_text_height(gui_font)) / 2;
+
+ masked_blit(box, gui_bitmap, 0, 0, x, y, box->w, box->h);
+ if (d->dp != NULL) {
+ rtm = alfont_text_mode(-1);
+ gui_text(gui_bitmap, (const char *)d->dp, tx, ty, col, 0);
+ alfont_text_mode(rtm);
+ }
+
+
+ } else {
+ return d_radio_proc(msg, d, c);
+ }
+ return D_O_K;
+}
+
+int tmw_edit_proc(int msg, DIALOG *d, int c) {
+// BITMAP *box = NULL;
+ int x;
+ int tx, ty, l;
+ int rtm = 0;
+ int col = 0;
+ char* start;
+ char* text;
+ char hack;
+ int cl, cr, cb, ct;
+ int lb, rb;
+
+
+ if (msg == MSG_DRAW) {
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h);
+
+ if (d->flags & D_DISABLED) {
+ col = gui_skin.textbox.textcolor[1];
+ } else {
+ col = gui_skin.textbox.textcolor[0];
+ }
+
+ lb = gui_skin.textbox.bg.grid[0]->w;
+ rb = gui_skin.textbox.bg.grid[2]->w;
+ tx = d->x + lb;
+ ty = d->y + (d->h - alfont_text_height(gui_font))/2;
+
+
+ text = (char *)d->dp;
+ start = text;
+
+ rtm = alfont_text_mode(-1);
+
+ if (gui_bitmap->clip) {
+ cl = gui_bitmap->cl;
+ ct = gui_bitmap->ct;
+ cr = gui_bitmap->cr;
+ cb = gui_bitmap->cb;
+ } else {
+ cl=ct=0;
+ cr=gui_bitmap->w;
+ cb=gui_bitmap->h;
+ }
+ set_clip_rect(gui_bitmap, tx, ty, d->x+d->w-rb, ty + alfont_text_height(gui_font)); // set_clip() is deprecated use set_clip_rect() instead
+ hack = text[d->d2];
+ text[d->d2] = '\0';
+ l = alfont_text_length(gui_font, text);
+ text[d->d2] = hack;
+
+ if (l > d->w-lb-rb) {
+ tx += ((d->w-lb-rb) - l);
+ }
+ gui_text(gui_bitmap, start, tx, ty, col, 0);
+
+
+ if (d->flags & D_GOTFOCUS) {
+ hack = text[d->d2];
+ text[d->d2] = '\0';
+ x = tx + alfont_text_length(gui_font, text);
+ vline(gui_bitmap, x, ty, ty + alfont_text_height(gui_font), col);
+ text[d->d2] = hack;
+ }
+ alfont_text_mode(rtm);
+ set_clip_rect(gui_bitmap, cl, ct, cr, cb);
+ } else {
+ return d_edit_proc(msg, d, c);
+ }
+ return D_O_K;
+}
+
+int tmw_password_proc(int msg, DIALOG *d, int c) {
+// BITMAP *box = NULL;
+ int x;
+ int tx, ty, l;
+ int rtm = 0;
+ int col = 0;
+ char* start;
+ char* text;
+ char hack;
+ int cl, cr, cb, ct;
+ int lb, rb;
+
+
+ if (msg == MSG_DRAW) {
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h);
+
+ if (d->flags & D_DISABLED) {
+ col = gui_skin.textbox.textcolor[1];
+ } else {
+ col = gui_skin.textbox.textcolor[0];
+ }
+
+ lb = gui_skin.textbox.bg.grid[0]->w;
+ rb = gui_skin.textbox.bg.grid[2]->w;
+ tx = d->x + lb;
+ ty = d->y + (d->h - alfont_text_height(gui_font))/2;
+
+
+ text = (char *)malloc(strlen((char *)d->dp)+1);
+ // Sull: new ansi standard
+ unsigned int i;
+ for(i=0;i<strlen((char *)d->dp);i++)text[i] = '*';
+ text[i] = '\0';
+ start = text;
+
+ rtm = alfont_text_mode(-1);
+
+ if (gui_bitmap->clip) {
+ cl = gui_bitmap->cl;
+ ct = gui_bitmap->ct;
+ cr = gui_bitmap->cr;
+ cb = gui_bitmap->cb;
+ } else {
+ cl=ct=0;
+ cr=gui_bitmap->w;
+ cb=gui_bitmap->h;
+ }
+ set_clip_rect(gui_bitmap, tx, ty, d->x+d->w-rb, ty + alfont_text_height(gui_font));
+
+ hack = text[d->d2];
+ text[d->d2] = '\0';
+ l = alfont_text_length(gui_font, text);
+ text[d->d2] = hack;
+
+ if (l > d->w-lb-rb) {
+ tx += ((d->w-lb-rb) - l);
+ }
+ gui_text(gui_bitmap, start, tx, ty, col, 0);
+
+
+ if (d->flags & D_GOTFOCUS) {
+ hack = text[d->d2];
+ text[d->d2] = '\0';
+ x = tx + alfont_text_length(gui_font, text);
+ vline(gui_bitmap, x, ty, ty + alfont_text_height(gui_font), col);
+ text[d->d2] = hack;
+ }
+ alfont_text_mode(rtm);
+ set_clip_rect(gui_bitmap, cl, ct, cr, cb);
+ } else {
+ return d_edit_proc(msg, d, c);
+ }
+ return D_O_K;
+}
+
+int tmw_list_proc(int msg, DIALOG *d, int c) {
+// BITMAP *box = NULL;
+
+ static int ignoreRedraw = FALSE;
+
+ int itemCount = 0;
+ int firstItem = d->d2;
+ int lastItem = 0;
+ int selectedItem = d->d1;
+ int x,y,delta;
+ int a, col;
+ int w, h = 0;
+ int rtm = 0;
+ int cl, cr, cb, ct;
+ int th = alfont_text_height(gui_font);
+
+ int vscroll = 0;
+ int sliderh = 10;
+ int slidery = 0;
+
+ (*(getfuncptr)d->dp)(-1, &itemCount);
+
+ w = d->w - gui_skin.listbox.bg.grid[0]->w - gui_skin.listbox.bg.grid[2]->w;
+ h = d->h - gui_skin.listbox.bg.grid[1]->h - gui_skin.listbox.bg.grid[7]->h;
+ lastItem = MIN(itemCount-1, firstItem + h / alfont_text_height(gui_font));
+
+
+
+ if (msg == MSG_DRAW) {
+ if (ignoreRedraw) {
+ return D_O_K;
+ }
+ rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg);
+ drawSkinnedRect(gui_bitmap, &gui_skin.listbox.bg, d->x, d->y, d->w, d->h);
+
+ (*(getfuncptr)d->dp)(-1, &itemCount);
+ vscroll = (h/th) < (itemCount-1);
+ if (vscroll) {
+ w = d->w - 17 - gui_skin.listbox.bg.grid[0]->w;
+ drawSkinnedRect(gui_bitmap, &gui_skin.listbox.bg, d->x+d->w-15, d->y+1, 14, d->h-2);
+ sliderh = MAX(((d->h-2)* (h / th)) / itemCount, gui_skin.listbox.bg.grid[0]->h*2);
+ slidery = ((d->h-2-sliderh) * firstItem) / (itemCount);
+ slidery+= d->y+1;
+ drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, d->x+d->w-13, slidery, 11, sliderh);
+ }
+
+ rtm = alfont_text_mode(-1);
+ if (gui_bitmap->clip) {
+ cl = gui_bitmap->cl;
+ ct = gui_bitmap->ct;
+ cr = gui_bitmap->cr;
+ cb = gui_bitmap->cb;
+ } else {
+ cl=ct=0;
+ cr=gui_bitmap->w;
+ cb=gui_bitmap->h;
+ }
+ x = d->x + gui_skin.listbox.bg.grid[0]->w;
+ y = d->y + gui_skin.listbox.bg.grid[0]->h;
+ set_clip_rect(gui_bitmap, x,y, x+w, y+h);
+
+
+ if (d->flags & D_DISABLED) {
+ col = gui_skin.listbox.textcolor[3];
+ for (a=firstItem; a < lastItem; a++) {
+ alfont_textout_aa(gui_bitmap, gui_font, (*(getfuncptr)d->dp)(a, 0), x, y, col);
+ y += alfont_text_height(gui_font);
+ }
+ } else {
+ for (a=firstItem; a <= lastItem; a++) {
+ if (a==d->d1) {
+ col = gui_skin.listbox.textcolor[1];
+ rectfill(gui_bitmap, x, y, x+w, y+alfont_text_height(gui_font)-1, gui_skin.listbox.textcolor[2]);
+ } else {
+ col = gui_skin.listbox.textcolor[0];
+ }
+ alfont_textout_aa(gui_bitmap, gui_font, (*(getfuncptr)d->dp)(a, 0), x, y, col);
+ y += alfont_text_height(gui_font);
+ }
+ }
+
+ alfont_text_mode(rtm);
+ set_clip_rect(gui_bitmap, cl, ct, cr, cb);
+
+ } else if (msg == MSG_CLICK) {
+
+ x = d->x + gui_skin.listbox.bg.grid[0]->w;
+ y = d->y + gui_skin.listbox.bg.grid[0]->h;
+
+ sliderh = MAX(((d->h-2)* (h / th)) / itemCount, gui_skin.listbox.bg.grid[0]->h*2);
+ //sliderh = ((d->h-2)* (h / th)) / itemCount;
+ slidery = ((d->h-2-sliderh) * firstItem) / (itemCount);
+ slidery+= d->y+1;
+
+ if (mouse_x > (d->x + d->w - 14) && mouse_x < (d->x+d->w-1)) {
+ // Ok, scroll bar
+ if (mouse_y >= slidery && mouse_y < slidery + sliderh) {
+ delta= mouse_y - slidery;
+ while (mouse_b) {
+ a = mouse_y - delta - d->y -1;
+ a *= itemCount;
+ a /= (d->h-2);
+ a = MID(0, a, itemCount- h/th);
+
+ if (a != d->d2) {
+ d->d2 = a;
+ scare_mouse();
+ object_message(d, MSG_DRAW, 0);
+ unscare_mouse();
+ }
+
+ slidery = ((d->h-2) * firstItem) / (itemCount);
+ slidery+= d->y+1;
+ }
+ } else if (mouse_y < slidery) {
+ a = d->d2 - (h/th)+1;
+ a = MID(0, a, itemCount- h/th);
+
+
+ d->d2 = a;
+ scare_mouse();
+ object_message(d, MSG_DRAW, 0);
+ unscare_mouse();
+
+ while (mouse_b) {
+ }
+ } else if (mouse_y > slidery + sliderh) {
+ a = d->d2 + (h/th)-1;
+ a = MID(0, a, itemCount- h/th);
+ d->d2 = a;
+
+ scare_mouse();
+ object_message(d, MSG_DRAW, 0);
+ unscare_mouse();
+
+ while (mouse_b) {
+ }
+ }
+ } else if (mouse_x >= x && mouse_x < x+w && mouse_y >= y && mouse_y < y+h) {
+
+ while (mouse_b) {
+ a = firstItem + (mouse_y-y) / alfont_text_height(gui_font);
+
+ if (a <= lastItem && a != selectedItem) {
+ d->d1 = selectedItem = a;
+ scare_mouse();
+ object_message(d, MSG_DRAW, 0);
+ unscare_mouse();
+ }
+ }
+ }
+ } else {
+ ignoreRedraw = (msg == MSG_GOTFOCUS || msg == MSG_LOSTFOCUS);
+ a = d_list_proc(msg, d, c);
+
+ if (a == D_USED_CHAR) {
+ if (d->d1 < d->d2) {
+ if (d->d1 > 0) {
+ d->d1 = d->d2;
+ }
+ } else if (d->d1 > d->d2 + h/th -1) {
+ d->d2 = d->d1 - h/th + 1;
+ }
+ }
+
+ return a;
+ }
+ return D_O_K;
+}
+
+int tmw_dialog_proc(int msg, DIALOG *d, int c) {
+ int rtm;
+ int x, y;
+
+ if (msg == MSG_CLICK) {
+ if(mouse_y < d->y + gui_skin.dialog.bg.grid[1]->h) {
+ //drag = true;
+ d->d1 = mouse_x - d->x;
+ d->d2 = mouse_y - d->y;
+ }
+ } else if (msg == MSG_DRAW) {
+ if((mouse_b & 1)&&(d->d1>=0)&&(d->d2>=0)) {//(drag==true)) {
+ 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>=785) {
+ x=800-d->w;
+ position_mouse(x+d->d1, mouse_y);
+ }
+ if(y+d->h>=585) {
+ y=600-d->h;
+ position_mouse(mouse_x, y+d->d2);
+ }
+ position_dialog(active_dialog, x, y);
+ } else {
+ //drag = false;
+ d->d1 = -1;
+ d->d2 = -1;
+ }
+ drawSkinnedRect(gui_bitmap, &gui_skin.dialog.bg, d->x, d->y, d->w, d->h);
+ rtm = alfont_text_mode(-1);
+ alfont_textprintf_centre_aa(gui_bitmap, gui_font,
+ d->x + d->w/2,
+ d->y + (gui_skin.dialog.bg.grid[1]->h - alfont_text_height(gui_font))/2, d->fg, "%s", d->dp);
+ alfont_text_mode(rtm);
+ }
+ return D_O_K;
+}
+
+int reroute_slider_proc(void *dp3, int d2) {
+ int ret = 0;
+
+ if (gui__external_slider_callback != NULL) {
+ ret = gui__external_slider_callback(dp3, d2);
+ }
+ return ret;
+}
+
+// Helper function to draw a scrollable bar
+void _gui_draw_scrollable_frame(DIALOG *d, int listsize, int offset, int height, int fg_color, int bg) {
+ int i, len;
+ int xx, yy;
+
+ /* create and draw the scrollbar */
+ i = ((d->h-5) * height + listsize/2) / listsize;
+ xx = d->x+d->w-10;
+ yy = d->y;
+
+ if (offset > 0) {
+ len = (((d->h-5) * offset) + listsize/2) / listsize;
+ } else len = 0;
+ if (yy+i < d->y+d->h-3) {
+ drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, xx, yy+len, 10, i);
+ } else {
+ drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, xx, yy, 10, d->h-3);
+ }
+}
+
+/* _gui_draw_textbox:
+ * Helper function to draw a textbox object.
+ */
+void _gui_draw_textbox(char *thetext, int *listsize, int draw, int offset,
+ int wword, int tabsize, int x, int y, int w, int h,
+ int disabled, int fore, int deselect, int disable)
+{
+ int fg = fore;
+ int y1 = y+4;
+ int x1;
+ int len;
+ int ww = w-6;
+ char s[16];
+ char text[16];
+ char space[16];
+ char *printed = text;
+ char *scanned = text;
+ char *oldscan = text;
+ char *ignore = NULL;
+ char *tmp, *ptmp;
+ int width;
+ int line = 0;
+ int i = 0;
+ int noignore;
+ int rtm;
+
+ usetc(s+usetc(s, '.'), 0);
+ usetc(text+usetc(text, ' '), 0);
+ usetc(space+usetc(space, ' '), 0);
+
+ /* find the correct text */
+ if (thetext != NULL) {
+ printed = thetext;
+ scanned = thetext;
+ }
+
+ /* choose the text color */
+ if (disabled)
+ fg = disable;
+
+ rtm = alfont_text_mode(-1);
+
+ /* loop over the entire string */
+ while (1) {
+ width = 0;
+
+ /* find the next break */
+ while (ugetc(scanned)) {
+ /* check for a forced break */
+ if (ugetc(scanned) == '\n') {
+ scanned += uwidth(scanned);
+
+ /* we are done parsing the line end */
+ break;
+ }
+
+ /* the next character length */
+ usetc(s+usetc(s, ugetc(scanned)), 0);
+ len = alfont_text_length(gui_font, s);
+
+ /* modify length if its a tab */
+ if (ugetc(s) == '\t')
+ len = tabsize * alfont_text_length(gui_font, space);
+
+ /* check for the end of a line by excess width of next char */
+ if (width+len >= ww) {
+ /* we have reached end of line do we go back to find start */
+ if (wword) {
+ /* remember where we were */
+ oldscan = scanned;
+ noignore = FALSE;
+
+ /* go backwards looking for start of word */
+ while (!uisspace(ugetc(scanned))) {
+ /* don't wrap too far */
+ if (scanned == printed) {
+ /* the whole line is filled, so stop here */
+ tmp = ptmp = scanned;
+ while (ptmp != oldscan) {
+ ptmp = tmp;
+ tmp += uwidth(tmp);
+ }
+ scanned = ptmp;
+ noignore = TRUE;
+ break;
+ }
+ /* look further backwards to wrap */
+ tmp = ptmp = printed;
+ while (tmp < scanned) {
+ ptmp = tmp;
+ tmp += uwidth(tmp);
+ }
+ scanned = ptmp;
+ }
+ /* put the space at the end of the line */
+ if (!noignore) {
+ ignore = scanned;
+ scanned += uwidth(scanned);
+ }
+ else
+ ignore = NULL;
+
+ /* check for endline at the convenient place */
+ if (ugetc(scanned) == '\n')
+ scanned += uwidth(scanned);
+ }
+ /* we are done parsing the line end */
+ break;
+ }
+
+ /* the character can be added */
+ scanned += uwidth(scanned);
+ width += len;
+ }
+
+ /* check if we are to print it */
+ if ((draw) && (line >= offset) && (y1+text_height(font) < (y+h-3))) {
+ x1 = x+4;
+
+ /* the initial blank bit */
+ //rectfill(gui_bitmap, x+2, y1, x1-1, y1+text_height(font), deselect);
+
+ /* print up to the marked character */
+ while (printed != scanned) {
+ /* do special stuff for each charater */
+ switch (ugetc(printed)) {
+
+ case '\r':
+ case '\n':
+ /* don't print endlines in the text */
+ break;
+
+ /* possibly expand the tabs */
+ case '\t':
+ for (i=0; i<tabsize; i++) {
+ usetc(s+usetc(s, ' '), 0);
+ alfont_textout_aa(gui_bitmap, gui_font, s, x1, y1, fg);
+ x1 += alfont_text_length(gui_font, s);
+ }
+ break;
+
+ /* print a normal character */
+ default:
+ if (printed != ignore) {
+ usetc(s+usetc(s, ugetc(printed)), 0);
+ alfont_textout_aa(gui_bitmap, gui_font, s, x1, y1, fg);
+ x1 += alfont_text_length(gui_font, s);
+ }
+ }
+
+ /* goto the next character */
+ printed += uwidth(printed);
+ }
+ /* the last blank bit */
+ /*if (x1 <= x+w-3)
+ rectfill(gui_bitmap, x1, y1, x+w-3, y1+alfont_text_height(gui_font)-1, deselect);*/
+
+ /* print the line end */
+ y1 += alfont_text_height(gui_font);
+ }
+ printed = scanned;
+
+ /* we have done a line */
+ line++;
+
+ /* check if we are at the end of the string */
+ if (!ugetc(printed)) {
+ /* the under blank bit */
+ /*if (draw)
+ rectfill(gui_bitmap, x+1, y1, x+w-3, y+h-1, deselect);*/
+
+ /* tell how many lines we found */
+ *listsize = line;
+ alfont_text_mode(rtm);
+ return;
+ }
+ }
+
+ alfont_text_mode(rtm);
+}
+
+int tmw_textbox_proc(int msg, DIALOG *d, int c) {
+ int height, bar, ret = D_O_K;
+ int start, top, bottom, l;
+ int used, delta;
+ int fg_color = (d->flags & D_DISABLED) ? gui_mg_color : d->fg;
+
+ /* calculate the actual height */
+ height = (d->h-8) / alfont_text_height(gui_font);
+
+ switch (msg) {
+
+ case MSG_START:
+ /* measure how many lines of text we contain */
+ _gui_draw_textbox((char *)d->dp, &d->d1,
+ 0, /* DONT DRAW anything */
+ d->d2, !(d->flags & D_SELECTED), 8,
+ d->x, d->y, d->w, d->h,
+ (d->flags & D_DISABLED),
+ 0, 0, 0);
+ break;
+
+ case MSG_DRAW:
+ /* tell the object to sort of draw, but only calculate the listsize */
+ _gui_draw_textbox((char *)d->dp, &d->d1,
+ 0, /* DONT DRAW anything */
+ d->d2, !(d->flags & D_SELECTED), 8,
+ d->x, d->y, d->w, d->h,
+ (d->flags & D_DISABLED),
+ 0, 0, 0);
+
+ if (d->d1 > height) {
+ bar = 12;
+ }
+ else {
+ bar = 0;
+ d->d2 = 0;
+ }
+
+ /* now do the actual drawing */
+ _gui_draw_textbox((char *)d->dp, &d->d1, 1, d->d2,
+ !(d->flags & D_SELECTED), 8,
+ d->x, d->y, d->w-bar, d->h,
+ (d->flags & D_DISABLED),
+ fg_color, d->bg, gui_mg_color);
+
+ /* draw the frame around */
+ _gui_draw_scrollable_frame(d, d->d1, d->d2, height, fg_color, d->bg);
+
+ break;
+
+ case MSG_CLICK:
+ /* figure out if it's on the text or the scrollbar */
+ bar = (d->d1 > height);
+
+ if ((!bar) || (gui_mouse_x() < d->x+d->w-13)) {
+ /* clicked on the text area */
+ ret = D_O_K;
+ }
+ else {
+ /* clicked on the scroll area */
+ _handle_scrollable_scroll_click(d, d->d1, &d->d2, height);
+ }
+ break;
+
+ case MSG_CHAR:
+ start = d->d2;
+ used = D_USED_CHAR;
+
+ if (d->d1 > 0) {
+ if (d->d2 > 0)
+ top = d->d2+1;
+ else
+ top = 0;
+
+ l = (d->h-8)/alfont_text_height(gui_font);
+
+ bottom = d->d2 + l - 1;
+ if (bottom >= d->d1-1)
+ bottom = d->d1-1;
+ else
+ bottom--;
+
+ if ((c>>8) == KEY_UP)
+ d->d2--;
+ else if ((c>>8) == KEY_DOWN)
+ d->d2++;
+ else if ((c>>8) == KEY_HOME)
+ d->d2 = 0;
+ else if ((c>>8) == KEY_END)
+ d->d2 = d->d1-l;
+ else if ((c>>8) == KEY_PGUP)
+ d->d2 -= (bottom-top) ? bottom-top : 1;
+ else if ((c>>8) == KEY_PGDN)
+ d->d2 += (bottom-top) ? bottom-top : 1;
+ else
+ used = D_O_K;
+
+ /* make sure that the list stays in bounds */
+ if (d->d2 > d->d1-l)
+ d->d2 = d->d1-l;
+ if (d->d2 < 0)
+ d->d2 = 0;
+ }
+ else
+ used = D_O_K;
+
+ /* if we changed something, better redraw... */
+ if (d->d2 != start)
+ d->flags |= D_DIRTY;
+
+ ret = used;
+ break;
+
+ case MSG_WHEEL:
+ l = (d->h-8)/alfont_text_height(gui_font);
+ delta = (l > 3) ? 3 : 1;
+
+ /* scroll, making sure that the list stays in bounds */
+ start = d->d2;
+ d->d2 = (c > 0) ? MAX(0, d->d2-delta) : MIN(d->d1-l, d->d2+delta);
+
+ /* if we changed something, better redraw... */
+ if (d->d2 != start)
+ d->flags |= D_DIRTY;
+
+ ret = D_O_K;
+ break;
+
+ case MSG_WANTFOCUS:
+ /* if we don't have a scrollbar we can't do anything with the focus */
+ if (d->d1 > height)
+ ret = D_WANTFOCUS;
+ break;
+
+ default:
+ ret = D_O_K;
+ }
+
+ return ret;
+}
+
+int tmw_bitmap_proc(int msg, DIALOG *d, int c) {
+ if(msg==MSG_DRAW) {
+ drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h);
+ if(d->dp!=NULL)
+ masked_blit(((BITMAP *)d->dp), gui_bitmap, 0, 0, d->x+(d->w-d->d1)/2, d->y+2, d->d1, d->d2);
+ }
+ 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 = alfont_text_length(gui_font, message)+4;
+ alert_dialog[1].w = alfont_text_length(gui_font, message);
+ alert_dialog[1].h = alfont_text_height(gui_font);
+ alert_dialog[2].x = alfont_text_length(gui_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 = alfont_text_length(gui_font, message)+4;
+ if(width<100)width=100;
+ alert_dialog[0].w = width;
+ alert_dialog[1].w = alfont_text_length(gui_font, message);
+ alert_dialog[1].h = alfont_text_height(gui_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;
+}