Adonthell  0.4
data_screen.cc
Go to the documentation of this file.
1 /*
2  $Id: data_screen.cc,v 1.25 2003/05/05 18:52:48 ksterker Exp $
3 
4  Copyright (C) 2001/2002 by Kai Sterker <kaisterker@linuxgames.com>
5  Part of the Adonthell Project http://adonthell.linuxgames.com
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 
16 /**
17  * @file data_screen.cc
18  * @author Kai Sterker <kaisterker@linuxgames.com>
19  *
20  * @brief Defines the data_screen class.
21  *
22  *
23  */
24 
25 
26 #include <string.h>
27 
28 #include "pnm.h"
29 #include "gamedata.h"
30 #include "gamedate.h"
31 #include "image.h"
32 #include "input.h"
33 #include "window.h"
34 #include "data_screen.h"
35 #include "gametime.h"
36 #include "win_manager.h"
37 
39 {
40  mode = m;
41  aborted = false;
42 
43  entry = NULL;
44 
45  //Init Position and Size
46  win_container::move (30, 15);
47  win_container::resize (260, 210);
48 
49  // Create GUI
50  font = win_manager::get_font ("original");
51  theme = win_manager::get_theme ("original");
52 
53  //Set features used
54  set_border(*theme);
55  set_background(*theme);
56 
57  //Set special Features
58  set_trans_background(true);
59 
60  //Create a win_select
61  image_list = new win_select();
62  image_list->move (10, 0);
63  image_list->resize (250, 210);
64  image_list->set_mode (win_select::MODE_BRIGHTNESS);
65  image_list->set_layout (win_container::LIST_LAYOUT);
66  image_list->set_circle (true);
67  image_list->set_space_with_border (9);
68  image_list->set_space_with_object (9);
69 
70  image_list->set_scrollbar (*theme);
71  image_list->set_visible_scrollbar (true);
72 
73  // activate the list
74  image_list->set_activate (true);
75 
76  // give focus to the list
77  set_focus_object (image_list);
78 
79  image_list->set_signal_connect (
80  makeFunctor (*this, &data_screen::on_select),
81  win_event::ACTIVATE_KEY);
82 
83  // add the win_select to *this
84  add (image_list);
85 
86  // add all the saved games to the list
87  init ();
88 
89  // show everything
90  set_visible_background (true);
91  set_visible_border (true);
92  set_visible_all (true);
93 }
94 
96 {
97  // fade in from black after loading a game
98  if (mode == LOAD_SCREEN && !aborted) data::engine->fade_in ();
99 }
100 
101 void data_screen::init ()
102 {
103  string filepath;
104  u_int16 num = 0;
105  win_image *shot;
106  win_write *entry;
107  win_label *date;
108  win_container *box = NULL;
109  win_font *yellow = win_manager::get_font ("yellow");
110  gamedata *gdata;
111 
112  // display all the available saved games
113  while ((gdata = gamedata::next_save ()) != NULL)
114  {
115  filepath = gdata->directory ();
116  filepath += "/preview.pnm";
117 
118  shot = new win_image ();
119  shot->image::load_pnm (filepath);
120  shot->move (5, 2);
121  shot->set_border (*theme, win_border::MINI);
122  shot->set_visible_border (true);
123  shot->pack();
124 
125  date = new win_label ();
126  date->move (100, 2);
127  ((label*)date)->resize (130, 14);
128  date->set_font (*yellow);
129  date->set_text (gdata->gametime ());
130  date->set_cursor_visible (false);
131  date->pack();
132 
133  entry = new win_write ();
134  entry->move (100, 18);
135  ((label_input*)entry)->resize (130, 40);
136  entry->set_font (*font);
137  entry->set_text (gdata->description ());
138  entry->set_cursor_visible (false);
139  entry->pack();
140 
141  entry_list.push_back (entry);
142 
143  box = new win_container ();
144  box->move (0, 0);
145  box->resize (230, 58);
146  box->add (shot);
147  box->add (date);
148  box->add (entry);
149  box->set_visible_all (true);
150 
151  // when the box is activated, we set the entry as
152  // focus object of the box
153  box->set_focus_object (entry);
154 
155  image_list->add (box);
156 
157  num++;
158  }
159 
160  // If we're saving the game, add "Empty Slot"
161  if (mode == SAVE_SCREEN)
162  {
163  sprintf (gametime, "Day %i - %02i:%02i", gamedate::day (),
165 
166  shot = new win_image ();
167  shot->move (5, 2);
168  shot->load_pnm ("gfx/empty_slot.pnm");
169  shot->set_border (*theme, win_border::MINI);
170  shot->set_visible_border (true);
171  shot->pack ();
172 
173  date = new win_label ();
174  date->move (100, 2);
175  ((label*)date)->resize (130, 14);
176  date->set_font (*yellow);
177  date->set_text (gametime);
178  date->set_cursor_visible (false);
179  date->pack();
180 
181  entry = new win_write ();
182  entry->set_font (*font);
183  entry->move (100, 18);
184  ((label_input*) entry)->resize (130, 40);
185  entry->set_text ("Empty Slot");
186  entry->set_cursor_visible (false);
187  entry->pack ();
188 
189  entry_list.push_back (entry);
190 
191  box = new win_container ();
192  box->move (0, 0);
193  box->resize (230, 58);
194  box->add (shot);
195  box->add (date);
196  box->add (entry);
197  box->set_visible_all (true);
198 
199  // when the box is activated, we set the entry as
200  // focus object of the box
201  box->set_focus_object(entry);
202 
203  image_list->add (box);
204  image_list->set_default_object (box);
205 
206  num++;
207  }
208  else image_list->set_default_position (0);
209 
210  // If there are no saved games, display a message.
211  if (!num)
212  {
213  box = new win_container ();
214  box->move(0, 0);
215  box->resize(230, 150);
216 
217  win_label * mess = new win_label ();
218  mess->set_font (*font);
219  mess->move (0, 65);
220  mess->set_form (label::AUTO_SIZE);
221  mess->set_text ("You have no saved games yet!");
222  mess->set_align (win_base::ALIGN_CENTER);
223  mess->pack ();
224  box->add (mess);
225 
226  mess = new win_label ();
227  mess->set_font (*font);
228  mess->move (0, 115);
229  mess->set_form (label::AUTO_SIZE);
230  mess->set_text ("Press ESC.");
231  mess->set_align (win_base::ALIGN_CENTER);
232  mess->pack ();
233  box->add (mess);
234 
235  box->set_visible_all (true);
236  box->set_can_be_selected (false);
237 
238  image_list->add (box);
239  }
240 }
241 
243 {
244  if (!win_container::update() || input::has_been_pushed (SDLK_ESCAPE))
245  {
246  aborted = true;
247  data::engine->main_quit ();
248  }
249 
250  return true;
251 }
252 
253 // Select a game
254 void data_screen::on_select ()
255 {
256  int pos = image_list->get_selected_position ();
257 
258  // loading
259  if (mode == LOAD_SCREEN)
260  {
261  // fade to black before doing the actual work
262  data::engine->fade_out ();
263  set_visible (false);
264  if (!gamedata::load (pos)) aborted = true;
265  data::engine->main_quit ();
266  }
267  // saving
268  else
269  {
270  win_container * tmp = (win_container*)image_list->get_selected_object();
271  image_list->set_focus_object(tmp);
272 
273  entry = (win_write*) tmp->focus_object();
274  entry->set_cursor_visible (true);
275  entry->set_cursor_moveable (true);
276 
277  const char *txt = entry->text_char ();
278  if (txt && !strncmp (txt, "Empty Slot", 10))
279  entry->set_text ("");
280 
281  entry->set_signal_connect (makeFunctor (*this, &data_screen::on_save),
282  win_event::ACTIVATE_KEY);
283  entry->set_activate (true);
285  }
286 }
287 
288 void data_screen::on_save ()
289 {
290  const char* description = entry->text_char ();
291  int pos = image_list->get_selected_position ();
292 
293  gamedata::save (pos, description, gametime);
294  gamedata *gdata = gamedata::get_saved_game (pos);
295 
296  // save sucessful --> save preview
297  if (gdata != NULL)
298  {
299  string filepath = gdata->directory ();
300  filepath += "/preview.pnm";
301  save_preview (filepath);
302  }
303 
304  data::engine->main_quit ();
305 }
306 
307 // Save the small thumbnail image
308 void data_screen::save_preview (string path)
309 {
310  drawing_area da (0, 0, screen::length () >> 1, screen::height () >> 1);
311  image temp (da.length (), da.height());
312  image preview (72, 54);
313 
314  mapview *view = data::engine->get_mapview ();
315  mapsquare_area *area = data::engine->get_landmap ()->get_submap
316  (data::the_player->submap ());
317 
318  u_int16 offx = 0;
319  u_int16 offy = 0;
320 
321  // In those cases where the mapview is smaller than the physical screen,
322  // it will be centered on the screen -> get the offset
323  if (area->area_length () * MAPSQUARE_SIZE < view->length ())
324  offx = (view->length () - area->area_length () * MAPSQUARE_SIZE) >> 1;
325  if (area->area_height () * MAPSQUARE_SIZE < view->height ())
326  offy = (view->height () - area->area_height () * MAPSQUARE_SIZE) >> 1;
327 
328  // Calculate the player's absolute position on the screen
329  s_int16 x = (data::the_player->posx () - view->posx ()) * MAPSQUARE_SIZE + offx;
330  s_int16 y = (data::the_player->posy () - view->posy ()) * MAPSQUARE_SIZE + offy;
331 
332  // this is a quarter of the screen's size.
333  u_int16 length = da.length() >> 1;
334  u_int16 height = da.height() >> 1;
335 
336  // If the player is too close to the border, make sure we still stay
337  // within the screen
338  if (x + length > screen::length ()) x = -da.length ();
339  else if (x - length < 0) x = 0;
340  else x = length - x;
341 
342  if (y + height > screen::height ()) y = -da.height ();
343  else if (y - height < 0) y = 0;
344  else y = height - y;
345 
346  data::engine->draw (x, y, &da, &temp);
347  preview.zoom (temp);
348  preview.save_pnm (path);
349 }