Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
 
21
#include <stdio.h>
22
#include <stdarg.h>
23
 
24
#include "maths.h"
25
#include "pstypes.h"
26
#include "gr.h"
27
#include "event.h"
28
#include "ui.h"
29
#include "mouse.h"
30
#include "key.h"
31
#include "u_mem.h"
32
 
33
#include "dxxsconf.h"
34
#include "dsx-ns.h"
35
#include <array>
36
#include <memory>
37
 
38
namespace dcx {
39
 
40
// ts = total span
41
// w = width of each item
42
// n = number of items
43
// i = item number (0 based)
44
#define EVEN_DIVIDE(ts,w,n,i) ((((ts)-((w)*(n)))*((i)+1))/((n)+1))+((w)*(i))
45
 
46
#define BUTTON_HORZ_SPACING 20
47
#define TEXT_EXTRA_HEIGHT 5
48
 
49
namespace {
50
 
51
struct messagebox
52
{
53
        const ui_messagebox_tie *button;
54
        std::array<std::unique_ptr<UI_GADGET_BUTTON>, 10> button_g;
55
        const char                              *text;
56
        int                                     *choice;
57
        int                                     width;
58
        int                                     text_y;
59
        int                                     line_y;
60
};
61
 
62
}
63
 
64
static window_event_result messagebox_handler(UI_DIALOG *dlg,const d_event &event, messagebox *m)
65
{
66
        if (event.type == EVENT_UI_DIALOG_DRAW)
67
        {
68
                const grs_font * temp_font;
69
 
70
                gr_set_current_canvas(grd_curscreen->sc_canvas);
71
                auto &canvas = *grd_curcanv;
72
                temp_font = grd_curscreen->sc_canvas.cv_font;
73
 
74
                if (grd_curscreen->get_screen_width() < 640) {
75
                        grd_curscreen->sc_canvas.cv_font = ui_small_font.get();
76
                }
77
 
78
                ui_dialog_set_current_canvas(dlg);
79
                ui_string_centered(canvas, m->width / 2, m->text_y, m->text);
80
 
81
                Hline(canvas, 1, m->width - 2, m->line_y + 1, CGREY);
82
                Hline(canvas, 2, m->width - 2, m->line_y + 2, CBRIGHT);
83
 
84
                grd_curscreen->sc_canvas.cv_font = temp_font;
85
 
86
                return window_event_result::handled;
87
        }
88
 
89
        for (uint_fast32_t i=0; i < m->button->count(); i++ )
90
        {
91
                if (GADGET_PRESSED(m->button_g[i].get()))
92
                {
93
                        *(m->choice) = i+1;
94
                        return window_event_result::handled;
95
                }
96
        }
97
 
98
        return window_event_result::ignored;
99
}
100
 
101
int (ui_messagebox)( short xc, short yc, const char * text, const ui_messagebox_tie &Button )
102
{
103
        UI_DIALOG * dlg;
104
        int avg, x, y;
105
        int button_width, button_height, text_height, text_width;
106
        int w, h;
107
 
108
        int choice;
109
 
110
        auto m = std::make_unique<messagebox>();
111
        m->button = &Button;
112
        m->text = text;
113
        m->choice = &choice;
114
 
115
        button_width = button_height = 0;
116
 
117
        gr_set_current_canvas(grd_curscreen->sc_canvas);
118
        auto &canvas = *grd_curcanv;
119
        auto &cv_font = *canvas.cv_font;
120
        w = grd_curscreen->get_screen_width();
121
        h = grd_curscreen->get_screen_height();
122
 
123
        for (uint_fast32_t i=0; i < Button.count(); i++ )
124
        {
125
                int width, height;
126
                ui_get_button_size(cv_font, Button.string(i), width, height);
127
 
128
                if ( width > button_width ) button_width = width;
129
                if ( height > button_height ) button_height = height;
130
        }
131
 
132
        gr_get_string_size(cv_font, text, &text_width, &text_height, &avg);
133
 
134
        unsigned width, height;
135
        width = button_width*Button.count();
136
        width += BUTTON_HORZ_SPACING*(Button.count()+1);
137
        width ++;
138
 
139
        text_width += avg*6;
140
        text_width += 10;
141
 
142
        if (text_width > width )
143
                width = text_width;
144
 
145
        height = text_height;
146
        height += button_height;
147
        height += 4*TEXT_EXTRA_HEIGHT;
148
        height += 2;  // For line in middle
149
 
150
        {
151
                int mx, my, mz;
152
 
153
                mouse_get_pos(&mx, &my, &mz);
154
 
155
                if ( xc == -1 )
156
                        xc = mx;
157
 
158
                if ( yc == -1 )
159
                        yc = my - button_height/2;
160
        }
161
 
162
        if ( xc == -2 )
163
                xc = w/2;
164
 
165
        if ( yc == -2 )
166
                yc = h/2;
167
 
168
        x = xc - width/2;
169
        y = yc - height/2;
170
 
171
        if (x < 0 ) {
172
                x = 0;
173
        }
174
 
175
        if ( (x+width-1) >= w ) {
176
                x = w - width;
177
        }
178
 
179
        if (y < 0 ) {
180
                y = 0;
181
        }
182
 
183
        if ( (y+height-1) >= h ) {
184
                y = h - height;
185
        }
186
 
187
        dlg = ui_create_dialog(x, y, width, height, static_cast<dialog_flags>(DF_DIALOG | DF_MODAL), messagebox_handler, m.get());
188
 
189
        y = TEXT_EXTRA_HEIGHT + text_height/2 - 1;
190
 
191
        m->width = width;
192
        m->text_y = y;
193
 
194
        y = 2*TEXT_EXTRA_HEIGHT + text_height;
195
 
196
        m->line_y = y;
197
 
198
        y = height - TEXT_EXTRA_HEIGHT - button_height;
199
 
200
        for (uint_fast32_t i=0; i < Button.count(); i++ )
201
        {
202
 
203
                x = EVEN_DIVIDE(width,button_width,Button.count(),i);
204
 
205
                m->button_g[i] = ui_add_gadget_button( dlg, x, y, button_width, button_height, Button.string(i), NULL );
206
        }
207
 
208
        ui_gadget_calc_keys(dlg);
209
 
210
        //key_flush();
211
 
212
        dlg->keyboard_focus_gadget = m->button_g[0].get();
213
 
214
        choice = 0;
215
 
216
        while(choice==0)
217
                event_process();
218
 
219
        ui_close_dialog(dlg);
220
 
221
        return choice;
222
}
223
 
224
}