Merge pull request #251 from x-qq/fix_scrollbar_segfaults
fix for scrollbar segfaults * fixes #206 * fixes broken mousewheel scrolling of the scenedit palette * removed boost threads dependency * added foundation for further refactoring of the drawing and event handling code: interfaces and drawable manager with layering * removed a bunch of unneeded redraw calls * removed some repeated recalculation of effectively constant values (boe.actions) * removed recalculation of effectively constant scrollbar and button positions (boe.graphics) Closes #251
This commit is contained in:
@@ -62,6 +62,10 @@ void cScrollbar::setStyle(eScrollStyle newStyle) {
|
||||
style = newStyle;
|
||||
}
|
||||
|
||||
void cScrollbar::set_wheel_event_rect(rectangle rect) {
|
||||
this->wheel_event_rect = rect;
|
||||
}
|
||||
|
||||
long cScrollbar::getPosition() {
|
||||
return pos;
|
||||
}
|
||||
@@ -86,6 +90,190 @@ eScrollStyle cScrollbar::getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
// TODO: centralize this translation somewhere
|
||||
// Translate raw x/y position using the view of the current rendering target
|
||||
location cScrollbar::translated_location(sf::Vector2i const point) const {
|
||||
return location { this->inWindow->mapPixelToCoords(point) };
|
||||
}
|
||||
|
||||
bool cScrollbar::handle_event(sf::Event const & event) {
|
||||
// Not visible -> not interested
|
||||
if(!this->isVisible())
|
||||
return false;
|
||||
|
||||
// Visible but no maximum -> not interested
|
||||
if(this->getMaximum() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(event.type) {
|
||||
case sf::Event::MouseButtonPressed:
|
||||
return this->handle_mouse_pressed(event);
|
||||
case sf::Event::MouseMoved:
|
||||
return this->handle_mouse_moved(event);
|
||||
case sf::Event::MouseButtonReleased:
|
||||
return this->handle_mouse_released(event);
|
||||
case sf::Event::MouseWheelScrolled:
|
||||
return this->handle_mouse_wheel_scrolled(event);
|
||||
default: break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cScrollbar::handle_mouse_wheel_scrolled(sf::Event const & event) {
|
||||
location event_location = this->translated_location({
|
||||
event.mouseWheelScroll.x,
|
||||
event.mouseWheelScroll.y
|
||||
});
|
||||
|
||||
// Scrolling outside of catching area or own frame -> not interested.
|
||||
if(!(event_location.in(this->wheel_event_rect) || event_location.in(this->getBounds())))
|
||||
return false;
|
||||
|
||||
this->setPosition(this->getPosition() - event.mouseWheelScroll.delta);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Given a (translated) location, determine which part of the scrollbar it corresponds to
|
||||
auto cScrollbar::location_to_part(location const & location) const -> eScrollbarPart {
|
||||
|
||||
cScrollbar::eScrollbarPart part;
|
||||
|
||||
// Yes, this is a mess, but at least it's relatively small.
|
||||
int clickPos = this->vert ? location.y : location.x;
|
||||
int bar_start = this->vert ? this->frame.top : this->frame.left;
|
||||
int bar_end = this->vert ? this->frame.bottom : this->frame.right;
|
||||
int total_bar_size = this->vert ? this->frame.height() : this->frame.width();
|
||||
|
||||
int btn_size = this->vert
|
||||
? this->up_rect[this->style][cScrollbar::VERT].height()
|
||||
: this->up_rect[this->style][cScrollbar::HORZ].width();
|
||||
|
||||
int bar_size = total_bar_size - btn_size * 2;
|
||||
int thumbPos = bar_start + btn_size + this->pos * (bar_size - btn_size) / this->max;
|
||||
|
||||
if(clickPos < bar_start + btn_size) {
|
||||
part = cScrollbar::PART_UP;
|
||||
} else if(clickPos < thumbPos) {
|
||||
part = cScrollbar::PART_PGUP;
|
||||
} else if(clickPos < thumbPos + btn_size) {
|
||||
part = cScrollbar::PART_THUMB;
|
||||
} else if(clickPos < bar_end - btn_size) {
|
||||
part = cScrollbar::PART_PGDN;
|
||||
} else {
|
||||
part = cScrollbar::PART_DOWN;
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
bool cScrollbar::handle_mouse_pressed(sf::Event const & event) {
|
||||
location event_location = this->translated_location({
|
||||
event.mouseButton.x,
|
||||
event.mouseButton.y
|
||||
});
|
||||
|
||||
// Mouse pressed somewhere outside -> not interested
|
||||
if(!event_location.in(this->getBounds())) return false;
|
||||
|
||||
// NOTE: depressed actually means pressed
|
||||
this->depressed = true;
|
||||
this->pressedPart = this->location_to_part(event_location);
|
||||
|
||||
// If the thumb is being dragged, record the initial click location
|
||||
if(this->pressedPart == cScrollbar::eScrollbarPart::PART_THUMB) {
|
||||
this->mouse_pressed_at = event_location;
|
||||
this->drag_start_position = this->pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cScrollbar::handle_mouse_moved(sf::Event const & event) {
|
||||
// Mouse movements while not pressed -> not interested
|
||||
// NOTE: depressed actually means pressed
|
||||
if(!this->depressed) return false;
|
||||
|
||||
// is there a need for restore_cursor() anywhere around here, and why?
|
||||
|
||||
location event_location = this->translated_location({
|
||||
event.mouseMove.x,
|
||||
event.mouseMove.y
|
||||
});
|
||||
|
||||
if(this->pressedPart == cScrollbar::eScrollbarPart::PART_THUMB) {
|
||||
// Thumb being dragged.
|
||||
this->handle_thumb_drag(event_location);
|
||||
return true;
|
||||
} else {
|
||||
// Dragging something ... but not thumb
|
||||
if(!event_location.in(this->getBounds())) {
|
||||
// Mouse was moved out of the scrollbar and not dragging thumb
|
||||
|
||||
// NOTE: depressed actually means pressed
|
||||
this->depressed = false;
|
||||
|
||||
// The event is outside the scrollbar so someone else might want to consume this.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Dragging something, but not thumb, but still within scrollbar bounds. Okay.jpg.
|
||||
return true;
|
||||
}
|
||||
|
||||
void cScrollbar::handle_thumb_drag(location const & event_location) {
|
||||
int bar_start = this->vert ? this->frame.top : this->frame.left;
|
||||
int bar_end = this->vert ? this->frame.bottom : this->frame.right;
|
||||
int btn_size = this->vert
|
||||
? this->up_rect[this->style][cScrollbar::VERT].height()
|
||||
: this->up_rect[this->style][cScrollbar::HORZ].width();
|
||||
|
||||
// XXX A lot of this looks like it can be precalculated once, but
|
||||
// be careful with the integer rounding.
|
||||
|
||||
int thumb_min_position = bar_start + btn_size;
|
||||
int thumb_max_position = bar_end - 2 * btn_size; // <- two button sizes: one for the top/left arrow and one for the thumb
|
||||
|
||||
int start = this->vert ? this->mouse_pressed_at.y : this->mouse_pressed_at.x;
|
||||
int current = this->vert ? event_location.y : event_location.x;
|
||||
|
||||
// This is done in this particular way to minimize integer rounding
|
||||
// that would otherwise heavily impact the result (when max is
|
||||
// significantly large compared to the pixel size of the scrollbar).
|
||||
int diff_in_steps = (current - start) * this->max / (thumb_max_position - thumb_min_position);
|
||||
|
||||
this->setPosition(this->drag_start_position + diff_in_steps);
|
||||
}
|
||||
|
||||
bool cScrollbar::handle_mouse_released(sf::Event const & event) {
|
||||
// Mouse released while not pressed -> not interested
|
||||
// NOTE: depressed actually means pressed
|
||||
if(!this->depressed) return false;
|
||||
|
||||
switch(this->pressedPart) {
|
||||
case cScrollbar::PART_UP: this->pos--; break;
|
||||
case cScrollbar::PART_DOWN: this->pos++; break;
|
||||
|
||||
case cScrollbar::PART_PGUP: this->pos -= this->pgsz; break;
|
||||
case cScrollbar::PART_PGDN: this->pos += this->pgsz; break;
|
||||
|
||||
case cScrollbar::PART_THUMB: break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Normalize
|
||||
this->pos = minmax(0, this->max, this->pos);
|
||||
|
||||
// NOTE: depressed actually means pressed
|
||||
this->depressed = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cScrollbar::handleClick(location where) {
|
||||
if(max == 0) return false;
|
||||
sf::Event e;
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
/// Scrollbar-related classes and types.
|
||||
|
||||
#include "control.hpp"
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable.hpp"
|
||||
|
||||
/// Specifies the style of a scrollbar.
|
||||
enum eScrollStyle {
|
||||
@@ -24,7 +26,7 @@ enum eScrollStyle {
|
||||
/// This has no coupling with scrollable data; that must be handled externally by
|
||||
/// using the methods to get the scrollbar's position.
|
||||
/// Alternatively, it can be used as a slider control.
|
||||
class cScrollbar : public cControl {
|
||||
class cScrollbar : public cControl, public iEventListener, public iDrawable {
|
||||
int pos, max, pgsz;
|
||||
std::string link;
|
||||
// Make sure this is equal to the number of constants in eScrollStyle
|
||||
@@ -34,7 +36,7 @@ class cScrollbar : public cControl {
|
||||
VERT, VERT_PRESSED, HORZ, HORZ_PRESSED
|
||||
};
|
||||
// Note: For horizontal scrollbars, up is left and down is right.
|
||||
enum {
|
||||
enum eScrollbarPart {
|
||||
PART_UP,
|
||||
PART_PGUP,
|
||||
PART_THUMB,
|
||||
@@ -45,7 +47,20 @@ class cScrollbar : public cControl {
|
||||
bool vert = true;
|
||||
static std::string scroll_textures[NUM_STYLES];
|
||||
static const rectangle up_rect[NUM_STYLES][4], down_rect[NUM_STYLES][4], bar_rect[NUM_STYLES][4], thumb_rect[NUM_STYLES][4];
|
||||
// Mouse wheel scrolling events inside this rectangle will be handled by the scrollbar.
|
||||
// Should at least cover the scrollbar itself, but can extend outside (example: scrolling
|
||||
// in the inventory area).
|
||||
rectangle wheel_event_rect {0, 0, 0, 0};
|
||||
void draw_vertical(), draw_horizontal();
|
||||
location translated_location(sf::Vector2i const) const;
|
||||
eScrollbarPart location_to_part(location const & location) const;
|
||||
location mouse_pressed_at;
|
||||
int drag_start_position;
|
||||
bool handle_mouse_pressed(sf::Event const &);
|
||||
bool handle_mouse_moved(sf::Event const &);
|
||||
bool handle_mouse_released(sf::Event const &);
|
||||
bool handle_mouse_wheel_scrolled(sf::Event const &);
|
||||
void handle_thumb_drag(location const &);
|
||||
public:
|
||||
/// @copydoc cDialog::init()
|
||||
static void init();
|
||||
@@ -114,7 +129,9 @@ public:
|
||||
/// Set the scrollbar style.
|
||||
/// @param newStyle The new style.
|
||||
void setStyle(eScrollStyle newStyle);
|
||||
void draw();
|
||||
void set_wheel_event_rect(rectangle);
|
||||
virtual void draw() override;
|
||||
virtual bool handle_event(sf::Event const &) override;
|
||||
/// @copydoc cControl::getSupportedHandlers
|
||||
///
|
||||
/// @todo Document possible handlers
|
||||
|
||||
@@ -72,7 +72,6 @@ cOutdoors::cWandering store_wandering_special;
|
||||
short store_selling_values[8] = {0,0,0,0,0,0,0,0};
|
||||
extern cShop active_shop;
|
||||
|
||||
extern rectangle shop_frame;
|
||||
extern short cen_x, cen_y;//,pc_moves[6];
|
||||
extern eGameMode overall_mode;
|
||||
extern eItemWinMode stat_window;
|
||||
@@ -2114,29 +2113,19 @@ bool handle_keystroke(const sf::Event& event){
|
||||
}
|
||||
|
||||
bool handle_scroll(const sf::Event& event) {
|
||||
rectangle status_panel_rect = {0,0,144,271}, text_panel_rect = {0,0,138,271};
|
||||
rectangle world_screen = win_to_rects[WINRECT_TERVIEW];
|
||||
world_screen.inset(13, 13);
|
||||
status_panel_rect.offset(win_to_rects[WINRECT_INVEN].topLeft());
|
||||
text_panel_rect.offset(win_to_rects[WINRECT_TRANSCRIPT].topLeft());
|
||||
fill_rect(mainPtr, world_screen, sf::Color::Magenta);
|
||||
|
||||
// TODO: centralize this translation somewhere
|
||||
location pos(event.mouseWheel.x, event.mouseWheel.y);
|
||||
pos = mainPtr.mapPixelToCoords(pos, mainView);
|
||||
|
||||
int amount = event.mouseWheel.delta;
|
||||
if(item_sbar->isVisible() && pos.in(status_panel_rect)) {
|
||||
item_sbar->setPosition(item_sbar->getPosition() - amount);
|
||||
redraw_screen(REFRESH_INVEN);
|
||||
} else if(text_sbar->isVisible() && pos.in(text_panel_rect)) {
|
||||
text_sbar->setPosition(text_sbar->getPosition() - amount);
|
||||
redraw_screen(REFRESH_TRANS);
|
||||
} else if(shop_sbar->isVisible() && pos.in(shop_frame)) {
|
||||
shop_sbar->setPosition(shop_sbar->getPosition() - amount);
|
||||
redraw_screen(REFRESH_DLOG);
|
||||
} else if(scrollableModes.count(overall_mode) && pos.in(world_screen)) {
|
||||
if(scrollableModes.count(overall_mode) && pos.in(world_screen)) {
|
||||
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
|
||||
center.x = minmax(4, univ.town->max_dim - 5, center.x - amount);
|
||||
else center.y = minmax(4, univ.town->max_dim - 5, center.y - amount);
|
||||
redraw_screen(REFRESH_TERRAIN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -158,8 +158,8 @@ const int MENUBAR_HEIGHT = 20;
|
||||
const int NUM_MAGE_SPELLS = 62;
|
||||
const int NUM_PRIEST_SPELLS = 62;
|
||||
|
||||
// spell levels
|
||||
const int MAGE_SPELL_LEVEL_MAX = 7;
|
||||
const int PRIEST_SPELL_LEVEL_MAX = 7;
|
||||
// UI layers
|
||||
const int UI_LAYER_DEFAULT = 1000;
|
||||
const int UI_LAYER_MENUBAR = 1200;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "boe.global.hpp"
|
||||
|
||||
@@ -19,6 +22,7 @@
|
||||
#include "mathutil.hpp"
|
||||
#include "button.hpp"
|
||||
#include "enum_map.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
|
||||
#include "boe.party.hpp"
|
||||
#include "boe.town.hpp"
|
||||
@@ -56,7 +60,8 @@ extern location spell_targets[8];
|
||||
extern std::shared_ptr<cScrollbar> text_sbar,item_sbar,shop_sbar;
|
||||
extern std::shared_ptr<cButton> done_btn, help_btn;
|
||||
extern sf::Texture bg_gworld;
|
||||
extern rectangle sbar_rect,item_sbar_rect,shop_sbar_rect,startup_top;
|
||||
extern rectangle const sbar_rect,item_sbar_rect,shop_sbar_rect;
|
||||
extern rectangle startup_top;
|
||||
extern rectangle talk_area_rect, word_place_rect;
|
||||
extern location store_anim_ul;
|
||||
extern long register_flag;
|
||||
@@ -68,6 +73,7 @@ extern cCustomGraphics spec_scen_g;
|
||||
extern sf::RenderWindow mini_map;
|
||||
bool map_visible = false;
|
||||
extern std::string save_talk_str1, save_talk_str2;
|
||||
extern cDrawableManager drawable_mgr;
|
||||
|
||||
rectangle menuBarRect;
|
||||
Region originalGrayRgn, newGrayRgn, underBarRgn;
|
||||
@@ -166,13 +172,7 @@ void adjust_window_mode() {
|
||||
const ImageRsrc& icon = ResMgr::graphics.get("icon", true);
|
||||
mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr());
|
||||
#endif
|
||||
if(text_sbar) {
|
||||
text_sbar->relocate({560,285});
|
||||
item_sbar->relocate({560,148});
|
||||
shop_sbar->relocate({272,69});
|
||||
done_btn->relocate({231,395});
|
||||
help_btn->relocate({273,12});
|
||||
}
|
||||
|
||||
init_menubar();
|
||||
showMenuBar();
|
||||
}
|
||||
@@ -538,13 +538,10 @@ void redraw_screen(int refresh) {
|
||||
draw_targeting_line(sf::Mouse::getPosition(mainPtr));
|
||||
refresh_stat_areas(0);
|
||||
}
|
||||
text_sbar->draw();
|
||||
item_sbar->draw();
|
||||
shop_sbar->draw();
|
||||
done_btn->draw();
|
||||
help_btn->draw();
|
||||
|
||||
drawMenuBar();
|
||||
drawable_mgr.draw_all();
|
||||
|
||||
mainPtr.display();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
#include "boe.global.hpp"
|
||||
#include "universe.hpp"
|
||||
|
||||
#define BOOST_NO_CXX11_NUMERIC_LIMITS // Because my libc++ is old and not quite standard-compliant, which breaks Boost.Thread
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "boe.graphics.hpp"
|
||||
#include "boe.newgraph.hpp"
|
||||
#include "boe.fileio.hpp"
|
||||
@@ -17,6 +18,8 @@
|
||||
#include "boe.dlgutil.hpp"
|
||||
#include "boe.infodlg.hpp"
|
||||
#include "boe.main.hpp"
|
||||
#include "boe.consts.hpp"
|
||||
#include "boe.ui.hpp"
|
||||
#include "winutil.hpp"
|
||||
#include "sounds.hpp"
|
||||
#include "render_image.hpp"
|
||||
@@ -32,7 +35,8 @@
|
||||
#include "button.hpp"
|
||||
#include "enum_map.hpp"
|
||||
#include "framerate_limiter.hpp"
|
||||
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
bool All_Done = false;
|
||||
sf::RenderWindow mainPtr;
|
||||
short had_text_freeze = 0,num_fonts;
|
||||
@@ -41,9 +45,10 @@ bool first_sound_played = false,spell_forced = false;
|
||||
bool party_in_memory = false;
|
||||
std::shared_ptr<cScrollbar> text_sbar, item_sbar, shop_sbar;
|
||||
std::shared_ptr<cButton> done_btn, help_btn;
|
||||
rectangle sbar_rect = {283,546,421,562};
|
||||
rectangle shop_sbar_rect = {67,258,357,274};
|
||||
rectangle item_sbar_rect = {146,546,253,562};
|
||||
// TODO: move these 3 to boe.ui.cpp ?
|
||||
extern rectangle const sbar_rect = {285,560,423,576};
|
||||
extern rectangle const shop_sbar_rect = {69,272,359,288};
|
||||
extern rectangle const item_sbar_rect = {148,560,255,576};
|
||||
bool bgm_on = false,bgm_init = false;
|
||||
location store_anim_ul;
|
||||
cUniverse univ;
|
||||
@@ -57,6 +62,9 @@ short on_monst_menu[256];
|
||||
extern bool map_visible;
|
||||
extern sf::View mainView;
|
||||
|
||||
extern rectangle shop_frame;
|
||||
extern enum_map(eGuiArea, rectangle) win_to_rects;
|
||||
|
||||
std::string scenario_temp_dir_name = "scenario";
|
||||
|
||||
/* Display globals */
|
||||
@@ -91,6 +99,10 @@ effect_pat_type current_pat;
|
||||
short missile_firer,current_monst_tactic;
|
||||
short store_current_pc = 0;
|
||||
|
||||
// TODO: these should be members of some global entity instead of being here
|
||||
std::unordered_map <std::string, std::shared_ptr <iEventListener>> event_listeners;
|
||||
cDrawableManager drawable_mgr;
|
||||
|
||||
sf::Clock animTimer;
|
||||
extern long anim_ticks;
|
||||
|
||||
@@ -135,21 +147,65 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void init_sbar(std::shared_ptr<cScrollbar>& sbar, rectangle rect, int max, int pgSz, int start = 0) {
|
||||
static void init_sbar(std::shared_ptr<cScrollbar>& sbar, std::string const name, rectangle rect, rectangle events_rect, int max, int pgSz, int start = 0) {
|
||||
sbar.reset(new cScrollbar(mainPtr));
|
||||
sbar->setBounds(rect);
|
||||
sbar->setMaximum(max);
|
||||
sbar->setPosition(start);
|
||||
sbar->setPageSize(pgSz);
|
||||
sbar->set_wheel_event_rect(events_rect);
|
||||
sbar->hide();
|
||||
|
||||
drawable_mgr.add_drawable(UI_LAYER_DEFAULT, name, sbar);
|
||||
event_listeners[name] = std::dynamic_pointer_cast <iEventListener> (sbar);
|
||||
}
|
||||
|
||||
static void init_btn(std::shared_ptr<cButton>& btn, eBtnType type) {
|
||||
static void init_scrollbars() {
|
||||
|
||||
// Cover entire transcript + scrollbar
|
||||
rectangle const transcript_events_rect {
|
||||
win_to_rects[WINRECT_TRANSCRIPT].top,
|
||||
win_to_rects[WINRECT_TRANSCRIPT].left,
|
||||
sbar_rect.bottom,
|
||||
sbar_rect.right
|
||||
};
|
||||
|
||||
// Cover entire inventory + scrollbar
|
||||
rectangle const inventory_events_rect {
|
||||
win_to_rects[WINRECT_INVEN].top,
|
||||
win_to_rects[WINRECT_INVEN].left,
|
||||
item_sbar_rect.bottom,
|
||||
item_sbar_rect.right
|
||||
};
|
||||
|
||||
// MAGIC NUMBERS: max size, page size, initial position - all in abstract "step" units
|
||||
init_sbar(text_sbar, "transcript-scrollbar", sbar_rect, transcript_events_rect, 58, 11, 58);
|
||||
init_sbar(item_sbar, "inventory-scrollbar", item_sbar_rect, inventory_events_rect, 16, 8);
|
||||
init_sbar(shop_sbar, "shop-scrollbar", shop_sbar_rect, shop_frame, 16, 8);
|
||||
}
|
||||
|
||||
static void init_btn(std::shared_ptr<cButton>& btn, eBtnType type, location loc) {
|
||||
btn.reset(new cButton(mainPtr));
|
||||
btn->setBtnType(type);
|
||||
btn->relocate(loc);
|
||||
btn->hide();
|
||||
}
|
||||
|
||||
static void init_buttons() {
|
||||
|
||||
// MAGIC NUMBERS: move to boe.ui.cpp ?
|
||||
|
||||
init_btn(done_btn, BTN_DONE, {231,395});
|
||||
init_btn(help_btn, BTN_HELP, {273,12});
|
||||
}
|
||||
|
||||
// NOTE: this should possibly be moved to boe.ui.cpp at some point
|
||||
static void init_ui() {
|
||||
cDialog::init();
|
||||
init_scrollbars();
|
||||
init_buttons();
|
||||
}
|
||||
|
||||
void init_boe(int argc, char* argv[]) {
|
||||
set_up_apple_events(argc, argv);
|
||||
init_directories(argv[0]);
|
||||
@@ -161,12 +217,7 @@ void init_boe(int argc, char* argv[]) {
|
||||
init_tiling();
|
||||
init_snd_tool();
|
||||
|
||||
cDialog::init();
|
||||
init_sbar(text_sbar, sbar_rect, 58, 11, 58);
|
||||
init_sbar(item_sbar, item_sbar_rect, 16, 8);
|
||||
init_sbar(shop_sbar, shop_sbar_rect, 16, 8);
|
||||
init_btn(done_btn, BTN_DONE);
|
||||
init_btn(help_btn, BTN_HELP);
|
||||
init_ui();
|
||||
|
||||
adjust_window_mode();
|
||||
// If we don't do this now it'll flash white to start with
|
||||
@@ -236,8 +287,10 @@ void handle_one_event(const sf::Event& event) {
|
||||
// What does this do and should it be here?
|
||||
clear_sound_memory();
|
||||
|
||||
// Check if the menubar wants to handle this event.
|
||||
if(menuBarProcessEvent(event)) return;
|
||||
// Check if any of the event listeners want this event.
|
||||
for(auto & listener : event_listeners) {
|
||||
if(listener.second->handle_event(event)) return;
|
||||
}
|
||||
|
||||
switch(event.type) {
|
||||
case sf::Event::KeyPressed:
|
||||
@@ -264,6 +317,7 @@ void handle_one_event(const sf::Event& event) {
|
||||
change_cursor({event.mouseMove.x, event.mouseMove.y});
|
||||
return;
|
||||
|
||||
// TODO: EVENT TYPE DEPRECATED IN SFML 2.5.1
|
||||
case sf::Event::MouseWheelMoved:
|
||||
if(flushingInput) return;
|
||||
handle_scroll(event);
|
||||
@@ -348,14 +402,6 @@ void redraw_everything() {
|
||||
if(map_visible) draw_map(false);
|
||||
}
|
||||
|
||||
static void handleUpdateWhileScrolling(volatile bool& doneScrolling, int refresh) {
|
||||
while(!doneScrolling) {
|
||||
sf::sleep(sf::milliseconds(10));
|
||||
redraw_screen(refresh);
|
||||
}
|
||||
mainPtr.setActive(false);
|
||||
}
|
||||
|
||||
void Mouse_Pressed(sf::Event const & event) {
|
||||
|
||||
// What is this stuff? Why is it here?
|
||||
@@ -364,37 +410,14 @@ void Mouse_Pressed(sf::Event const & event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(overall_mode != MODE_STARTUP) {
|
||||
location mousePos(event.mouseButton.x, event.mouseButton.y);
|
||||
mousePos = mainPtr.mapPixelToCoords(mousePos, mainView);
|
||||
volatile bool doneScrolling = false;
|
||||
if(mousePos.in(text_sbar->getBounds())) {
|
||||
mainPtr.setActive(false);
|
||||
boost::thread updater(std::bind(handleUpdateWhileScrolling, std::ref(doneScrolling), REFRESH_TRANS));
|
||||
text_sbar->handleClick(mousePos);
|
||||
doneScrolling = true;
|
||||
updater.join();
|
||||
redraw_screen(REFRESH_TRANS);
|
||||
} else if(mousePos.in(item_sbar->getBounds())) {
|
||||
mainPtr.setActive(false);
|
||||
boost::thread updater(std::bind(handleUpdateWhileScrolling, std::ref(doneScrolling), REFRESH_INVEN));
|
||||
item_sbar->handleClick(mousePos);
|
||||
doneScrolling = true;
|
||||
updater.join();
|
||||
redraw_screen(REFRESH_INVEN);
|
||||
} else if(overall_mode == MODE_SHOPPING && mousePos.in(shop_sbar->getBounds())) {
|
||||
mainPtr.setActive(false);
|
||||
boost::thread updater(std::bind(handleUpdateWhileScrolling, std::ref(doneScrolling), REFRESH_DLOG));
|
||||
shop_sbar->handleClick(mousePos);
|
||||
doneScrolling = true;
|
||||
updater.join();
|
||||
redraw_screen(REFRESH_DLOG);
|
||||
} else All_Done = handle_action(event);
|
||||
} else All_Done = handle_startup_press({event.mouseButton.x, event.mouseButton.y});
|
||||
if(overall_mode == MODE_STARTUP) {
|
||||
All_Done = handle_startup_press({event.mouseButton.x, event.mouseButton.y});
|
||||
} else {
|
||||
All_Done = handle_action(event);
|
||||
}
|
||||
|
||||
// Why does every mouse click activate a menu?
|
||||
menu_activate();
|
||||
|
||||
}
|
||||
|
||||
void close_program() {
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
OpenBoEMenu::OpenBoEMenu(sf::RenderWindow& window, cUniverse& universe)
|
||||
: tgui { window }
|
||||
, mainPtr { window }
|
||||
, univ { universe } {
|
||||
|
||||
// Build a menubar and store it in tgui with a known name
|
||||
@@ -26,7 +25,7 @@ OpenBoEMenu::OpenBoEMenu(sf::RenderWindow& window, cUniverse& universe)
|
||||
tgui::MenuBar::Ptr OpenBoEMenu::build_menubar() const {
|
||||
auto menubar = tgui::MenuBar::create();
|
||||
|
||||
menubar->setSize(this->mainPtr.getSize().x, MENUBAR_HEIGHT);
|
||||
menubar->setSize("100%", MENUBAR_HEIGHT);
|
||||
|
||||
this->add_menu_placeholders(menubar);
|
||||
this->add_persistent_menu_items(menubar);
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
#include "boe.consts.hpp"
|
||||
#include "spell.hpp"
|
||||
#include "skills_traits.hpp"
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable.hpp"
|
||||
|
||||
class OpenBoEMenu {
|
||||
class OpenBoEMenu : public iEventListener, public iDrawable {
|
||||
public:
|
||||
|
||||
OpenBoEMenu(sf::RenderWindow&, cUniverse&);
|
||||
|
||||
bool handle_event(const sf::Event&);
|
||||
void draw();
|
||||
virtual bool handle_event(const sf::Event&) override;
|
||||
virtual void draw() override;
|
||||
void update_for_game_state(eGameMode overall_mode, bool party_in_memory);
|
||||
void update_spell_menus();
|
||||
void update_monsters_menu();
|
||||
@@ -27,7 +29,6 @@ private:
|
||||
using MenuHierarchy = std::vector<sf::String>;
|
||||
|
||||
tgui::Gui tgui;
|
||||
sf::RenderWindow& mainPtr;
|
||||
cUniverse& univ;
|
||||
const sf::String internal_menubar_widget_name { "openboe-menu" };
|
||||
std::vector<unsigned int> spell_menus_connection_ids;
|
||||
|
||||
@@ -22,12 +22,6 @@ void menu_activate();
|
||||
void hideMenuBar();
|
||||
void showMenuBar();
|
||||
|
||||
// If a menubar runs inside our own event loop, we need ways to supply it with events and to draw it.
|
||||
namespace sf { class Event; };
|
||||
// Return true if event has been consumed by the menubar.
|
||||
bool menuBarProcessEvent(const sf::Event&);
|
||||
void drawMenuBar();
|
||||
|
||||
enum class eMenu {
|
||||
NONE, ABOUT, PREFS, QUIT,
|
||||
FILE_NEW, FILE_OPEN, FILE_ABORT, FILE_SAVE, FILE_SAVE_AS,
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
#include "boe.menus.hpp"
|
||||
#include "boe.consts.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include "boe.menu.hpp"
|
||||
#include "boe.consts.hpp"
|
||||
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern cUniverse univ;
|
||||
extern bool party_in_memory;
|
||||
extern eGameMode overall_mode;
|
||||
extern std::unordered_map<std::string, std::shared_ptr<iEventListener>>event_listeners;
|
||||
extern cDrawableManager drawable_mgr;
|
||||
|
||||
std::shared_ptr<OpenBoEMenu> menu_ptr;
|
||||
|
||||
void init_menubar() {
|
||||
menu_ptr.reset(new OpenBoEMenu(mainPtr, univ));
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event& event) {
|
||||
return menu_ptr->handle_event(event);
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
menu_ptr->draw();
|
||||
|
||||
event_listeners["menubar"] = std::dynamic_pointer_cast<iEventListener>(menu_ptr);
|
||||
drawable_mgr.add_drawable(UI_LAYER_MENUBAR, "menubar", menu_ptr);
|
||||
}
|
||||
|
||||
void adjust_monst_menu() {
|
||||
|
||||
@@ -278,13 +278,6 @@ void menu_activate() {
|
||||
[[file_menu itemWithTitle: @"Save As…"] setEnabled: YES];
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
}
|
||||
|
||||
@implementation MenuHandler
|
||||
-(void) monstMenu:(id) sender {
|
||||
cMonster* monst = [[sender representedObject] monst];
|
||||
|
||||
@@ -334,10 +334,3 @@ void set_up_apple_events(int argc, char* argv[]) {
|
||||
post_load();
|
||||
}
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
}
|
||||
|
||||
@@ -1777,25 +1777,12 @@ void handle_keystroke(sf::Event event) {
|
||||
}
|
||||
|
||||
void handle_scroll(const sf::Event& event) {
|
||||
rectangle pal_rect = terrain_buttons_rect, right_area_rect = {0,0,RIGHT_AREA_HEIGHT,RIGHT_AREA_WIDTH};
|
||||
right_area_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||||
pal_rect.offset(RIGHT_AREA_UL_X,RIGHT_AREA_UL_Y);
|
||||
pal_rect.height() = 16 * 17 + 2;
|
||||
fill_rect(mainPtr, right_area_rect, sf::Color::Magenta);
|
||||
location pos { translate_mouse_coordinates({event.mouseMove.x,event.mouseMove.y}) };
|
||||
int amount = event.mouseWheel.delta;
|
||||
if(right_sbar->isVisible() && pos.in(right_area_rect)) {
|
||||
right_sbar->setPosition(right_sbar->getPosition() - amount);
|
||||
redraw_screen();
|
||||
} else if(pal_sbar->isVisible() && pos.in(pal_rect)) {
|
||||
pal_sbar->setPosition(pal_sbar->getPosition() - amount);
|
||||
set_up_terrain_buttons(false);
|
||||
redraw_screen();
|
||||
} else if(overall_mode < MODE_MAIN_SCREEN && pos.in(terrain_rect)) {
|
||||
if(overall_mode < MODE_MAIN_SCREEN && pos.in(terrain_rect)) {
|
||||
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
|
||||
cen_x = minmax(4, town->max_dim - 5, cen_x - amount);
|
||||
else cen_y = minmax(4, town->max_dim - 5, cen_y - amount);
|
||||
redraw_screen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ const int RIGHT_AREA_HEIGHT = 400;
|
||||
const int TER_RECT_UL_X = 6;
|
||||
const int TER_RECT_UL_Y = 19;
|
||||
|
||||
const int UI_LAYER_DEFAULT = 1000;
|
||||
const int UI_LAYER_MENUBAR = 1200;
|
||||
|
||||
enum eScenMode {
|
||||
MODE_DRAWING = 0,
|
||||
MODE_TOGGLE_ROAD = 1,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "scen.keydlgs.hpp"
|
||||
#include "sounds.hpp"
|
||||
#include "mathutil.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
#include "cursors.hpp"
|
||||
|
||||
#include "dialog.hpp"
|
||||
@@ -38,6 +39,7 @@ void sort_specials();
|
||||
extern cOutdoors* current_terrain;
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern sf::View mainView;
|
||||
extern cDrawableManager drawable_mgr;
|
||||
extern cTown* current_town;
|
||||
extern short cen_x, cen_y,current_terrain_type,cur_town;
|
||||
extern cTown* town;
|
||||
@@ -402,7 +404,7 @@ void redraw_screen() {
|
||||
// DIRTY FIX to a problem that exist somewhere else. But where?
|
||||
undo_clip(mainPtr);
|
||||
|
||||
drawMenuBar();
|
||||
drawable_mgr.draw_all();
|
||||
|
||||
mainPtr.display();
|
||||
}
|
||||
@@ -424,14 +426,12 @@ void draw_main_screen() {
|
||||
tileImage(mainPtr,draw_rect,bg[17]);
|
||||
|
||||
draw_rb();
|
||||
right_sbar->draw();
|
||||
}
|
||||
|
||||
// draw terrain palette
|
||||
if((overall_mode < MODE_MAIN_SCREEN) || (overall_mode == MODE_EDIT_TYPES)) {
|
||||
place_location();
|
||||
set_up_terrain_buttons(false);
|
||||
pal_sbar->draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#define BOOST_NO_CXX11_NUMERIC_LIMITS // Because my libc++ is old and not quite standard-compliant, which breaks Boost.Thread
|
||||
#include <cstdio>
|
||||
#include <boost/thread.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include "scen.global.hpp"
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "res_image.hpp"
|
||||
#include "prefs.hpp"
|
||||
#include "framerate_limiter.hpp"
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
|
||||
/* Globals */
|
||||
bool All_Done = false;
|
||||
@@ -52,7 +54,6 @@ location cur_out;
|
||||
static void init_scened(int, char*[]);
|
||||
void handle_events();
|
||||
void handle_one_event(const sf::Event&);
|
||||
void Handle_Activate();
|
||||
void redraw_everything();
|
||||
void Mouse_Pressed(const sf::Event&);
|
||||
void close_program();
|
||||
@@ -66,6 +67,10 @@ extern rectangle terrain_buttons_rect;
|
||||
|
||||
extern void set_up_apple_events(int argc, char* argv[]);
|
||||
|
||||
// TODO: these should be members of some global entity instead of being here
|
||||
std::unordered_map <std::string, std::shared_ptr <iEventListener>> event_listeners;
|
||||
cDrawableManager drawable_mgr;
|
||||
|
||||
//Changed to ISO C specified argument and return type.
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
@@ -95,11 +100,32 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void init_sbar(std::shared_ptr<cScrollbar>& sbar, rectangle rect, int pgSz) {
|
||||
static void init_sbar(std::shared_ptr<cScrollbar>& sbar, std::string const name, rectangle rect, rectangle events_rect, int pgSz) {
|
||||
sbar.reset(new cScrollbar(mainPtr));
|
||||
sbar->setBounds(rect);
|
||||
sbar->set_wheel_event_rect(events_rect);
|
||||
sbar->setPageSize(pgSz);
|
||||
sbar->hide();
|
||||
|
||||
drawable_mgr.add_drawable(UI_LAYER_DEFAULT, name, sbar);
|
||||
event_listeners[name] = std::dynamic_pointer_cast <iEventListener> (sbar);
|
||||
}
|
||||
|
||||
static void init_scrollbars () {
|
||||
right_sbar_rect.top = RIGHT_AREA_UL_Y - 1;
|
||||
right_sbar_rect.left = RIGHT_AREA_UL_X + RIGHT_AREA_WIDTH - 1 - 16;
|
||||
right_sbar_rect.bottom = RIGHT_AREA_UL_Y + RIGHT_AREA_HEIGHT + 1;
|
||||
right_sbar_rect.right = RIGHT_AREA_UL_X + RIGHT_AREA_WIDTH - 1;
|
||||
rectangle pal_sbar_rect = terrain_buttons_rect;
|
||||
pal_sbar_rect.offset(RIGHT_AREA_UL_X,RIGHT_AREA_UL_Y);
|
||||
pal_sbar_rect.left = pal_sbar_rect.right - 16;
|
||||
pal_sbar_rect.height() = 17 * 16;
|
||||
|
||||
rectangle const right_sbar_event_rect { 5, 287, 405, 577 };
|
||||
rectangle const pal_sbar_event_rect { 5, 287, 279, 581 };
|
||||
|
||||
init_sbar(right_sbar, "right_sbar", right_sbar_rect, right_sbar_event_rect, NRSONPAGE - 1);
|
||||
init_sbar(pal_sbar, "pal_sbar", pal_sbar_rect, pal_sbar_event_rect, 16);
|
||||
}
|
||||
|
||||
sf::FloatRect compute_viewport(sf::RenderWindow const & mainPtr, float ui_scale) {
|
||||
@@ -177,17 +203,7 @@ void init_scened(int argc, char* argv[]) {
|
||||
cen_x = 18;
|
||||
cen_y = 18;
|
||||
|
||||
right_sbar_rect.top = RIGHT_AREA_UL_Y - 1;
|
||||
right_sbar_rect.left = RIGHT_AREA_UL_X + RIGHT_AREA_WIDTH - 1 - 16;
|
||||
right_sbar_rect.bottom = RIGHT_AREA_UL_Y + RIGHT_AREA_HEIGHT + 1;
|
||||
right_sbar_rect.right = RIGHT_AREA_UL_X + RIGHT_AREA_WIDTH - 1;
|
||||
rectangle pal_sbar_rect = terrain_buttons_rect;
|
||||
pal_sbar_rect.offset(RIGHT_AREA_UL_X,RIGHT_AREA_UL_Y);
|
||||
pal_sbar_rect.left = pal_sbar_rect.right - 16;
|
||||
pal_sbar_rect.height() = 17 * 16;
|
||||
|
||||
init_sbar(right_sbar, right_sbar_rect, NRSONPAGE - 1);
|
||||
init_sbar(pal_sbar, pal_sbar_rect, 16);
|
||||
init_scrollbars();
|
||||
init_lb();
|
||||
init_rb();
|
||||
|
||||
@@ -203,7 +219,6 @@ void init_scened(int argc, char* argv[]) {
|
||||
cDialog::doAnimations = true;
|
||||
set_up_apple_events(argc, argv);
|
||||
init_fileio();
|
||||
redraw_screen();
|
||||
}
|
||||
|
||||
void handle_events() {
|
||||
@@ -225,8 +240,10 @@ void handle_events() {
|
||||
|
||||
void handle_one_event(sf::Event const & event) {
|
||||
|
||||
// Check if the menubar wants to handle this event.
|
||||
if(menuBarProcessEvent(event)) return;
|
||||
// Check if any of the event listeners want this event.
|
||||
for (auto & listener : event_listeners) {
|
||||
if(listener.second->handle_event(event)) return;
|
||||
}
|
||||
|
||||
switch(event.type) {
|
||||
case sf::Event::KeyPressed:
|
||||
@@ -609,39 +626,9 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
redraw_screen();
|
||||
}
|
||||
|
||||
static void handleUpdateWhileScrolling(volatile bool& doneScrolling) {
|
||||
while(!doneScrolling) {
|
||||
sf::sleep(sf::milliseconds(10));
|
||||
// TODO: redraw_screen should probably take the argument specifying what to update
|
||||
redraw_screen(/*REFRESH_RIGHT_BAR*/);
|
||||
if(overall_mode < MODE_MAIN_SCREEN || overall_mode == MODE_EDIT_TYPES)
|
||||
set_up_terrain_buttons(false);
|
||||
}
|
||||
mainPtr.setActive(false);
|
||||
}
|
||||
|
||||
void Mouse_Pressed(sf::Event const & event) {
|
||||
|
||||
// Translate coordinates
|
||||
location mousePos { translate_mouse_coordinates({event.mouseButton.x, event.mouseButton.y}) };
|
||||
|
||||
volatile bool doneScrolling = false;
|
||||
if(right_sbar->isVisible() && mousePos.in(right_sbar->getBounds())) {
|
||||
mainPtr.setActive(false);
|
||||
boost::thread updater(std::bind(handleUpdateWhileScrolling, std::ref(doneScrolling)));
|
||||
right_sbar->handleClick(mousePos);
|
||||
doneScrolling = true;
|
||||
updater.join();
|
||||
redraw_screen(/*REFRESH_RIGHT_BAR*/);
|
||||
} else if(pal_sbar->isVisible() && mousePos.in(pal_sbar->getBounds())) {
|
||||
mainPtr.setActive(false);
|
||||
boost::thread updater(std::bind(handleUpdateWhileScrolling, std::ref(doneScrolling)));
|
||||
pal_sbar->handleClick(mousePos);
|
||||
doneScrolling = true;
|
||||
updater.join();
|
||||
redraw_screen(/*REFRESH_RIGHT_BAR*/);
|
||||
set_up_terrain_buttons(false);
|
||||
} else handle_action(mousePos,event);
|
||||
handle_action(mousePos,event);
|
||||
}
|
||||
|
||||
void close_program() {
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
OpenBoESceneditMenu::OpenBoESceneditMenu(sf::RenderWindow& window)
|
||||
: tgui { window }
|
||||
, mainPtr { window } {
|
||||
|
||||
: tgui { window } {
|
||||
// Build a menubar and store it in tgui with a known name
|
||||
this->tgui.add(this->build_menubar(), this->internal_menubar_widget_name);
|
||||
}
|
||||
@@ -17,7 +15,7 @@ tgui::MenuBar::Ptr OpenBoESceneditMenu::build_menubar() const {
|
||||
auto menubar = tgui::MenuBar::create();
|
||||
|
||||
// XXX can we get this constant magic number from somewhere?
|
||||
menubar->setSize(this->mainPtr.getSize().x, 20);
|
||||
menubar->setSize("100%", 20);
|
||||
|
||||
this->add_menu_placeholders(menubar);
|
||||
this->add_persistent_menu_items(menubar);
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
#include <TGUI/TGUI.hpp>
|
||||
#include <vector>
|
||||
#include "undo.hpp"
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable.hpp"
|
||||
|
||||
class OpenBoESceneditMenu {
|
||||
class OpenBoESceneditMenu : public iEventListener, public iDrawable {
|
||||
public:
|
||||
|
||||
OpenBoESceneditMenu(sf::RenderWindow &);
|
||||
|
||||
bool handle_event(const sf::Event&);
|
||||
void draw();
|
||||
virtual bool handle_event(const sf::Event&) override;
|
||||
virtual void draw() override;
|
||||
void update_for_mode(short mode);
|
||||
void update_edit_menu(cUndoList const &);
|
||||
|
||||
@@ -23,7 +25,6 @@ private:
|
||||
using MenuHierarchy = std::vector<sf::String>;
|
||||
|
||||
tgui::Gui tgui;
|
||||
sf::RenderWindow& mainPtr;
|
||||
const sf::String internal_menubar_widget_name { "openboe-scenedit-menu" };
|
||||
|
||||
tgui::MenuBar::Ptr build_menubar() const;
|
||||
|
||||
@@ -13,10 +13,6 @@ void init_menubar();
|
||||
void shut_down_menus(short mode);
|
||||
void update_edit_menu();
|
||||
|
||||
namespace sf { class Event; };
|
||||
bool menuBarProcessEvent(const sf::Event&);
|
||||
void drawMenuBar();
|
||||
|
||||
enum class eMenu {
|
||||
NONE, ABOUT, QUIT, FRILL, UNFRILL,
|
||||
FILE_NEW, FILE_OPEN, FILE_CLOSE, FILE_SAVE, FILE_SAVE_AS, FILE_REVERT,
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
#include "scen.global.hpp"
|
||||
#include "scen.menus.hpp"
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include "scen.menu.hpp"
|
||||
#include "undo.hpp"
|
||||
#include "event_listener.hpp"
|
||||
#include "drawable_manager.hpp"
|
||||
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern cUndoList undo_list;
|
||||
extern std::unordered_map <std::string, std::shared_ptr <iEventListener>> event_listeners;
|
||||
extern cDrawableManager drawable_mgr;
|
||||
|
||||
std::shared_ptr <OpenBoESceneditMenu> menu_ptr;
|
||||
|
||||
void init_menubar() {
|
||||
menu_ptr.reset(new OpenBoESceneditMenu(mainPtr));
|
||||
|
||||
event_listeners["menubar"] = std::dynamic_pointer_cast <iEventListener> (menu_ptr);
|
||||
drawable_mgr.add_drawable(UI_LAYER_MENUBAR, "menubar", menu_ptr);
|
||||
}
|
||||
|
||||
void shut_down_menus(short mode) {
|
||||
@@ -21,13 +31,5 @@ void update_edit_menu() {
|
||||
menu_ptr->update_edit_menu(undo_list);
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event& event) {
|
||||
return menu_ptr->handle_event(event);
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
menu_ptr->draw();
|
||||
}
|
||||
|
||||
void set_up_apple_events(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
@@ -164,13 +164,6 @@ void update_edit_menu() {
|
||||
}
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
}
|
||||
|
||||
@implementation MenuHandler
|
||||
-(void) menuChoice:(id) sender {
|
||||
handle_menu_choice(eMenu([[sender representedObject] intValue]));
|
||||
|
||||
@@ -253,10 +253,3 @@ void set_up_apple_events(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent(const sf::Event&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void drawMenuBar() {
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ Import("env platform")
|
||||
tools = Split("""
|
||||
undo.cpp
|
||||
framerate_limiter.cpp
|
||||
drawable_manager.cpp
|
||||
../location.cpp
|
||||
../mathutil.cpp
|
||||
../porting.cpp
|
||||
|
||||
14
src/tools/drawable.hpp
Normal file
14
src/tools/drawable.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef DRAWABLE_HPP
|
||||
#define DRAWABLE_HPP
|
||||
|
||||
class iDrawable {
|
||||
|
||||
public:
|
||||
|
||||
virtual void draw() = 0;
|
||||
|
||||
virtual ~iDrawable() {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
10
src/tools/drawable_manager.cpp
Normal file
10
src/tools/drawable_manager.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "drawable_manager.hpp"
|
||||
|
||||
void cDrawableManager::draw_all () {
|
||||
// layer order from lowest to highest is ensured by std::map
|
||||
for (auto & layer : this->layers) {
|
||||
for (auto & drawable : layer.second) {
|
||||
drawable.second->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/tools/drawable_manager.hpp
Normal file
27
src/tools/drawable_manager.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef DRAWABLE_MANAGER_HPP
|
||||
#define DRAWABLE_MANAGER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "drawable.hpp"
|
||||
|
||||
class cDrawableManager {
|
||||
|
||||
public:
|
||||
|
||||
void draw_all();
|
||||
|
||||
template<typename T>void add_drawable (int layer_id, std::string const name, std::shared_ptr<T>drawable) {
|
||||
this->layers[layer_id][name] = std::dynamic_pointer_cast<iDrawable>(drawable);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using Layer = std::unordered_map <std::string, std::shared_ptr<iDrawable>>;
|
||||
|
||||
std::map <int, Layer> layers;
|
||||
};
|
||||
|
||||
#endif
|
||||
16
src/tools/event_listener.hpp
Normal file
16
src/tools/event_listener.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef EVENT_LISTENER_HPP
|
||||
#define EVENT_LISTENER_HPP
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
class iEventListener {
|
||||
|
||||
public:
|
||||
|
||||
virtual bool handle_event(sf::Event const &) = 0;
|
||||
|
||||
virtual ~iEventListener() {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user