1 /*
2 Copyright (C) 2000-2013 The Exult Team
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <SDL_events.h>
24
25 #include "Yesno_gump.h"
26 #include "gamewin.h"
27 #include "mouse.h"
28 #include "game.h"
29 #include "Gump_button.h"
30 #include "Gump_manager.h"
31 #include "font.h"
32 #include "exult.h"
33 #include "touchui.h"
34
35 #include <cstring>
36
37 /*
38 * Statics:
39 */
40
41 short Yesno_gump::yesx = 63;
42 short Yesno_gump::yesnoy = 45;
43 short Yesno_gump::nox = 84;
44
45
46 /*
47 * A 'yes' or 'no' button.
48 */
49
50 class Yesno_button : public Gump_button {
51 int isyes; // 1 for 'yes', 0 for 'no'.
52 public:
Yesno_button(Gump * par,int px,int py,int yes)53 Yesno_button(Gump *par, int px, int py, int yes)
54 : Gump_button(par, yes ?
55 game->get_shape("gumps/yesbtn")
56 : game->get_shape("gumps/nobtn"), px, py),
57 isyes(yes)
58 { }
59 // What to do when 'clicked':
60 bool activate(int button = 1) override;
61 };
62
63
64 /*
65 * Handle 'yes' or 'no' button.
66 */
67
activate(int button)68 bool Yesno_button::activate(
69 int button
70 ) {
71 if (button != 1) return false;
72 static_cast<Yesno_gump *>(parent)->set_answer(isyes);
73 return true;
74 }
75
76
77 /*
78 * Create a yes/no box.
79 */
80
Yesno_gump(const std::string & txt,const char * font)81 Yesno_gump::Yesno_gump(
82 const std::string &txt, const char *font
83 ) : Modal_gump(nullptr, game->get_shape("gumps/yesnobox")), text(txt), fontname(font), answer(-1) {
84 set_object_area(TileRect(6, 5, 116, 32));
85 add_elem(new Yesno_button(this, yesx, yesnoy, 1));
86 add_elem(new Yesno_button(this, nox, yesnoy, 0));
87 }
88
89 /*
90 * Paint on screen.
91 */
92
paint()93 void Yesno_gump::paint(
94 ) {
95 // Paint the gump itself.
96 paint_shape(x, y);
97 paint_elems(); // Paint buttons.
98 // Paint text.
99 fontManager.get_font(fontname)->paint_text_box(gwin->get_win()->get_ib8(), text.c_str(),
100 x + object_area.x, y + object_area.y, object_area.w, object_area.h, 2);
101 if (touchui != nullptr) {
102 touchui->showButtonControls();
103 }
104 gwin->set_painted();
105 }
106
107 /*
108 * Handle mouse-down events.
109 */
110
mouse_down(int mx,int my,int button)111 bool Yesno_gump::mouse_down(
112 int mx, int my, int button // Position in window.
113 ) {
114 if (button != 1) return false;
115 pushed = on_button(mx, my);
116 if (pushed)
117 pushed->push(button); // Show it.
118 return true;
119 }
120
121 /*
122 * Handle mouse-up events.
123 */
124
mouse_up(int mx,int my,int button)125 bool Yesno_gump::mouse_up(
126 int mx, int my, int button // Position in window.
127 ) {
128 if (button != 1) return false;
129
130 if (pushed) { // Pushing a button?
131 pushed->unpush(button);
132 if (pushed->on_button(mx, my))
133 pushed->activate(button);
134 pushed = nullptr;
135 }
136 return true;
137 }
138
139 /*
140 * Handle ASCII character typed.
141 */
142
key_down(int chr)143 void Yesno_gump::key_down(int chr) {
144 if (chr == 'y' || chr == 'Y' || chr == SDLK_RETURN || chr == SDLK_KP_ENTER)
145 set_answer(1);
146 else if (chr == 'n' || chr == 'N' || chr == SDLK_ESCAPE)
147 set_answer(0);
148 }
149
150 /*
151 * Get an answer to a question.
152 *
153 * Output: 1 if yes, 0 if no or ESC.
154 */
155
ask(const char * txt,const char * font)156 bool Yesno_gump::ask(
157 const char *txt, // What to ask.
158 const char *font
159 ) {
160 Yesno_gump dlg(txt, font);
161 bool answer;
162 if (!gumpman->do_modal_gump(&dlg, Mouse::hand))
163 answer = false;
164 else
165 answer = dlg.get_answer();
166 if (touchui != nullptr && gumpman->gump_mode())
167 touchui->hideButtonControls();
168 return answer;
169 }
170
171
172
Countdown_gump(const std::string & txt,int timeout,const char * font)173 Countdown_gump::Countdown_gump(const std::string &txt, int timeout, const char *font) :
174 Yesno_gump(std::string(), font), text_fmt(txt), timer(timeout) {
175 answer = false;
176 start_time = SDL_GetTicks();
177 }
178
run()179 bool Countdown_gump::run() {
180 int elapsed = SDL_GetTicks() - start_time;
181 int remaining = timer * 1000 - elapsed;
182
183 if (remaining <= 0) set_answer(0);
184
185 char *new_text = new char[text_fmt.size() + 32];
186 snprintf(new_text, text_fmt.size() + 31, "%s %i...", text_fmt.c_str(), remaining / 1000);
187 new_text[text_fmt.size() + 31] = 0;
188 text = new_text;
189 delete [] new_text;
190
191 return true;
192 }
193
ask(const char * txt,int timeout,const char * font)194 bool Countdown_gump::ask(const char *txt, int timeout, const char *font) {
195 Countdown_gump dlg(txt, timeout, font);
196 bool answer;
197 if (!gumpman->do_modal_gump(&dlg, Mouse::hand))
198 answer = false;
199 else
200 answer = dlg.get_answer();
201 if (touchui != nullptr && gumpman->gump_mode())
202 touchui->hideButtonControls();
203 return answer;
204 }
205