new buttons and logic to navigate story screen,
...allowing back an forth, patch #1587 by icelus
This commit is contained in:
parent
e6566fa8dd
commit
cc5330c08c
9 changed files with 306 additions and 69 deletions
|
@ -120,6 +120,7 @@ Version 1.9.0-svn:
|
|||
* Clicking on some elements of sidebar now open the related help page
|
||||
* Display weapon stats in recruit/recall dialog the same way as in sidebar
|
||||
* Accuracy/parry have its own line and tooltip in sidebar.
|
||||
* Add first, last, play and back buttons to storyscreens
|
||||
* Units:
|
||||
* Giant Rat moved from DiD to core.
|
||||
* WML Engine:
|
||||
|
|
|
@ -107,6 +107,8 @@ public:
|
|||
|
||||
child_iterator &operator++() { ++i_; return *this; }
|
||||
child_iterator operator++(int) { return child_iterator(i_++); }
|
||||
child_iterator &operator--() { --i_; return *this; }
|
||||
child_iterator operator--(int) { return child_iterator(i_--); }
|
||||
|
||||
config &operator*() const { return **i_; }
|
||||
config *operator->() const { return &**i_; }
|
||||
|
@ -132,6 +134,8 @@ public:
|
|||
|
||||
const_child_iterator &operator++() { ++i_; return *this; }
|
||||
const_child_iterator operator++(int) { return const_child_iterator(i_++); }
|
||||
const_child_iterator &operator--() { --i_; return *this; }
|
||||
const_child_iterator operator--(int) { return const_child_iterator(i_--); }
|
||||
|
||||
const config &operator*() const { return **i_; }
|
||||
const config *operator->() const { return &**i_; }
|
||||
|
|
|
@ -290,9 +290,11 @@ LEVEL_RESULT playsingle_controller::play_scenario(
|
|||
sound::commit_music_changes();
|
||||
|
||||
if(!skip_replay) {
|
||||
foreach (const config &s, story) {
|
||||
show_storyscreen(*gui_, vconfig(s, true), level_["name"]);
|
||||
storyscreen::STORY_RESULT result = show_story(*gui_, level_["name"], story);
|
||||
if(result == storyscreen::QUIT) {
|
||||
return QUIT;
|
||||
}
|
||||
assert(result == storyscreen::NEXT);
|
||||
}
|
||||
gui_->labels().read(level_);
|
||||
|
||||
|
|
|
@ -42,12 +42,15 @@ static lg::log_domain log_engine("engine");
|
|||
|
||||
namespace storyscreen {
|
||||
|
||||
controller::controller(display& disp, const vconfig& data, const std::string& scenario_name)
|
||||
controller::controller(display& disp, const vconfig& data, const std::string& scenario_name,
|
||||
int segment_index, int total_segments)
|
||||
: disp_(disp)
|
||||
, disp_resize_lock_()
|
||||
, evt_context_()
|
||||
, data_(data)
|
||||
, scenario_name_(scenario_name)
|
||||
, segment_index_(segment_index)
|
||||
, total_segments_(total_segments)
|
||||
, parts_()
|
||||
{
|
||||
ASSERT_LOG(resources::state_of_game != NULL, "Ouch: gamestate is NULL when initializing storyscreen controller");
|
||||
|
@ -120,17 +123,18 @@ void controller::resolve_wml(const vconfig& cfg)
|
|||
}
|
||||
}
|
||||
|
||||
void controller::show()
|
||||
STORY_RESULT controller::show(START_POSITION startpos)
|
||||
{
|
||||
if(parts_.empty()) {
|
||||
LOG_NG << "no storyscreen parts to show\n";
|
||||
return;
|
||||
return NEXT;
|
||||
}
|
||||
|
||||
gui::button next_button(disp_.video(),_("Next") + std::string(" >"));
|
||||
gui::button skip_button(disp_.video(),_("Skip"));
|
||||
// TODO:
|
||||
// gui::button back_button(disp_.video(),std::string("< ")+_("Next"));
|
||||
gui::button first_button(disp_.video(),_("First") + std::string(" <<"));
|
||||
gui::button last_button (disp_.video(),std::string(">> ") + _("Last"));
|
||||
gui::button back_button (disp_.video(),std::string("< ")+ _("Back"));
|
||||
gui::button next_button (disp_.video(),_("Next") + std::string(" >"));
|
||||
gui::button play_button (disp_.video(),_("Play") + std::string(" >"));
|
||||
|
||||
// Build renderer cache unless built for a low-memory environment;
|
||||
// caching the scaled backgrounds can take over a decent amount of memory.
|
||||
|
@ -138,39 +142,83 @@ void controller::show()
|
|||
std::vector< render_pointer_type > uis_;
|
||||
foreach(part_pointer_type p, parts_) {
|
||||
ASSERT_LOG( p != NULL, "Ouch: hit NULL storyscreen part in collection" );
|
||||
render_pointer_type const rpt(new part_ui(*p, disp_, next_button, skip_button));
|
||||
render_pointer_type const rpt(new part_ui(*p, disp_, next_button, back_button, first_button, last_button, play_button));
|
||||
uis_.push_back(rpt);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t k = 0;
|
||||
switch(startpos) {
|
||||
case START_BEGINNING:
|
||||
break;
|
||||
case START_END:
|
||||
k = parts_.size() -1;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
while(k < parts_.size()) {
|
||||
#ifndef LOW_MEM
|
||||
render_reference_type render_interface = *uis_[k];
|
||||
#else
|
||||
render_value_type render_interface(*parts_[k], disp_, next_button, skip_button);
|
||||
render_value_type render_interface(*parts_[k], disp_, next_button, back_button, first_button, last_button, play_button);
|
||||
#endif
|
||||
|
||||
LOG_NG << "displaying storyscreen part " << k+1 << " of " << parts_.size() << '\n';
|
||||
|
||||
const bool first_page = (segment_index_ == 0) && (k == 0);
|
||||
const bool last_page = (segment_index_ == total_segments_ - 1) && (k == parts_.size() - 1);
|
||||
|
||||
first_button.hide(first_page);
|
||||
back_button.hide(first_page);
|
||||
last_button.hide(last_page);
|
||||
next_button.hide(false);
|
||||
play_button.hide(!last_page);
|
||||
|
||||
switch(render_interface.show()) {
|
||||
case part_ui::NEXT:
|
||||
++k;
|
||||
break;
|
||||
case part_ui::BACK:
|
||||
// If we are at the first page we can't go back.
|
||||
if(k > 0) {
|
||||
--k;
|
||||
}
|
||||
else if(segment_index_ > 0) {
|
||||
return BACK;
|
||||
}
|
||||
break;
|
||||
case part_ui::SKIP:
|
||||
k = parts_.size();
|
||||
case part_ui::FIRST:
|
||||
if(segment_index_ == 0) {
|
||||
// this is the first segment
|
||||
k = 0;
|
||||
}
|
||||
else {
|
||||
// we want to rewind all the way
|
||||
// to the last segment
|
||||
return FIRST;
|
||||
}
|
||||
break;
|
||||
case part_ui::LAST:
|
||||
if(segment_index_ == total_segments_ - 1) {
|
||||
// not at the end of this segment
|
||||
k = parts_.size() - 1;
|
||||
}
|
||||
else {
|
||||
// we want to fast forward all the way
|
||||
// to the last segment
|
||||
return LAST;
|
||||
}
|
||||
break;
|
||||
case part_ui::QUIT:
|
||||
return QUIT;
|
||||
default:
|
||||
throw quit();
|
||||
assert(false);
|
||||
return QUIT;
|
||||
}
|
||||
}
|
||||
return NEXT;
|
||||
}
|
||||
|
||||
} // end namespace storyscreen
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define STORYSCREEN_CONTROLLER_HPP_INCLUDED
|
||||
|
||||
#include "events.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "variable.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
|
@ -39,12 +40,13 @@ class floating_image;
|
|||
class controller
|
||||
{
|
||||
public:
|
||||
controller(display& disp, const vconfig& data, const std::string& scenario_name);
|
||||
|
||||
controller(display& disp, const vconfig& data, const std::string& scenario_name,
|
||||
int segment_index, int total_segments);
|
||||
|
||||
/**
|
||||
* Display all story screen parts in a first..last sequence.
|
||||
*/
|
||||
void show();
|
||||
STORY_RESULT show(START_POSITION startpos=START_BEGINNING);
|
||||
|
||||
private:
|
||||
typedef boost::shared_ptr< part > part_pointer_type;
|
||||
|
@ -67,14 +69,14 @@ private:
|
|||
|
||||
vconfig data_;
|
||||
std::string scenario_name_;
|
||||
int segment_index_;
|
||||
int total_segments_;
|
||||
|
||||
// The part cache.
|
||||
std::vector< part_pointer_type > parts_;
|
||||
|
||||
public:
|
||||
struct no_parts {};
|
||||
struct quit {};
|
||||
|
||||
};
|
||||
|
||||
} // end namespace storyscreen
|
||||
|
|
|
@ -45,22 +45,81 @@ namespace {
|
|||
config& partcfg = append_to_cfg.add_child("story").add_child("part");
|
||||
partcfg["text_align"] = "centered";
|
||||
}
|
||||
|
||||
int count_segments(const config::const_child_itors &story)
|
||||
{
|
||||
config::const_child_iterator itor = story.first;
|
||||
int count = 0;
|
||||
while(itor != story.second) {
|
||||
++itor;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
void show_storyscreen(display& disp, const vconfig& story_cfg, const std::string& scenario_name)
|
||||
|
||||
storyscreen::STORY_RESULT show_story(display& disp,
|
||||
const std::string& scenario_name,
|
||||
const config::const_child_itors &story) {
|
||||
const int total_segments = count_segments(story);
|
||||
int segment_count = 0;
|
||||
config::const_child_iterator itor = story.first;
|
||||
storyscreen::START_POSITION startpos = storyscreen::START_BEGINNING;
|
||||
while(itor != story.second) {
|
||||
storyscreen::STORY_RESULT result = show_storyscreen(disp, vconfig(*itor, true), scenario_name,
|
||||
startpos, segment_count, total_segments);
|
||||
switch(result) {
|
||||
case storyscreen::NEXT:
|
||||
if(itor != story.second) {
|
||||
++itor;
|
||||
++segment_count;
|
||||
startpos = storyscreen::START_BEGINNING;
|
||||
}
|
||||
break;
|
||||
case storyscreen::BACK:
|
||||
if(itor != story.first) {
|
||||
--itor;
|
||||
--segment_count;
|
||||
startpos = storyscreen::START_END;
|
||||
}
|
||||
break;
|
||||
case storyscreen::LAST:
|
||||
itor = story.second;
|
||||
--itor;
|
||||
segment_count = total_segments - 1;
|
||||
startpos = storyscreen::START_END;
|
||||
break;
|
||||
case storyscreen::FIRST:
|
||||
itor = story.first;
|
||||
segment_count = 0;
|
||||
startpos = storyscreen::START_BEGINNING;
|
||||
break;
|
||||
case storyscreen::QUIT:
|
||||
return storyscreen::QUIT;
|
||||
default:
|
||||
assert(false);
|
||||
itor = story.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return storyscreen::NEXT;
|
||||
}
|
||||
|
||||
storyscreen::STORY_RESULT show_storyscreen(display& disp, const vconfig& story_cfg,
|
||||
const std::string& scenario_name,
|
||||
storyscreen::START_POSITION startpos,
|
||||
int segment_index, int total_segments)
|
||||
{
|
||||
LOG_NG << "entering storyscreen procedure...\n";
|
||||
|
||||
storyscreen::controller ctl(disp, story_cfg, scenario_name);
|
||||
storyscreen::controller ctl(disp, story_cfg, scenario_name, segment_index, total_segments);
|
||||
|
||||
try {
|
||||
ctl.show();
|
||||
} catch(storyscreen::controller::quit const&) {
|
||||
LOG_NG << "leaving storyscreen for titlescreen...\n";
|
||||
STUB();
|
||||
}
|
||||
storyscreen::STORY_RESULT ret = ctl.show(startpos);
|
||||
|
||||
LOG_NG << "leaving storyscreen procedure...\n";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void show_endscreen(display& /*disp*/, const t_string& /*text*/, unsigned int /*duration*/)
|
||||
|
|
|
@ -20,15 +20,33 @@
|
|||
#ifndef STORYSCREEN_HPP_INCLUDED
|
||||
#define STORYSCREEN_HPP_INCLUDED
|
||||
|
||||
class config;
|
||||
#include <string>
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
class vconfig;
|
||||
class display;
|
||||
class t_string;
|
||||
|
||||
#include <string>
|
||||
namespace storyscreen {
|
||||
|
||||
enum STORY_RESULT {
|
||||
NEXT,
|
||||
BACK,
|
||||
FIRST,
|
||||
LAST,
|
||||
QUIT
|
||||
};
|
||||
|
||||
enum START_POSITION {
|
||||
START_BEGINNING,
|
||||
START_END
|
||||
};
|
||||
|
||||
} /* storyscreen namespace */
|
||||
|
||||
/**
|
||||
* Function to show an introduction sequence using story WML.
|
||||
* Function to show an introduction sequence segment using story WML.
|
||||
* The WML config data (story_cfg) has a format similar to:
|
||||
* @code
|
||||
* [part]
|
||||
|
@ -41,9 +59,19 @@ class t_string;
|
|||
* storyline,and 'img' is a background image. Each part of the sequence will
|
||||
* be displayed in turn, with the user able to go to the next part, or skip
|
||||
* it entirely.
|
||||
* @return is NEXT if the segment played to the end, BACK if the segment played to the beginning,
|
||||
* FIRST if a skip to the first segment is requested, LAST if a skip to the last segment is requested,
|
||||
* and QUIT if the story was quit
|
||||
*/
|
||||
void show_storyscreen(display& disp, const vconfig& story_cfg, const std::string& scenario_name);
|
||||
|
||||
storyscreen::STORY_RESULT show_storyscreen(display& disp, const vconfig& story_cfg,
|
||||
const std::string& scenario_name,
|
||||
storyscreen::START_POSITION startpos,
|
||||
int segment_index, int total_segments);
|
||||
/**
|
||||
* Function to show a complete introduction sequence using story WML (calls show_storyscreen, see there for format).
|
||||
* @return is NEXT if the story played to the end and QUIT if the story was quit
|
||||
*/
|
||||
storyscreen::STORY_RESULT show_story(display& disp, const std::string& scenario_name, const config::const_child_itors &story);
|
||||
/**
|
||||
* Displays a simple fading screen with any user-provided text.
|
||||
* Used after the end of single-player campaigns.
|
||||
|
|
|
@ -81,13 +81,19 @@ namespace {
|
|||
|
||||
namespace storyscreen {
|
||||
|
||||
part_ui::part_ui(part& p, display& disp, gui::button& next_button, gui::button& skip_button)
|
||||
part_ui::part_ui(part& p, display& disp,
|
||||
gui::button& next_button, gui::button& back_button,
|
||||
gui::button& first_button, gui::button& last_button,
|
||||
gui::button& play_button)
|
||||
: p_(p)
|
||||
, disp_(disp)
|
||||
, video_(disp.video())
|
||||
, keys_()
|
||||
, next_button_(next_button)
|
||||
, skip_button_(skip_button)
|
||||
, back_button_(back_button)
|
||||
, first_button_(first_button)
|
||||
, last_button_(last_button)
|
||||
, play_button_(play_button)
|
||||
, ret_(NEXT)
|
||||
, scale_factor_(1.0)
|
||||
, base_rect_()
|
||||
|
@ -139,8 +145,11 @@ void part_ui::prepare_geometry()
|
|||
buttons_x_ = video_.getx() - 50;
|
||||
buttons_y_ = base_rect_.y + base_rect_.h - 20;
|
||||
|
||||
next_button_.set_location(buttons_x_, buttons_y_ - 20);
|
||||
skip_button_.set_location(buttons_x_, buttons_y_);
|
||||
next_button_.set_location(buttons_x_, buttons_y_ - 60);
|
||||
back_button_.set_location(buttons_x_, buttons_y_ - 40);
|
||||
first_button_.set_location(buttons_x_, buttons_y_ - 20);
|
||||
last_button_.set_location(buttons_x_, buttons_y_);
|
||||
play_button_.set_location(buttons_x_, buttons_y_);
|
||||
|
||||
#else // elif !defined(USE_TINY_GUI)
|
||||
|
||||
|
@ -163,12 +172,18 @@ void part_ui::prepare_geometry()
|
|||
buttons_y_ = video_.gety() - 40;
|
||||
break;
|
||||
}
|
||||
next_button_.set_location(buttons_x_, buttons_y_ - 30);
|
||||
skip_button_.set_location(buttons_x_, buttons_y_);
|
||||
next_button_.set_location(buttons_x_, buttons_y_ - 90);
|
||||
back_button_.set_location(buttons_x_, buttons_y_ - 60);
|
||||
first_button_.set_location(buttons_x_, buttons_y_ - 30);
|
||||
last_button_.set_location(buttons_x_, buttons_y_);
|
||||
play_button_.set_location(buttons_x_, buttons_y_);
|
||||
#endif
|
||||
|
||||
next_button_.set_volatile(true);
|
||||
skip_button_.set_volatile(true);
|
||||
play_button_.set_volatile(true);
|
||||
back_button_.set_volatile(true);
|
||||
first_button_.set_volatile(true);
|
||||
last_button_.set_volatile(true);
|
||||
}
|
||||
|
||||
void part_ui::prepare_floating_images()
|
||||
|
@ -194,6 +209,7 @@ bool part_ui::render_floating_images()
|
|||
update_whole_screen();
|
||||
|
||||
bool skip = false;
|
||||
bool last_key = true;
|
||||
|
||||
size_t fi_n = 0;
|
||||
foreach(floating_image::render_input& ri, imgs_) {
|
||||
|
@ -206,14 +222,30 @@ bool part_ui::render_floating_images()
|
|||
|
||||
if(skip == false) {
|
||||
for(unsigned i = 0; i != 50; ++i) {
|
||||
if(keys_[SDLK_ESCAPE] || skip_button_.pressed()) {
|
||||
ret_ = SKIP;
|
||||
const bool next_keydown = keys_[SDLK_SPACE] || keys_[SDLK_RETURN] || keys_[SDLK_KP_ENTER] || keys_[SDLK_RIGHT];
|
||||
const bool play_keydown = keys_[SDLK_ESCAPE] && !play_button_.hidden();
|
||||
const bool last_keydown = (keys_[SDLK_ESCAPE] && play_button_.hidden()) || keys_[SDLK_END] || keys_[SDLK_DOWN];
|
||||
const bool first_keydown = keys_[SDLK_HOME] || keys_[SDLK_UP];
|
||||
const bool back_keydown = keys_[SDLK_BACKSPACE] || keys_[SDLK_LEFT];
|
||||
|
||||
if((last_keydown && !last_key) || last_button_.pressed()) {
|
||||
ret_ = LAST;
|
||||
return false;
|
||||
}
|
||||
else if(next_button_.pressed()) {
|
||||
else if((first_keydown && !last_key) || first_button_.pressed()) {
|
||||
ret_ = FIRST;
|
||||
return false;
|
||||
}
|
||||
else if(((next_keydown || play_keydown) && !last_key) || next_button_.pressed() || play_button_.pressed()) {
|
||||
ret_ = NEXT;
|
||||
return false;
|
||||
}
|
||||
else if((back_keydown && !last_key) || back_button_.pressed()) {
|
||||
ret_ = BACK;
|
||||
return false;
|
||||
}
|
||||
|
||||
last_key = next_keydown || play_keydown || last_keydown || first_keydown || back_keydown;
|
||||
|
||||
disp_.delay(fi.display_delay() / 50);
|
||||
|
||||
|
@ -238,7 +270,10 @@ bool part_ui::render_floating_images()
|
|||
}
|
||||
}
|
||||
|
||||
if(keys_[SDLK_ESCAPE] || next_button_.pressed() || skip_button_.pressed()) {
|
||||
if(keys_[SDLK_ESCAPE] ||
|
||||
next_button_.pressed() || back_button_.pressed() ||
|
||||
first_button_.pressed() || last_button_.pressed() ||
|
||||
play_button_.pressed()) {
|
||||
skip = true;
|
||||
++fi_n;
|
||||
continue;
|
||||
|
@ -372,6 +407,8 @@ void part_ui::render_story_box_borders(SDL_Rect& update_area)
|
|||
|
||||
void part_ui::render_story_box()
|
||||
{
|
||||
LOG_NG << "ENTER part_ui()::render_story_box()\n";
|
||||
|
||||
const std::string& storytxt = p_.text();
|
||||
if(storytxt.empty()) {
|
||||
wait_for_input();
|
||||
|
@ -429,10 +466,17 @@ void part_ui::render_story_box()
|
|||
// by the buttons being hidden and unhidden in this scope.
|
||||
update_locker locker(video_);
|
||||
|
||||
//back_button_.hide();
|
||||
const bool next_hidden = next_button_.hidden();
|
||||
const bool back_hidden = back_button_.hidden();
|
||||
const bool play_hidden = play_button_.hidden();
|
||||
const bool first_hidden = first_button_.hidden();
|
||||
const bool last_hidden = last_button_.hidden();
|
||||
|
||||
next_button_.hide();
|
||||
skip_button_.hide();
|
||||
//quit_button_.hide();
|
||||
back_button_.hide();
|
||||
first_button_.hide();
|
||||
last_button_.hide();
|
||||
play_button_.hide();
|
||||
|
||||
#ifndef LOW_MEM
|
||||
blur_area(video_, fix_text_y, fix_text_h);
|
||||
|
@ -449,9 +493,15 @@ void part_ui::render_story_box()
|
|||
|
||||
// Make GUI1 buttons aware of background modifications
|
||||
next_button_.set_location(next_button_.location());
|
||||
next_button_.hide(false);
|
||||
skip_button_.set_location(skip_button_.location());
|
||||
skip_button_.hide(false);
|
||||
next_button_.hide(next_hidden);
|
||||
back_button_.set_location(back_button_.location());
|
||||
back_button_.hide(back_hidden);
|
||||
first_button_.set_location(first_button_.location());
|
||||
first_button_.hide(first_hidden);
|
||||
last_button_.set_location(last_button_.location());
|
||||
last_button_.hide(last_hidden);
|
||||
play_button_.set_location(play_button_.location());
|
||||
play_button_.hide(play_hidden);
|
||||
}
|
||||
|
||||
if(imgs_.empty()) {
|
||||
|
@ -478,10 +528,15 @@ void part_ui::render_story_box()
|
|||
update_rect(dstrect);
|
||||
++scan.y;
|
||||
}
|
||||
next_button_.hide(next_button_.hidden() || (scan_finished && last_button_.hidden()));
|
||||
|
||||
const bool keydown = keys_[SDLK_SPACE] || keys_[SDLK_RETURN] || keys_[SDLK_KP_ENTER];
|
||||
const bool next_keydown = keys_[SDLK_SPACE] || keys_[SDLK_RETURN] || keys_[SDLK_KP_ENTER] || keys_[SDLK_RIGHT];
|
||||
const bool back_keydown = keys_[SDLK_BACKSPACE] || keys_[SDLK_LEFT];
|
||||
const bool play_keydown = keys_[SDLK_ESCAPE] && !play_button_.hidden();
|
||||
const bool last_keydown = (keys_[SDLK_ESCAPE] && play_button_.hidden()) || keys_[SDLK_END] || keys_[SDLK_DOWN];
|
||||
const bool first_keydown = keys_[SDLK_HOME] || keys_[SDLK_UP];
|
||||
|
||||
if((keydown && !last_key) || next_button_.pressed()) {
|
||||
if((next_keydown && !last_key) || next_button_.pressed()) {
|
||||
if(skip == true || scan_finished) {
|
||||
ret_ = NEXT;
|
||||
break;
|
||||
|
@ -490,13 +545,28 @@ void part_ui::render_story_box()
|
|||
}
|
||||
}
|
||||
|
||||
last_key = keydown;
|
||||
if((play_keydown && !last_key) || play_button_.pressed()) {
|
||||
ret_ = NEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
if(keys_[SDLK_ESCAPE] || skip_button_.pressed()) {
|
||||
ret_ = SKIP;
|
||||
if((back_keydown && !last_key) || back_button_.pressed()) {
|
||||
ret_ = BACK;
|
||||
break;
|
||||
}
|
||||
|
||||
if((last_keydown && !last_key) || last_button_.pressed()) {
|
||||
ret_ = LAST;
|
||||
return;
|
||||
}
|
||||
|
||||
if((first_keydown && !last_key) || first_button_.pressed()) {
|
||||
ret_ = FIRST;
|
||||
return;
|
||||
}
|
||||
|
||||
last_key = next_keydown || back_keydown || play_keydown || last_keydown || first_keydown;
|
||||
|
||||
events::pump();
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
@ -515,22 +585,40 @@ void part_ui::render_story_box()
|
|||
|
||||
void part_ui::wait_for_input()
|
||||
{
|
||||
bool last_key = true;
|
||||
while(true) {
|
||||
const bool keydown = keys_[SDLK_SPACE] || keys_[SDLK_RETURN] || keys_[SDLK_KP_ENTER];
|
||||
LOG_NG << "ENTER part_ui()::wait_for_input()\n";
|
||||
|
||||
if((keydown && !last_key) || next_button_.pressed()) {
|
||||
bool last_key = true;
|
||||
next_button_.hide(next_button_.hidden() || last_button_.hidden());
|
||||
while(true) {
|
||||
const bool next_keydown = keys_[SDLK_SPACE] || keys_[SDLK_RETURN] || keys_[SDLK_KP_ENTER] || keys_[SDLK_RIGHT];
|
||||
const bool play_keydown = keys_[SDLK_ESCAPE] && !play_button_.hidden();
|
||||
const bool last_keydown = (keys_[SDLK_ESCAPE] && play_button_.hidden()) || keys_[SDLK_END] || keys_[SDLK_DOWN];
|
||||
const bool first_keydown = keys_[SDLK_HOME] || keys_[SDLK_UP];
|
||||
const bool back_keydown = keys_[SDLK_BACKSPACE] || keys_[SDLK_LEFT];
|
||||
|
||||
if(((next_keydown || play_keydown) && !last_key) || next_button_.pressed() || play_button_.pressed()) {
|
||||
ret_ = NEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
if((back_keydown && !last_key) || back_button_.pressed()) {
|
||||
ret_ = BACK;
|
||||
break;
|
||||
}
|
||||
|
||||
last_key = keydown;
|
||||
|
||||
if(keys_[SDLK_ESCAPE] || skip_button_.pressed()) {
|
||||
ret_ = SKIP;
|
||||
if((last_keydown && !last_key) || last_button_.pressed()) {
|
||||
ret_ = LAST;
|
||||
return;
|
||||
}
|
||||
|
||||
if((first_keydown && !last_key) || first_button_.pressed()) {
|
||||
ret_ = FIRST;
|
||||
return;
|
||||
}
|
||||
|
||||
last_key = next_keydown || back_keydown || first_keydown || last_keydown || play_keydown;
|
||||
|
||||
events::pump();
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
|
|
@ -45,9 +45,10 @@ public:
|
|||
/** Storyscreen result. */
|
||||
enum RESULT {
|
||||
NEXT, /**< The user pressed the go-next button. */
|
||||
BACK, /**< The user pressed the go-back button (TODO: not implemented). */
|
||||
SKIP, /**< The user pressed the skip button. */
|
||||
QUIT /**< The user pressed the quit button (TODO: not implemented). */
|
||||
BACK, /**< The user pressed the go-back button. */
|
||||
FIRST, /**< The user pressed the go-first button. */
|
||||
LAST, /**< The user pressed the go-last button. */
|
||||
QUIT /**< The user selected quit. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -57,7 +58,10 @@ public:
|
|||
* @param next_button Next button. Shouldn't be destroyed before the part_ui object.
|
||||
* @param skip_button Skip button. Shouldn't be destroyed before the part_ui object.
|
||||
*/
|
||||
part_ui(part& p, display& disp, gui::button& next_button, gui::button& skip_button);
|
||||
part_ui(part& p, display& disp,
|
||||
gui::button& next_button, gui::button& back_button,
|
||||
gui::button& first_button, gui::button& last_button,
|
||||
gui::button& play_button);
|
||||
|
||||
/**
|
||||
* Render and display the storyscreen, process and return user input.
|
||||
|
@ -70,10 +74,11 @@ private:
|
|||
CVideo& video_; // convenience, it's currently obtained from disp_
|
||||
CKey keys_; // convenience
|
||||
|
||||
//gui::button& back_button_;
|
||||
gui::button& next_button_;
|
||||
gui::button& skip_button_;
|
||||
//gui::button& quit_button_;
|
||||
gui::button& back_button_;
|
||||
gui::button& first_button_;
|
||||
gui::button& last_button_;
|
||||
gui::button& play_button_;
|
||||
|
||||
RESULT ret_;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue