Adonthell  0.4
data_screen.cc
Go to the documentation of this file.
00001 /*
00002    $Id: data_screen.cc,v 1.25 2003/05/05 18:52:48 ksterker Exp $
00003 
00004    Copyright (C) 2001/2002 by Kai Sterker <kaisterker@linuxgames.com>
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 
00016 /**
00017  * @file   data_screen.cc
00018  * @author Kai Sterker <kaisterker@linuxgames.com>
00019  * 
00020  * @brief  Defines the data_screen class.
00021  * 
00022  * 
00023  */
00024 
00025 
00026 #include <string.h>
00027 
00028 #include "pnm.h"
00029 #include "gamedata.h"
00030 #include "gamedate.h"
00031 #include "image.h"
00032 #include "input.h"
00033 #include "window.h"
00034 #include "data_screen.h"
00035 #include "gametime.h"
00036 #include "win_manager.h"
00037 
00038 data_screen::data_screen (int m)
00039 {
00040     mode = m;
00041     aborted = false;
00042 
00043     entry = NULL;
00044 
00045     //Init Position and Size
00046     win_container::move (30, 15);
00047     win_container::resize (260, 210);
00048     
00049     // Create GUI
00050     font = win_manager::get_font ("original");
00051     theme = win_manager::get_theme ("original"); 
00052     
00053     //Set features used
00054     set_border(*theme);
00055     set_background(*theme);
00056 
00057     //Set special Features
00058     set_trans_background(true);
00059      
00060     //Create a win_select
00061     image_list = new win_select();
00062     image_list->move (10, 0);
00063     image_list->resize (250, 210);
00064     image_list->set_mode (win_select::MODE_BRIGHTNESS);
00065     image_list->set_layout (win_container::LIST_LAYOUT);
00066     image_list->set_circle (true);
00067     image_list->set_space_with_border (9);
00068     image_list->set_space_with_object (9);
00069     
00070     image_list->set_scrollbar (*theme);
00071     image_list->set_visible_scrollbar (true);
00072     
00073     // activate the list
00074     image_list->set_activate (true);
00075     
00076     // give focus to the list
00077     set_focus_object (image_list);
00078     
00079     image_list->set_signal_connect (
00080         makeFunctor (*this, &data_screen::on_select), 
00081         win_event::ACTIVATE_KEY);
00082     
00083     // add the win_select to *this
00084     add (image_list);
00085     
00086     // add all the saved games to the list
00087     init ();
00088     
00089     // show everything
00090     set_visible_background (true);
00091     set_visible_border (true);
00092     set_visible_all (true);
00093 }
00094 
00095 data_screen::~data_screen ()
00096 {
00097     // fade in from black after loading a game
00098     if (mode == LOAD_SCREEN && !aborted) data::engine->fade_in ();
00099 }
00100 
00101 void data_screen::init ()
00102 {
00103     string filepath;
00104     u_int16 num = 0; 
00105     win_image *shot;
00106     win_write *entry;
00107     win_label *date;
00108     win_container *box = NULL;
00109     win_font *yellow = win_manager::get_font ("yellow");
00110     gamedata *gdata;
00111     
00112     // display all the available saved games
00113     while ((gdata = gamedata::next_save ()) != NULL)
00114     {
00115         filepath = gdata->directory ();
00116         filepath += "/preview.pnm";
00117     
00118         shot = new win_image ();
00119         shot->image::load_pnm (filepath); 
00120         shot->move (5, 2);
00121         shot->set_border (*theme, win_border::MINI);
00122         shot->set_visible_border (true);
00123         shot->pack();
00124         
00125         date = new win_label ();
00126         date->move (100, 2);
00127         ((label*)date)->resize (130, 14);
00128         date->set_font (*yellow);
00129         date->set_text (gdata->gametime ());
00130         date->set_cursor_visible (false);
00131         date->pack();
00132         
00133         entry = new win_write ();
00134         entry->move (100, 18);
00135         ((label_input*)entry)->resize (130, 40);
00136         entry->set_font (*font);
00137         entry->set_text (gdata->description ());
00138         entry->set_cursor_visible (false);
00139         entry->pack();
00140     
00141         entry_list.push_back (entry);
00142     
00143         box = new win_container ();
00144         box->move (0, 0);
00145         box->resize (230, 58);
00146         box->add (shot);
00147         box->add (date);
00148         box->add (entry);
00149         box->set_visible_all (true);
00150     
00151         // when the box is activated, we set the entry as 
00152         // focus object of the box
00153         box->set_focus_object (entry);
00154         
00155         image_list->add (box);
00156         
00157         num++;
00158     }
00159     
00160     // If we're saving the game, add "Empty Slot"
00161     if (mode == SAVE_SCREEN)
00162     {
00163         sprintf (gametime, "Day %i - %02i:%02i", gamedate::day (), 
00164             gamedate::hour (), gamedate::minute ());
00165         
00166         shot = new win_image ();
00167         shot->move (5, 2);
00168         shot->load_pnm ("gfx/empty_slot.pnm");
00169         shot->set_border (*theme, win_border::MINI);
00170         shot->set_visible_border (true);
00171         shot->pack (); 
00172         
00173         date = new win_label ();
00174         date->move (100, 2);
00175         ((label*)date)->resize (130, 14);
00176         date->set_font (*yellow);
00177         date->set_text (gametime);
00178         date->set_cursor_visible (false);
00179         date->pack();
00180 
00181         entry = new win_write ();
00182         entry->set_font (*font);
00183         entry->move (100, 18);
00184         ((label_input*) entry)->resize (130, 40);
00185         entry->set_text ("Empty Slot");
00186         entry->set_cursor_visible (false);
00187         entry->pack ();
00188     
00189         entry_list.push_back (entry);
00190         
00191         box = new win_container ();
00192         box->move (0, 0);
00193         box->resize (230, 58);
00194         box->add (shot);
00195         box->add (date);
00196         box->add (entry);
00197         box->set_visible_all (true);
00198     
00199         // when the box is activated, we set the entry as
00200         // focus object of the box
00201         box->set_focus_object(entry);
00202     
00203         image_list->add (box);
00204         image_list->set_default_object (box);
00205     
00206         num++;
00207     }
00208     else image_list->set_default_position (0);
00209 
00210     // If there are no saved games, display a message.
00211     if (!num) 
00212     {
00213         box = new win_container ();
00214         box->move(0, 0);
00215         box->resize(230, 150);
00216         
00217         win_label * mess = new win_label ();
00218         mess->set_font (*font); 
00219         mess->move (0, 65);
00220         mess->set_form (label::AUTO_SIZE); 
00221         mess->set_text ("You have no saved games yet!");
00222         mess->set_align (win_base::ALIGN_CENTER);  
00223         mess->pack ();
00224         box->add (mess); 
00225         
00226         mess = new win_label ();
00227         mess->set_font (*font); 
00228         mess->move (0, 115);
00229         mess->set_form (label::AUTO_SIZE); 
00230         mess->set_text ("Press ESC.");
00231         mess->set_align (win_base::ALIGN_CENTER);  
00232         mess->pack ();
00233         box->add (mess);
00234         
00235         box->set_visible_all (true);
00236         box->set_can_be_selected (false); 
00237  
00238         image_list->add (box); 
00239     }
00240 }
00241 
00242 bool data_screen::update ()
00243 {
00244     if (!win_container::update() || input::has_been_pushed (SDLK_ESCAPE))
00245     {
00246         aborted = true;
00247         data::engine->main_quit ();
00248     }
00249     
00250     return true;
00251 }
00252 
00253 // Select a game
00254 void data_screen::on_select ()
00255 {
00256     int pos = image_list->get_selected_position ();
00257     
00258     // loading
00259     if (mode == LOAD_SCREEN)
00260     {
00261         // fade to black before doing the actual work
00262         data::engine->fade_out ();
00263         set_visible (false);
00264         if (!gamedata::load (pos)) aborted = true;
00265         data::engine->main_quit ();
00266     }
00267     // saving
00268     else
00269     {
00270         win_container * tmp = (win_container*)image_list->get_selected_object();
00271         image_list->set_focus_object(tmp);
00272     
00273         entry = (win_write*) tmp->focus_object();
00274         entry->set_cursor_visible (true);
00275         entry->set_cursor_moveable (true);
00276     
00277         const char *txt = entry->text_char ();
00278         if (txt && !strncmp (txt, "Empty Slot", 10))
00279             entry->set_text ("");
00280   
00281         entry->set_signal_connect (makeFunctor (*this, &data_screen::on_save),
00282                    win_event::ACTIVATE_KEY);
00283         entry->set_activate (true);
00284         input::clear_keys_queue ();
00285     }
00286 }
00287 
00288 void data_screen::on_save ()
00289 {
00290     const char* description = entry->text_char ();
00291     int pos = image_list->get_selected_position ();
00292 
00293     gamedata::save (pos, description, gametime);
00294     gamedata *gdata = gamedata::get_saved_game (pos);
00295 
00296     // save sucessful --> save preview
00297     if (gdata != NULL)
00298     {
00299         string filepath = gdata->directory ();
00300         filepath += "/preview.pnm";
00301         save_preview (filepath);
00302     }
00303     
00304     data::engine->main_quit ();
00305 }
00306 
00307 // Save the small thumbnail image
00308 void data_screen::save_preview (string path)
00309 {
00310     drawing_area da (0, 0, screen::length () >> 1, screen::height () >> 1);
00311     image temp (da.length (), da.height());
00312     image preview (72, 54);
00313 
00314     mapview *view = data::engine->get_mapview ();
00315     mapsquare_area *area = data::engine->get_landmap ()->get_submap
00316         (data::the_player->submap ());
00317 
00318     u_int16 offx = 0;
00319     u_int16 offy = 0;
00320 
00321     // In those cases where the mapview is smaller than the physical screen,
00322     // it will be centered on the screen -> get the offset
00323     if (area->area_length () * MAPSQUARE_SIZE < view->length ())
00324         offx = (view->length () - area->area_length () * MAPSQUARE_SIZE) >> 1;
00325     if (area->area_height () * MAPSQUARE_SIZE < view->height ())
00326         offy = (view->height () - area->area_height () * MAPSQUARE_SIZE) >> 1;
00327 
00328     // Calculate the player's absolute position on the screen
00329     s_int16 x = (data::the_player->posx () - view->posx ()) * MAPSQUARE_SIZE + offx;
00330     s_int16 y = (data::the_player->posy () - view->posy ()) * MAPSQUARE_SIZE + offy;
00331 
00332     // this is a quarter of the screen's size.
00333     u_int16 length = da.length() >> 1;
00334     u_int16 height = da.height() >> 1;
00335 
00336     // If the player is too close to the border, make sure we still stay
00337     // within the screen
00338     if (x + length > screen::length ()) x = -da.length ();
00339     else if (x - length < 0) x = 0;
00340     else x = length - x;
00341 
00342     if (y + height > screen::height ()) y = -da.height ();
00343     else if (y - height < 0) y = 0;
00344     else y = height - y;
00345 
00346     data::engine->draw (x, y, &da, &temp);
00347     preview.zoom (temp); 
00348     preview.save_pnm (path);     
00349 }