diff --git a/Makefile b/Makefile index c4dd72b05..fef039b17 100644 --- a/Makefile +++ b/Makefile @@ -313,6 +313,7 @@ SOURCES += finder/placefinder.cc SOURCES += freight_list_sorter.cc SOURCES += gui/ai_option_t.cc SOURCES += gui/ai_selector.cc +SOURCES += gui/alert_dialog.cc SOURCES += gui/banner.cc SOURCES += gui/base_info.cc SOURCES += gui/baum_edit.cc diff --git a/gui/alert_dialog.cc b/gui/alert_dialog.cc new file mode 100644 index 000000000..a797017cd --- /dev/null +++ b/gui/alert_dialog.cc @@ -0,0 +1,62 @@ +#include "alert_dialog.h" + +#include "../simskin.h" +#include "../dataobj/translator.h" +#include "../descriptor/skin_desc.h" +#include "components/gui_image.h" + +alert_dialog::alert_dialog(const char* title, const char* text, player_t* player) : + base_infowin_t(translator::translate(title), player) { + // text and image + buf.append(translator::translate(text)); + image_id id = skinverwaltung_t::meldungsymbol->get_image_id(0); + image.set_image(id, true); + image.enable_offset_removal(true); + image.set_size(image.get_min_size()); + set_embedded(&image); +} + +alert_dialog::~alert_dialog() { + FOR(vector_tpl, &i, items) { + delete(i.button); + } +} + +void alert_dialog::add_item(const char* text, PIXVAL text_color) { + items.append({new button_t(), text, text_color}); +} + +void alert_dialog::end_item() { + add_table(items.get_count(), 1); + FOR(vector_tpl, &i, items) { + i.button->init(button_t::roundbox_state | button_t::flexible, i.text); + i.button->text_color = i.text_color; + i.button->add_listener(this); + add_component(i.button); + } + recalc_size(); +} + +bool alert_dialog::action_triggered(gui_action_creator_t* comp, value_t) { + FOR(vector_tpl, &i, items) { + if( i.button==comp ) { + call_listeners(i.text); + break; + } + } + return true; +} + + +confirmation_dialog::confirmation_dialog(const char* title, const char* text, player_t* player) : alert_dialog(title, text, player){ + // append "cancel" and "OK" buttons + add_item("cancel", SYSCOL_BUTTON_TEXT); + add_item("OK", color_idx_to_rgb(COL_RED)); + end_item(); +} + +bool confirmation_dialog::action_triggered(gui_action_creator_t* comp, value_t) { + // send true only when "OK" button pressed. + call_listeners(comp==items[1].button); + return true; +} diff --git a/gui/alert_dialog.h b/gui/alert_dialog.h new file mode 100644 index 000000000..a4ce783e1 --- /dev/null +++ b/gui/alert_dialog.h @@ -0,0 +1,58 @@ +/* + * This file is part of the Simutrans project under the Artistic License. + * (see LICENSE.txt) + */ + +#ifndef GUI_ALERT_DIALOG_H +#define GUI_ALERT_DIALOG_H + + +#include "base_info.h" +#include "components/gui_image.h" +#include "../simcolor.h" +#include "../dataobj/environment.h" + +class button_t; + +/** + * A dialog to show an alert + * passes the text pointer of the pressed button. + */ +class alert_dialog : public base_infowin_t, public gui_action_creator_t, public action_listener_t +{ +public: + alert_dialog(const char* title, const char* text, player_t* player = NULL); + ~alert_dialog(); + + void add_item(const char* text, PIXVAL text_color = SYSCOL_BUTTON_TEXT); + void end_item(); // call this after adding all items + +protected: + typedef struct{ + button_t* button; + const char* text; + PIXVAL text_color; + } item_t; + + vector_tpl items; + + bool action_triggered(gui_action_creator_t*, value_t) OVERRIDE; + +private: + gui_image_t image; + +}; + +/** + * Typical alert dialog which has only "OK" and "cancel" items. + * It passes true when "OK" is pressed. Otherwise, it passes false. + */ +class confirmation_dialog : public alert_dialog { +public: + confirmation_dialog(const char* title, const char* text, player_t* player = NULL); + +private: + bool action_triggered(gui_action_creator_t*, value_t) OVERRIDE; +}; + +#endif diff --git a/gui/convoi_detail_t.cc b/gui/convoi_detail_t.cc index 6042133ab..b4ad8fb8d 100644 --- a/gui/convoi_detail_t.cc +++ b/gui/convoi_detail_t.cc @@ -9,6 +9,7 @@ #include "components/gui_divider.h" #include "components/gui_image.h" #include "components/gui_textarea.h" +#include "simwin.h" #include "../simconvoi.h" #include "../vehicle/simvehicle.h" @@ -137,6 +138,15 @@ convoi_detail_t::convoi_detail_t(convoihandle_t cnv) } } + +convoi_detail_t::~convoi_detail_t() { + // destory existing confirmation dialog + if( sale_confirmation ) { + destroy_win(sale_confirmation); + } +} + + void convoi_detail_t::init(convoihandle_t cnv) { this->cnv = cnv; @@ -225,17 +235,27 @@ void convoi_detail_t::draw(scr_coord offset) /** * This method is called if an action is triggered */ -bool convoi_detail_t::action_triggered(gui_action_creator_t *comp,value_t /* */) +bool convoi_detail_t::action_triggered(gui_action_creator_t *comp,value_t v) { if(cnv.is_bound()) { if(comp==&sale_button) { - cnv->call_convoi_tool( 'x', NULL ); + sale_confirmation = new confirmation_dialog("Sale Confirmation", "Do you want to sell the convoy immediately?", cnv->get_owner()); + sale_confirmation->add_listener(this); + create_win(sale_confirmation, w_info, (ptrdiff_t)this); return true; } else if(comp==&withdraw_button) { cnv->call_convoi_tool( 'w', NULL ); return true; } + else if(comp==sale_confirmation) { + destroy_win(sale_confirmation); + sale_confirmation = NULL; + if( v.i ) { + cnv->call_convoi_tool( 'x', NULL ); + return true; + } + } } return false; } diff --git a/gui/convoi_detail_t.h b/gui/convoi_detail_t.h index 422ee3fa3..e032ab7dd 100644 --- a/gui/convoi_detail_t.h +++ b/gui/convoi_detail_t.h @@ -13,6 +13,7 @@ #include "components/gui_label.h" #include "components/action_listener.h" #include "../convoihandle_t.h" +#include "alert_dialog.h" class scr_coord; class karte_ptr_t; @@ -30,6 +31,7 @@ private: gui_aligned_container_t container; gui_scrollpane_t scrolly; + confirmation_dialog* sale_confirmation; gui_label_buf_t label_power, label_odometer, label_resale, label_length, label_speed; @@ -40,6 +42,8 @@ private: static karte_ptr_t welt; public: convoi_detail_t(convoihandle_t cnv = convoihandle_t()); + + ~convoi_detail_t(); /** * Initializes layout, @p cnv needs to be valid.