Enable UI scaling in the scenario and implement Linux menus
Patch from @x-qq Addresses #195 Note: UI scaling for the scenario editor still needs some work, but it's basically functional.
This commit is contained in:
@@ -110,6 +110,13 @@ bool OpenBoEMenu::handle_event(const sf::Event& event) {
|
|||||||
// Returns true if event was consumed
|
// Returns true if event was consumed
|
||||||
bool OpenBoEMenu::handle_keypressed_event(const sf::Event& event) {
|
bool OpenBoEMenu::handle_keypressed_event(const sf::Event& event) {
|
||||||
|
|
||||||
|
// NOTE: menu items get dynamically enabled/disabled based
|
||||||
|
// on gamestate, but these keyboard shortcuts do not. So
|
||||||
|
// this may not be the best way to implement them.
|
||||||
|
|
||||||
|
// NOTE: since we are manually adding keyboard shortcut descriptions
|
||||||
|
// to the menu items, they become parts of menu hierarchies
|
||||||
|
|
||||||
bool event_was_consumed { false };
|
bool event_was_consumed { false };
|
||||||
|
|
||||||
if(this->is_control_key_pressed()) {
|
if(this->is_control_key_pressed()) {
|
||||||
@@ -133,7 +140,7 @@ bool OpenBoEMenu::handle_keypressed_event(const sf::Event& event) {
|
|||||||
return event_was_consumed;
|
return event_was_consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenBoEMenu::is_control_key_pressed() {
|
bool OpenBoEMenu::is_control_key_pressed() const {
|
||||||
|
|
||||||
// NOTE: Control is not cross-platform (apple)
|
// NOTE: Control is not cross-platform (apple)
|
||||||
|
|
||||||
@@ -161,7 +168,7 @@ void OpenBoEMenu::update_for_game_state(eGameMode overall_mode, bool party_in_me
|
|||||||
menubar->setMenuEnabled("Cast Mage", false);
|
menubar->setMenuEnabled("Cast Mage", false);
|
||||||
menubar->setMenuEnabled("Cast Priest", false);
|
menubar->setMenuEnabled("Cast Priest", false);
|
||||||
|
|
||||||
menubar->setMenuItemEnabled({ "File", "Save Game" }, false);
|
menubar->setMenuItemEnabled({ "File", "Save Game Ctrl-S" }, false);
|
||||||
if(party_in_memory) {
|
if(party_in_memory) {
|
||||||
menubar->setMenuItemEnabled({ "File", "Save As..." }, true);
|
menubar->setMenuItemEnabled({ "File", "Save As..." }, true);
|
||||||
} else {
|
} else {
|
||||||
@@ -174,7 +181,7 @@ void OpenBoEMenu::update_for_game_state(eGameMode overall_mode, bool party_in_me
|
|||||||
menubar->setMenuEnabled("Cast Mage", true);
|
menubar->setMenuEnabled("Cast Mage", true);
|
||||||
menubar->setMenuEnabled("Cast Priest", true);
|
menubar->setMenuEnabled("Cast Priest", true);
|
||||||
|
|
||||||
menubar->setMenuItemEnabled({ "File", "Save Game" }, true);
|
menubar->setMenuItemEnabled({ "File", "Save Game Ctrl-S" }, true);
|
||||||
menubar->setMenuItemEnabled({ "File", "Save As..." }, true);
|
menubar->setMenuItemEnabled({ "File", "Save As..." }, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +202,7 @@ void OpenBoEMenu::purge_spell_menus(tgui::MenuBar::Ptr& menubar) {
|
|||||||
void OpenBoEMenu::update_mage_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
void OpenBoEMenu::update_mage_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
||||||
|
|
||||||
// Add "About" menu item and store connection id
|
// Add "About" menu item and store connection id
|
||||||
const OpenBoEMenu::MenuHierarchy about_hierarchy {{ "Cast Mage", "About this menu" }};
|
const OpenBoEMenu::MenuHierarchy about_hierarchy { "Cast Mage", "About this menu" };
|
||||||
menubar->addMenuItem(about_hierarchy);
|
menubar->addMenuItem(about_hierarchy);
|
||||||
this->spell_menus_connection_ids.push_back(
|
this->spell_menus_connection_ids.push_back(
|
||||||
menubar->connectMenuItem(about_hierarchy, handle_menu_choice, eMenu::ABOUT_MAGE)
|
menubar->connectMenuItem(about_hierarchy, handle_menu_choice, eMenu::ABOUT_MAGE)
|
||||||
@@ -205,7 +212,7 @@ void OpenBoEMenu::update_mage_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
|||||||
for(int spell_id = 0; spell_id < NUM_MAGE_SPELLS; ++spell_id) {
|
for(int spell_id = 0; spell_id < NUM_MAGE_SPELLS; ++spell_id) {
|
||||||
eSpell spell = cSpell::fromNum(eSkill::MAGE_SPELLS, spell_id);
|
eSpell spell = cSpell::fromNum(eSkill::MAGE_SPELLS, spell_id);
|
||||||
if(pc_can_cast_spell(this->univ.current_pc(), spell)) {
|
if(pc_can_cast_spell(this->univ.current_pc(), spell)) {
|
||||||
const OpenBoEMenu::MenuHierarchy spell_hierarchy = this->menu_hierarchy_from_spell(*spell);
|
const auto spell_hierarchy = this->menu_hierarchy_from_spell(*spell);
|
||||||
menubar->addMenuItem(spell_hierarchy);
|
menubar->addMenuItem(spell_hierarchy);
|
||||||
// Connect and store connection id
|
// Connect and store connection id
|
||||||
this->spell_menus_connection_ids.push_back(
|
this->spell_menus_connection_ids.push_back(
|
||||||
@@ -218,7 +225,7 @@ void OpenBoEMenu::update_mage_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
|||||||
void OpenBoEMenu::update_priest_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
void OpenBoEMenu::update_priest_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
||||||
|
|
||||||
// Add "About" menu item and store connection id
|
// Add "About" menu item and store connection id
|
||||||
const OpenBoEMenu::MenuHierarchy about_hierarchy { { "Cast Priest", "About this menu" } };
|
const OpenBoEMenu::MenuHierarchy about_hierarchy { "Cast Priest", "About this menu" };
|
||||||
menubar->addMenuItem(about_hierarchy);
|
menubar->addMenuItem(about_hierarchy);
|
||||||
this->spell_menus_connection_ids.push_back(
|
this->spell_menus_connection_ids.push_back(
|
||||||
menubar->connectMenuItem(about_hierarchy, handle_menu_choice, eMenu::ABOUT_PRIEST)
|
menubar->connectMenuItem(about_hierarchy, handle_menu_choice, eMenu::ABOUT_PRIEST)
|
||||||
@@ -228,7 +235,7 @@ void OpenBoEMenu::update_priest_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
|||||||
for (int spell_id = 0; spell_id < NUM_PRIEST_SPELLS; ++spell_id) {
|
for (int spell_id = 0; spell_id < NUM_PRIEST_SPELLS; ++spell_id) {
|
||||||
eSpell spell = cSpell::fromNum(eSkill::PRIEST_SPELLS, spell_id);
|
eSpell spell = cSpell::fromNum(eSkill::PRIEST_SPELLS, spell_id);
|
||||||
if(pc_can_cast_spell(this->univ.current_pc(), spell)) {
|
if(pc_can_cast_spell(this->univ.current_pc(), spell)) {
|
||||||
const OpenBoEMenu::MenuHierarchy spell_hierarchy = this->menu_hierarchy_from_spell(*spell);
|
const auto spell_hierarchy = this->menu_hierarchy_from_spell(*spell);
|
||||||
menubar->addMenuItem(spell_hierarchy);
|
menubar->addMenuItem(spell_hierarchy);
|
||||||
// Connect and store connection id
|
// Connect and store connection id
|
||||||
this->spell_menus_connection_ids.push_back(
|
this->spell_menus_connection_ids.push_back(
|
||||||
@@ -238,7 +245,7 @@ void OpenBoEMenu::update_priest_spells_menu(tgui::MenuBar::Ptr& menubar) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a menu hierarcy from cSpell
|
// Create a menu hierarchy from cSpell
|
||||||
OpenBoEMenu::MenuHierarchy OpenBoEMenu::menu_hierarchy_from_spell(const cSpell& spell) const {
|
OpenBoEMenu::MenuHierarchy OpenBoEMenu::menu_hierarchy_from_spell(const cSpell& spell) const {
|
||||||
OpenBoEMenu::MenuHierarchy hier;
|
OpenBoEMenu::MenuHierarchy hier;
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ public:
|
|||||||
|
|
||||||
tgui::MenuBar::Ptr build_menubar() const;
|
tgui::MenuBar::Ptr build_menubar() const;
|
||||||
bool handle_keypressed_event(const sf::Event&);
|
bool handle_keypressed_event(const sf::Event&);
|
||||||
bool is_control_key_pressed();
|
bool is_control_key_pressed() const;
|
||||||
void add_menu_placeholders(tgui::MenuBar::Ptr&) const;
|
void add_menu_placeholders(tgui::MenuBar::Ptr&) const;
|
||||||
void add_persistent_menu_items(tgui::MenuBar::Ptr&) const;
|
void add_persistent_menu_items(tgui::MenuBar::Ptr&) const;
|
||||||
tgui::MenuBar::Ptr get_menubar_ptr() const;
|
tgui::MenuBar::Ptr get_menubar_ptr() const;
|
||||||
|
@@ -27,6 +27,7 @@ elif str(platform) == "win32":
|
|||||||
elif str(platform) == "posix":
|
elif str(platform) == "posix":
|
||||||
scened_sources.extend(Split("""
|
scened_sources.extend(Split("""
|
||||||
scen.menus.linux.cpp
|
scen.menus.linux.cpp
|
||||||
|
scen.menu.cpp
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
scened = env.Program("#build/bin/BoE Scenario Editor", scened_sources + common_sources)
|
scened = env.Program("#build/bin/BoE Scenario Editor", scened_sources + common_sources)
|
||||||
|
@@ -1776,13 +1776,13 @@ void handle_keystroke(sf::Event event) {
|
|||||||
mouse_button_held = false;
|
mouse_button_held = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_scroll(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};
|
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);
|
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.offset(RIGHT_AREA_UL_X,RIGHT_AREA_UL_Y);
|
||||||
pal_rect.height() = 16 * 17 + 2;
|
pal_rect.height() = 16 * 17 + 2;
|
||||||
fill_rect(mainPtr, right_area_rect, sf::Color::Magenta);
|
fill_rect(mainPtr, right_area_rect, sf::Color::Magenta);
|
||||||
location pos(event.mouseWheel.x, event.mouseWheel.y);
|
location pos { translate_mouse_coordinates({event.mouseMove.x,event.mouseMove.y}) };
|
||||||
int amount = event.mouseWheel.delta;
|
int amount = event.mouseWheel.delta;
|
||||||
if(right_sbar->isVisible() && pos.in(right_area_rect)) {
|
if(right_sbar->isVisible() && pos.in(right_area_rect)) {
|
||||||
right_sbar->setPosition(right_sbar->getPosition() - amount);
|
right_sbar->setPosition(right_sbar->getPosition() - amount);
|
||||||
@@ -2288,7 +2288,7 @@ void set_up_start_screen() {
|
|||||||
set_lb(NLS - 2,LB_TEXT,LB_NO_ACTION,"Copyright 1997, All rights reserved.");
|
set_lb(NLS - 2,LB_TEXT,LB_NO_ACTION,"Copyright 1997, All rights reserved.");
|
||||||
set_lb(NLS - 1,LB_TEXT,LB_NO_ACTION,version());
|
set_lb(NLS - 1,LB_TEXT,LB_NO_ACTION,version());
|
||||||
change_made = false;
|
change_made = false;
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_up_main_screen() {
|
void set_up_main_screen() {
|
||||||
@@ -2328,7 +2328,7 @@ void set_up_main_screen() {
|
|||||||
shut_down_menus(4);
|
shut_down_menus(4);
|
||||||
shut_down_menus(3);
|
shut_down_menus(3);
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_town_edit() {
|
void start_town_edit() {
|
||||||
@@ -2358,7 +2358,7 @@ void start_town_edit() {
|
|||||||
current_ground = 0;
|
current_ground = 0;
|
||||||
else if(town->terrain(i,j) == 2)
|
else if(town->terrain(i,j) == 2)
|
||||||
current_ground = 2;
|
current_ground = 2;
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_out_edit() {
|
void start_out_edit() {
|
||||||
@@ -2389,7 +2389,7 @@ void start_out_edit() {
|
|||||||
current_ground = 0;
|
current_ground = 0;
|
||||||
else if(current_terrain->terrain[i][j] == 2)
|
else if(current_terrain->terrain[i][j] == 2)
|
||||||
current_ground = 2;
|
current_ground = 2;
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2402,7 +2402,7 @@ void start_terrain_editing() {
|
|||||||
place_location();
|
place_location();
|
||||||
|
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete/clear",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete/clear",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_monster_editing(bool just_redo_text) {
|
void start_monster_editing(bool just_redo_text) {
|
||||||
@@ -2426,7 +2426,7 @@ void start_monster_editing(bool just_redo_text) {
|
|||||||
set_rb(i - 1,RB_MONST, i, title);
|
set_rb(i - 1,RB_MONST, i, title);
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2456,7 +2456,7 @@ void start_item_editing(bool just_redo_text) {
|
|||||||
set_rb(i,RB_ITEM, i, title);
|
set_rb(i,RB_ITEM, i, title);
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2483,7 +2483,7 @@ void start_special_item_editing(bool just_redo_text) {
|
|||||||
set_rb(i,RB_SPEC_ITEM, i, title);
|
set_rb(i,RB_SPEC_ITEM, i, title);
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2508,7 +2508,7 @@ void start_quest_editing(bool just_redo_text) {
|
|||||||
set_rb(i, RB_QUEST, i, title);
|
set_rb(i, RB_QUEST, i, title);
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2533,7 +2533,7 @@ void start_shops_editing(bool just_redo_text) {
|
|||||||
set_rb(i, RB_SHOP, i, title);
|
set_rb(i, RB_SHOP, i, title);
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2606,7 +2606,7 @@ void start_string_editing(eStrMode mode,short just_redo_text) {
|
|||||||
|
|
||||||
pos = right_sbar->getPosition();
|
pos = right_sbar->getPosition();
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2655,7 +2655,7 @@ void start_special_editing(short mode,short just_redo_text) {
|
|||||||
case 2: set_rb(num_specs, RB_TOWN_SPEC, num_specs, make_new); break;
|
case 2: set_rb(num_specs, RB_TOWN_SPEC, num_specs, make_new); break;
|
||||||
}
|
}
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2691,7 +2691,7 @@ void start_dialogue_editing(short restoring) {
|
|||||||
}
|
}
|
||||||
set_rb(10 + n_nodes, RB_DIALOGUE, n_nodes, "Create New Node");
|
set_rb(10 + n_nodes, RB_DIALOGUE, n_nodes, "Create New Node");
|
||||||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click node to delete",true);
|
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click node to delete",true);
|
||||||
update_mouse_spot(sf::Mouse::getPosition(mainPtr));
|
update_mouse_spot(translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr)));
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ void flash_rect(rectangle to_flash);
|
|||||||
void swap_terrain();
|
void swap_terrain();
|
||||||
void set_new_terrain(ter_num_t selected_terrain);
|
void set_new_terrain(ter_num_t selected_terrain);
|
||||||
void handle_keystroke(sf::Event event);
|
void handle_keystroke(sf::Event event);
|
||||||
void handle_scroll(sf::Event& event);
|
void handle_scroll(const sf::Event& event);
|
||||||
void get_wandering_monst();
|
void get_wandering_monst();
|
||||||
void get_town_info();
|
void get_town_info();
|
||||||
void get_sign_resource();
|
void get_sign_resource();
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "dialog.hpp"
|
#include "dialog.hpp"
|
||||||
|
|
||||||
#include "scen.core.hpp"
|
#include "scen.core.hpp"
|
||||||
|
#include "scen.menus.hpp"
|
||||||
#include "scen.townout.hpp"
|
#include "scen.townout.hpp"
|
||||||
#include "scrollbar.hpp"
|
#include "scrollbar.hpp"
|
||||||
#include "res_image.hpp"
|
#include "res_image.hpp"
|
||||||
@@ -36,6 +37,7 @@ void sort_specials();
|
|||||||
|
|
||||||
extern cOutdoors* current_terrain;
|
extern cOutdoors* current_terrain;
|
||||||
extern sf::RenderWindow mainPtr;
|
extern sf::RenderWindow mainPtr;
|
||||||
|
extern sf::View mainView;
|
||||||
extern cTown* current_town;
|
extern cTown* current_town;
|
||||||
extern short cen_x, cen_y,current_terrain_type,cur_town;
|
extern short cen_x, cen_y,current_terrain_type,cur_town;
|
||||||
extern cTown* town;
|
extern cTown* town;
|
||||||
@@ -385,10 +387,23 @@ void load_graphics(){
|
|||||||
|
|
||||||
void redraw_screen() {
|
void redraw_screen() {
|
||||||
rectangle windRect(mainPtr);
|
rectangle windRect(mainPtr);
|
||||||
|
|
||||||
|
// Switch back to the default view while drawing the background tiles
|
||||||
|
// so that they are not upscaled
|
||||||
|
mainPtr.setView(mainPtr.getDefaultView());
|
||||||
tileImage(mainPtr,windRect,bg[20]);
|
tileImage(mainPtr,windRect,bg[20]);
|
||||||
|
mainPtr.setView(mainView);
|
||||||
|
|
||||||
draw_main_screen();
|
draw_main_screen();
|
||||||
|
|
||||||
if(overall_mode < MODE_MAIN_SCREEN)
|
if(overall_mode < MODE_MAIN_SCREEN)
|
||||||
draw_terrain();
|
draw_terrain();
|
||||||
|
|
||||||
|
// DIRTY FIX to a problem that exist somewhere else. But where?
|
||||||
|
undo_clip(mainPtr);
|
||||||
|
|
||||||
|
drawMenuBar();
|
||||||
|
|
||||||
mainPtr.display();
|
mainPtr.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,7 +976,7 @@ void draw_terrain(){
|
|||||||
yMin = cen_y + 5 - (324 / size);
|
yMin = cen_y + 5 - (324 / size);
|
||||||
yMax = cen_y + 5;
|
yMax = cen_y + 5;
|
||||||
} else yMax = std::min(yMax, 324 / size);
|
} else yMax = std::min(yMax, 324 / size);
|
||||||
std::cout << "Drawing map for x = " << xMin << "..." << xMax << " and y = " << yMin << "..." << yMax << std::endl;
|
// std::cout << "Drawing map for x = " << xMin << "..." << xMax << " and y = " << yMin << "..." << yMax << std::endl;
|
||||||
for(short q = xMin; q < xMax; q++)
|
for(short q = xMin; q < xMax; q++)
|
||||||
for(short r = yMin; r < yMax; r++) {
|
for(short r = yMin; r < yMax; r++) {
|
||||||
if(q - xMin < 0 || q - xMin >= max_dim || r - yMin < 0 || r - yMin >= max_dim)
|
if(q - xMin < 0 || q - xMin >= max_dim || r - yMin < 0 || r - yMin >= max_dim)
|
||||||
@@ -1298,13 +1313,13 @@ void place_location() {
|
|||||||
short picture_wanted;
|
short picture_wanted;
|
||||||
tileImage(mainPtr, terrain_buttons_rect, bg[17]);
|
tileImage(mainPtr, terrain_buttons_rect, bg[17]);
|
||||||
frame_rect(mainPtr, terrain_buttons_rect, sf::Color::Black);
|
frame_rect(mainPtr, terrain_buttons_rect, sf::Color::Black);
|
||||||
location mouse = sf::Mouse::getPosition(mainPtr);
|
location mouse = translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr));
|
||||||
|
|
||||||
location moveTo(5, terrain_rects[255].top + 18);
|
location moveTo(5, terrain_rects[255].top + 18);
|
||||||
draw_rect = text_rect;
|
draw_rect = text_rect;
|
||||||
draw_rect.offset(moveTo);
|
draw_rect.offset(moveTo);
|
||||||
if(overall_mode < MODE_MAIN_SCREEN) {
|
if(overall_mode < MODE_MAIN_SCREEN) {
|
||||||
std::cout << "Mouse: " << mouse << " Buttons: " << terrain_buttons_rect << " Terrain: " << terrain_rect << std::endl;
|
// std::cout << "Mouse: " << mouse << " Buttons: " << terrain_buttons_rect << " Terrain: " << terrain_rect << std::endl;
|
||||||
if(mouse.in(terrain_buttons_rect)) {
|
if(mouse.in(terrain_buttons_rect)) {
|
||||||
location rel_mouse = mouse;
|
location rel_mouse = mouse;
|
||||||
rel_mouse.x -= RIGHT_AREA_UL_X;
|
rel_mouse.x -= RIGHT_AREA_UL_X;
|
||||||
@@ -1613,3 +1628,8 @@ bool container_there(location l) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void record_display_strings(){}
|
void record_display_strings(){}
|
||||||
|
|
||||||
|
// Translate mouse event coordinates based on the global view and viewport
|
||||||
|
sf::Vector2f translate_mouse_coordinates(sf::Vector2i const point) {
|
||||||
|
return mainPtr.mapPixelToCoords(point, mainView);
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
#include "fields.hpp"
|
#include "fields.hpp"
|
||||||
#include "location.hpp"
|
#include "location.hpp"
|
||||||
|
|
||||||
@@ -36,3 +37,4 @@ short string_length(char *str);
|
|||||||
rectangle get_custom_rect (short which_rect);
|
rectangle get_custom_rect (short which_rect);
|
||||||
void init_dialogs();
|
void init_dialogs();
|
||||||
void record_display_strings();
|
void record_display_strings();
|
||||||
|
sf::Vector2f translate_mouse_coordinates(sf::Vector2i const point);
|
||||||
|
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
bool All_Done = false;
|
bool All_Done = false;
|
||||||
sf::Event event;
|
|
||||||
sf::RenderWindow mainPtr;
|
sf::RenderWindow mainPtr;
|
||||||
|
sf::View mainView;
|
||||||
cTown* town = nullptr;
|
cTown* town = nullptr;
|
||||||
bool mouse_button_held = false,editing_town = false;
|
bool mouse_button_held = false,editing_town = false;
|
||||||
short cur_viewing_mode = 0;
|
short cur_viewing_mode = 0;
|
||||||
@@ -49,12 +49,15 @@ location cur_out;
|
|||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
static void init_scened(int, char*[]);
|
static void init_scened(int, char*[]);
|
||||||
void Handle_One_Event();
|
void handle_events();
|
||||||
|
void handle_one_event(const sf::Event&);
|
||||||
void Handle_Activate();
|
void Handle_Activate();
|
||||||
void Handle_Update();
|
void redraw_everything();
|
||||||
void Mouse_Pressed();
|
void Mouse_Pressed(const sf::Event&);
|
||||||
void close_program();
|
void close_program();
|
||||||
void ding();
|
void ding();
|
||||||
|
void init_main_window(sf::RenderWindow&, sf::View&);
|
||||||
|
sf::FloatRect compute_viewport(sf::RenderWindow&, float ui_scale);
|
||||||
|
|
||||||
cScenario scenario;
|
cScenario scenario;
|
||||||
rectangle right_sbar_rect;
|
rectangle right_sbar_rect;
|
||||||
@@ -75,8 +78,7 @@ int main(int argc, char* argv[]) {
|
|||||||
set_up_start_screen();
|
set_up_start_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!All_Done)
|
handle_events();
|
||||||
Handle_One_Event();
|
|
||||||
|
|
||||||
close_program();
|
close_program();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -99,29 +101,71 @@ static void init_sbar(std::shared_ptr<cScrollbar>& sbar, rectangle rect, int pgS
|
|||||||
sbar->hide();
|
sbar->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_scened(int argc, char* argv[]) {
|
sf::FloatRect compute_viewport(sf::RenderWindow& mainPtr, float ui_scale) {
|
||||||
init_directories(argv[0]);
|
|
||||||
init_menubar();
|
|
||||||
sync_prefs();
|
|
||||||
init_shaders();
|
|
||||||
init_tiling();
|
|
||||||
init_snd_tool();
|
|
||||||
|
|
||||||
sf::VideoMode mode = sf::VideoMode::getDesktopMode();
|
// See compute_viewport() in boe.graphics.cpp
|
||||||
rectangle windRect;
|
int const os_specific_y_offset =
|
||||||
windRect.width() = mode.width;
|
#if defined(SFML_SYSTEM_WINDOWS) || defined(SFML_SYSTEM_MAC)
|
||||||
windRect.height() = mode.height;
|
0;
|
||||||
int height = 420 + getMenubarHeight();
|
#else
|
||||||
|
getMenubarHeight();
|
||||||
|
#endif
|
||||||
|
|
||||||
windRect.inset((windRect.right - 584) / 2,(windRect.bottom - height) / 2);
|
sf::FloatRect viewport;
|
||||||
windRect.offset(0,18);
|
|
||||||
mainPtr.create(sf::VideoMode(windRect.width(), windRect.height()), "Blades of Exile Scenario Editor", sf::Style::Titlebar | sf::Style::Close);
|
viewport.top = float(os_specific_y_offset) / mainPtr.getSize().y;
|
||||||
mainPtr.setPosition(windRect.topLeft());
|
viewport.left = 0;
|
||||||
#ifndef __APPLE__ // This overrides Dock icon on OSX, which isn't what we want at all
|
viewport.width = ui_scale;
|
||||||
|
viewport.height = ui_scale;
|
||||||
|
|
||||||
|
return viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_main_window (sf::RenderWindow & mainPtr, sf::View & mainView) {
|
||||||
|
|
||||||
|
// TODO: things might still be broken when upscaled.
|
||||||
|
// translate_mouse_coordinates has been applied in some places but more work might be needed.
|
||||||
|
// In particular, the white area on the right side of the main menu needs fixing.
|
||||||
|
float ui_scale = get_float_pref("UIScale", 1.0);
|
||||||
|
|
||||||
|
int const width = ui_scale * 584;
|
||||||
|
int const height = ui_scale * 420
|
||||||
|
#ifndef SFML_SYSTEM_WINDOWS
|
||||||
|
+ getMenubarHeight()
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
mainPtr.create(sf::VideoMode(width, height), "Blades of Exile Scenario Editor", sf::Style::Titlebar | sf::Style::Close);
|
||||||
|
mainPtr.setPosition({0,0});
|
||||||
|
|
||||||
|
// Initialize the view
|
||||||
|
mainView.setSize(width, height);
|
||||||
|
mainView.setCenter(width / 2, height / 2);
|
||||||
|
|
||||||
|
// Apply the viewport to the view
|
||||||
|
sf::FloatRect mainPort = compute_viewport(mainPtr, ui_scale);
|
||||||
|
mainView.setViewport(mainPort);
|
||||||
|
|
||||||
|
// Apply view to the main window
|
||||||
|
mainPtr.setView(mainView);
|
||||||
|
|
||||||
|
#ifndef SFML_SYSTEM_MAC // This overrides Dock icon on OSX, which isn't what we want at all
|
||||||
const ImageRsrc& icon = ResMgr::graphics.get("icon", true);
|
const ImageRsrc& icon = ResMgr::graphics.get("icon", true);
|
||||||
mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr());
|
mainPtr.setIcon(icon->getSize().x, icon->getSize().y, icon->copyToImage().getPixelsPtr());
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_scened(int argc, char* argv[]) {
|
||||||
|
init_directories(argv[0]);
|
||||||
|
sync_prefs();
|
||||||
|
init_main_window(mainPtr, mainView);
|
||||||
|
init_menubar();
|
||||||
|
init_shaders();
|
||||||
|
init_tiling();
|
||||||
|
init_snd_tool();
|
||||||
|
#ifdef SFML_SYSTEM_MAC
|
||||||
init_menubar(); // This is called twice because Windows and Mac have different ordering requirements
|
init_menubar(); // This is called twice because Windows and Mac have different ordering requirements
|
||||||
|
#endif
|
||||||
mainPtr.clear(sf::Color::Black);
|
mainPtr.clear(sf::Color::Black);
|
||||||
mainPtr.display();
|
mainPtr.display();
|
||||||
|
|
||||||
@@ -161,11 +205,30 @@ void init_scened(int argc, char* argv[]) {
|
|||||||
redraw_screen();
|
redraw_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Handle_One_Event() {
|
void handle_events() {
|
||||||
ae_loading = false;
|
sf::Event currentEvent;
|
||||||
Handle_Update();
|
sf::Clock framerate_clock;
|
||||||
|
const sf::Int64 desired_microseconds_per_frame { 1000000 / 60 }; // us / FPS
|
||||||
|
|
||||||
if(!mainPtr.waitEvent(event)) return;
|
while(!All_Done) {
|
||||||
|
while(mainPtr.pollEvent(currentEvent)) handle_one_event(currentEvent);
|
||||||
|
|
||||||
|
// Why do we have to set this to false after handling every event?
|
||||||
|
ae_loading = false;
|
||||||
|
|
||||||
|
redraw_everything();
|
||||||
|
|
||||||
|
// Prevent the loop from executing too fast.
|
||||||
|
const sf::Int64 remaining_time_budget = desired_microseconds_per_frame - framerate_clock.getElapsedTime().asMicroseconds();
|
||||||
|
if(remaining_time_budget > 0) sf::sleep(sf::microseconds(remaining_time_budget));
|
||||||
|
framerate_clock.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_one_event(sf::Event const & event) {
|
||||||
|
|
||||||
|
// Check if the menubar wants to handle this event.
|
||||||
|
if(menuBarProcessEvent(event)) return;
|
||||||
|
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
@@ -174,13 +237,13 @@ void Handle_One_Event() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::MouseButtonPressed:
|
case sf::Event::MouseButtonPressed:
|
||||||
Mouse_Pressed();
|
Mouse_Pressed(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::MouseMoved:
|
case sf::Event::MouseMoved:
|
||||||
if(mouse_button_held)
|
if(mouse_button_held)
|
||||||
handle_action(loc(event.mouseMove.x,event.mouseMove.y),event);
|
handle_action(location { translate_mouse_coordinates({event.mouseMove.x,event.mouseMove.y})},event);
|
||||||
update_mouse_spot(loc(event.mouseMove.x,event.mouseMove.y));
|
update_mouse_spot(location { translate_mouse_coordinates({event.mouseMove.x,event.mouseMove.y})});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sf::Event::MouseWheelMoved:
|
case sf::Event::MouseWheelMoved:
|
||||||
@@ -202,7 +265,7 @@ void Handle_One_Event() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Handle_Update() {
|
void redraw_everything() {
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
restore_cursor();
|
restore_cursor();
|
||||||
}
|
}
|
||||||
@@ -559,9 +622,11 @@ static void handleUpdateWhileScrolling(volatile bool& doneScrolling) {
|
|||||||
mainPtr.setActive(false);
|
mainPtr.setActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mouse_Pressed() {
|
void Mouse_Pressed(sf::Event const & event) {
|
||||||
|
|
||||||
|
// Translate coordinates
|
||||||
|
location mousePos { translate_mouse_coordinates({event.mouseButton.x, event.mouseButton.y}) };
|
||||||
|
|
||||||
location mousePos(event.mouseButton.x, event.mouseButton.y);
|
|
||||||
volatile bool doneScrolling = false;
|
volatile bool doneScrolling = false;
|
||||||
if(right_sbar->isVisible() && mousePos.in(right_sbar->getBounds())) {
|
if(right_sbar->isVisible() && mousePos.in(right_sbar->getBounds())) {
|
||||||
mainPtr.setActive(false);
|
mainPtr.setActive(false);
|
||||||
@@ -578,7 +643,7 @@ void Mouse_Pressed() {
|
|||||||
updater.join();
|
updater.join();
|
||||||
redraw_screen(/*REFRESH_RIGHT_BAR*/);
|
redraw_screen(/*REFRESH_RIGHT_BAR*/);
|
||||||
set_up_terrain_buttons(false);
|
set_up_terrain_buttons(false);
|
||||||
} else handle_action(loc(event.mouseButton.x,event.mouseButton.y),event);
|
} else handle_action(mousePos,event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_program() {
|
void close_program() {
|
||||||
|
263
src/scenedit/scen.menu.cpp
Normal file
263
src/scenedit/scen.menu.cpp
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
// Author: xq, Tuesday 2020-01-28
|
||||||
|
|
||||||
|
#include "scen.menu.hpp"
|
||||||
|
#include "scen.menus.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
OpenBoESceneditMenu::OpenBoESceneditMenu(sf::RenderWindow& window)
|
||||||
|
: tgui { window }
|
||||||
|
, mainPtr { window } {
|
||||||
|
|
||||||
|
// Build a menubar and store it in tgui with a known name
|
||||||
|
this->tgui.add(this->build_menubar(), this->internal_menubar_widget_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
this->add_menu_placeholders(menubar);
|
||||||
|
this->add_persistent_menu_items(menubar);
|
||||||
|
|
||||||
|
return menubar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method ensures that the menus on the menubar are in specific order
|
||||||
|
void OpenBoESceneditMenu::add_menu_placeholders(tgui::MenuBar::Ptr& menubar) const {
|
||||||
|
menubar->addMenu("File");
|
||||||
|
menubar->addMenu("Edit");
|
||||||
|
|
||||||
|
// With Advanced as a topmost item to have more vertical space for sub-items there
|
||||||
|
menubar->addMenuItem({"Scenario", "Advanced"});
|
||||||
|
menubar->addMenuItem({"Town", "Advanced"});
|
||||||
|
menubar->addMenuItem({"Outdoors", "Advanced"});
|
||||||
|
|
||||||
|
menubar->addMenu("Help");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method fills the menu with items that never change.
|
||||||
|
void OpenBoESceneditMenu::add_persistent_menu_items(tgui::MenuBar::Ptr& menubar) const {
|
||||||
|
const std::vector<std::pair <OpenBoESceneditMenu::MenuHierarchy, eMenu>> persistent_menu_items {
|
||||||
|
{ { "File", "New Scenario" }, eMenu::FILE_NEW },
|
||||||
|
{ { "File", "Open Scenario Ctrl-O" }, eMenu::FILE_OPEN },
|
||||||
|
{ { "File", "Close Scenario" }, eMenu::FILE_CLOSE },
|
||||||
|
{ { "File", "Save Scenario" }, eMenu::FILE_SAVE },
|
||||||
|
{ { "File", "Save As..." }, eMenu::FILE_SAVE_AS },
|
||||||
|
{ { "File", "Revert to Saved" }, eMenu::FILE_REVERT },
|
||||||
|
{ { "File", "Quit Ctrl-Q" }, eMenu::QUIT },
|
||||||
|
|
||||||
|
{ { "Edit", "Undo" }, eMenu::EDIT_UNDO },
|
||||||
|
{ { "Edit", "Redo" }, eMenu::EDIT_REDO },
|
||||||
|
{ { "Edit", "Cut" }, eMenu::EDIT_CUT },
|
||||||
|
{ { "Edit", "Copy" }, eMenu::EDIT_COPY },
|
||||||
|
{ { "Edit", "Paste" }, eMenu::EDIT_PASTE },
|
||||||
|
{ { "Edit", "Delete" }, eMenu::EDIT_DELETE },
|
||||||
|
{ { "Edit", "Select All" }, eMenu::EDIT_SELECT_ALL },
|
||||||
|
|
||||||
|
{ { "Scenario", "Advanced", "Edit Special Nodes" }, eMenu::SCEN_SPECIALS },
|
||||||
|
{ { "Scenario", "Advanced", "Edit Scenario Text" }, eMenu::SCEN_TEXT },
|
||||||
|
{ { "Scenario", "Advanced", "Edit Journal Entries" }, eMenu::SCEN_JOURNALS },
|
||||||
|
{ { "Scenario", "Advanced", "Import Town" }, eMenu::TOWN_IMPORT },
|
||||||
|
{ { "Scenario", "Advanced", "Import Outdoor Sector" }, eMenu::OUT_IMPORT },
|
||||||
|
{ { "Scenario", "Advanced", "Edit Saved Item Rectangles" }, eMenu::SCEN_SAVE_ITEM_RECTS },
|
||||||
|
{ { "Scenario", "Advanced", "Set Variable Town Entry" }, eMenu::TOWN_VARYING },
|
||||||
|
{ { "Scenario", "Advanced", "Set Scenario Event Timers" }, eMenu::SCEN_TIMERS },
|
||||||
|
{ { "Scenario", "Advanced", "Edit Item Placement Shortcuts" }, eMenu::SCEN_ITEM_SHORTCUTS },
|
||||||
|
{ { "Scenario", "Advanced", "Delete Last Town" }, eMenu::TOWN_DELETE },
|
||||||
|
{ { "Scenario", "Advanced", "Write Data To Text File" }, eMenu::SCEN_DATA_DUMP },
|
||||||
|
{ { "Scenario", "Advanced", "Do Full Text Dump" }, eMenu::SCEN_TEXT_DUMP },
|
||||||
|
// NOT IMPLEMENTED:
|
||||||
|
// { { "Scenario", "Advanced", "Scenario Shopping Text Dump" }, eMenu::NONE },
|
||||||
|
// { { "Scenario", "Advanced", "Scenario Monster Dump" }, eMenu::NONE },
|
||||||
|
// { { "Scenario", "Advanced", "Scenario Specials Dump" }, eMenu::NONE },
|
||||||
|
// { { "Scenario", "Advanced", "Scenario Object Data Dump" }, eMenu::NONE },
|
||||||
|
|
||||||
|
{ { "Scenario", "Create New Town" }, eMenu::TOWN_CREATE },
|
||||||
|
{ { "Scenario", "Create New Town" }, eMenu::TOWN_CREATE },
|
||||||
|
{ { "Scenario", "Resize Outdoors" }, eMenu::OUT_RESIZE },
|
||||||
|
{ { "Scenario", "Scenario Details" }, eMenu::SCEN_DETAILS },
|
||||||
|
{ { "Scenario", "Scenario Intro Text" }, eMenu::SCEN_INTRO },
|
||||||
|
{ { "Scenario", "Edit Custom Graphic Sheets" }, eMenu::SCEN_SHEETS },
|
||||||
|
{ { "Scenario", "Classify Custom Graphics" }, eMenu::SCEN_PICS },
|
||||||
|
{ { "Scenario", "Edit Custom Sounds" }, eMenu::SCEN_SNDS },
|
||||||
|
|
||||||
|
{ { "Town", "Advanced", "Edit Special Nodes" }, eMenu::TOWN_SPECIALS },
|
||||||
|
{ { "Town", "Advanced", "Edit Town Text" }, eMenu::TOWN_TEXT },
|
||||||
|
{ { "Town", "Advanced", "Edit Town Signs" }, eMenu::TOWN_SIGNS },
|
||||||
|
{ { "Town", "Advanced", "Advanced Town Details" }, eMenu::TOWN_ADVANCED },
|
||||||
|
{ { "Town", "Advanced", "Set Town Event Timers" }, eMenu::TOWN_TIMERS },
|
||||||
|
// NOT IMPLEMENTED:
|
||||||
|
// { { "Town", "Advanced", "Concise Town Report" }, eMenu::NONE },
|
||||||
|
|
||||||
|
{ { "Town", "Town Details" }, eMenu::TOWN_DETAILS },
|
||||||
|
{ { "Town", "Town Wandering Monsters" }, eMenu::TOWN_WANDERING },
|
||||||
|
{ { "Town", "Set Town Boundaries" }, eMenu::TOWN_BOUNDARIES },
|
||||||
|
{ { "Town", "Frill Up Terrain" }, eMenu::FRILL },
|
||||||
|
{ { "Town", "Remove Terrain Frills" }, eMenu::UNFRILL },
|
||||||
|
{ { "Town", "Edit Area Descriptions" }, eMenu::TOWN_AREAS },
|
||||||
|
{ { "Town", "Set Starting Location" }, eMenu::TOWN_START },
|
||||||
|
{ { "Town", "Add Random Items" }, eMenu::TOWN_ITEMS_RANDOM },
|
||||||
|
{ { "Town", "Set All Items Not Property" }, eMenu::TOWN_ITEMS_NOT_PROPERTY },
|
||||||
|
{ { "Town", "Clear All Items" }, eMenu::TOWN_ITEMS_CLEAR },
|
||||||
|
|
||||||
|
{ { "Outdoors", "Advanced", "Edit Special Nodes" }, eMenu::OUT_SPECIALS },
|
||||||
|
{ { "Outdoors", "Advanced", "Edit Outdoor Text" }, eMenu::OUT_TEXT },
|
||||||
|
{ { "Outdoors", "Advanced", "Edit Outdoor Signs" }, eMenu::OUT_SIGNS },
|
||||||
|
// NOT IMPLEMENTED:
|
||||||
|
// { { "Outdoors", "Advanced", "Concise Outdoor Report" }, eMenu::NONE },
|
||||||
|
|
||||||
|
{ { "Outdoors", "Outdoor Details" }, eMenu::OUT_DETAILS },
|
||||||
|
{ { "Outdoors", "Outdoor Wandering Monsters" }, eMenu::OUT_WANDERING },
|
||||||
|
{ { "Outdoors", "Outdoor Special Encounters" }, eMenu::OUT_ENCOUNTERS },
|
||||||
|
{ { "Outdoors", "Frill Up Terrain" }, eMenu::FRILL },
|
||||||
|
{ { "Outdoors", "Remove Terrain Frills" }, eMenu::UNFRILL },
|
||||||
|
{ { "Outdoors", "Edit Area Descriptions" }, eMenu::OUT_AREAS },
|
||||||
|
{ { "Outdoors", "Set Starting Location" }, eMenu::OUT_START },
|
||||||
|
|
||||||
|
{ { "Help", "Index" }, eMenu::HELP_TOC },
|
||||||
|
{ { "Help", "About Blades Scenario Editor" }, eMenu::ABOUT },
|
||||||
|
{ { "Help", "Getting Started" }, eMenu::HELP_START },
|
||||||
|
{ { "Help", "Testing Your Scenario" }, eMenu::HELP_TEST },
|
||||||
|
{ { "Help", "Distributing Your Scenario" }, eMenu::HELP_DIST },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note that signal connection ids are discarded.
|
||||||
|
for(const auto& item : persistent_menu_items) {
|
||||||
|
menubar->addMenuItem(item.first);
|
||||||
|
menubar->connectMenuItem(item.first, handle_menu_choice, item.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenBoESceneditMenu::handle_event(const sf::Event& event) {
|
||||||
|
|
||||||
|
if(event.type == sf::Event::KeyPressed && this->handle_keypressed_event(event))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return this->tgui.handleEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if event was consumed
|
||||||
|
bool OpenBoESceneditMenu::handle_keypressed_event(const sf::Event& event) {
|
||||||
|
|
||||||
|
// NOTE: menu items get dynamically enabled/disabled based
|
||||||
|
// on gamestate, but these keyboard shortcuts do not. So
|
||||||
|
// this may not be the best way to implement them.
|
||||||
|
|
||||||
|
// NOTE: since we are manually adding keyboard shortcut descriptions
|
||||||
|
// to the menu items, they become parts of menu hierarchies
|
||||||
|
|
||||||
|
bool event_was_consumed { false };
|
||||||
|
|
||||||
|
if(this->is_control_key_pressed()) {
|
||||||
|
switch(event.key.code) {
|
||||||
|
case sf::Keyboard::O:
|
||||||
|
handle_menu_choice(eMenu::FILE_OPEN);
|
||||||
|
event_was_consumed = true;
|
||||||
|
break;
|
||||||
|
case sf::Keyboard::Q:
|
||||||
|
handle_menu_choice(eMenu::QUIT);
|
||||||
|
event_was_consumed = true;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event_was_consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenBoESceneditMenu::is_control_key_pressed() const {
|
||||||
|
|
||||||
|
// NOTE: Control is not cross-platform (apple)
|
||||||
|
|
||||||
|
return (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)
|
||||||
|
|| sf::Keyboard::isKeyPressed(sf::Keyboard::RControl));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::draw() {
|
||||||
|
this->tgui.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
tgui::MenuBar::Ptr OpenBoESceneditMenu::get_menubar_ptr() const {
|
||||||
|
return this->tgui.get<tgui::MenuBar>(this->internal_menubar_widget_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mode 0: no scenario loaded
|
||||||
|
// mode 1: town menu disabled
|
||||||
|
// mode 2: outdoors menu disabled
|
||||||
|
// mode 3: both town and outdoors menus disabled
|
||||||
|
// mode 4: scenario loaded, everything enabled
|
||||||
|
void OpenBoESceneditMenu::update_for_mode(short mode) {
|
||||||
|
switch(mode){
|
||||||
|
case 0: this->update_for_mode_0(); break;
|
||||||
|
case 1: this->update_for_mode_1(); break;
|
||||||
|
case 2: this->update_for_mode_2(); break;
|
||||||
|
case 3: this->update_for_mode_3(); break;
|
||||||
|
case 4: this->update_for_mode_4(); break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error { "BUG: update_for_mode called with unknown mode!" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_for_mode_0() {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
menubar->setMenuItemEnabled({ "File", "Save Scenario" }, false);
|
||||||
|
menubar->setMenuItemEnabled({ "File", "Save As..." }, false);
|
||||||
|
|
||||||
|
menubar->setMenuEnabled("Scenario", false);
|
||||||
|
menubar->setMenuEnabled("Town", false);
|
||||||
|
menubar->setMenuEnabled("Outdoors", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_for_mode_1() {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
menubar->setMenuEnabled("Town", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_for_mode_2() {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
menubar->setMenuEnabled("Outdoors", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_for_mode_3() {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
menubar->setMenuEnabled("Town", false);
|
||||||
|
menubar->setMenuEnabled("Outdoors", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_for_mode_4() {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
menubar->setMenuItemEnabled({ "File", "Save Scenario" }, true);
|
||||||
|
menubar->setMenuItemEnabled({ "File", "Save As..." }, true);
|
||||||
|
|
||||||
|
menubar->setMenuEnabled("Scenario", true);
|
||||||
|
menubar->setMenuEnabled("Town", true);
|
||||||
|
menubar->setMenuEnabled("Outdoors", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenBoESceneditMenu::update_edit_menu(cUndoList const & undo_list) {
|
||||||
|
auto menubar = this->get_menubar_ptr();
|
||||||
|
|
||||||
|
OpenBoESceneditMenu::MenuHierarchy const undo_menu_item { "Edit", "Undo" };
|
||||||
|
OpenBoESceneditMenu::MenuHierarchy const redo_menu_item { "Edit", "Redo" };
|
||||||
|
|
||||||
|
if(undo_list.noUndo()) {
|
||||||
|
menubar->setMenuItemEnabled(undo_menu_item, false);
|
||||||
|
} else {
|
||||||
|
menubar->setMenuItemEnabled(undo_menu_item, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(undo_list.noRedo()) {
|
||||||
|
menubar->setMenuItemEnabled(redo_menu_item, false);
|
||||||
|
} else {
|
||||||
|
menubar->setMenuItemEnabled(redo_menu_item, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
42
src/scenedit/scen.menu.hpp
Normal file
42
src/scenedit/scen.menu.hpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Author: xq, Tuesday 2020-01-28
|
||||||
|
|
||||||
|
#ifndef SCEN_MENU_HPP
|
||||||
|
#define SCEN_MENU_HPP
|
||||||
|
|
||||||
|
// NOTE: this also includes SFML for us
|
||||||
|
#include <TGUI/TGUI.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include "undo.hpp"
|
||||||
|
|
||||||
|
class OpenBoESceneditMenu {
|
||||||
|
public:
|
||||||
|
|
||||||
|
OpenBoESceneditMenu(sf::RenderWindow &);
|
||||||
|
|
||||||
|
bool handle_event(const sf::Event&);
|
||||||
|
void draw();
|
||||||
|
void update_for_mode(short mode);
|
||||||
|
void update_edit_menu(cUndoList const &);
|
||||||
|
|
||||||
|
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;
|
||||||
|
void add_menu_placeholders(tgui::MenuBar::Ptr&) const;
|
||||||
|
void add_persistent_menu_items(tgui::MenuBar::Ptr&) const;
|
||||||
|
tgui::MenuBar::Ptr get_menubar_ptr() const;
|
||||||
|
bool handle_keypressed_event(const sf::Event&);
|
||||||
|
bool is_control_key_pressed() const;
|
||||||
|
void update_for_mode_0();
|
||||||
|
void update_for_mode_1();
|
||||||
|
void update_for_mode_2();
|
||||||
|
void update_for_mode_3();
|
||||||
|
void update_for_mode_4();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -13,6 +13,10 @@ void init_menubar();
|
|||||||
void shut_down_menus(short mode);
|
void shut_down_menus(short mode);
|
||||||
void update_edit_menu();
|
void update_edit_menu();
|
||||||
|
|
||||||
|
namespace sf { class Event; };
|
||||||
|
bool menuBarProcessEvent(const sf::Event&);
|
||||||
|
void drawMenuBar();
|
||||||
|
|
||||||
enum class eMenu {
|
enum class eMenu {
|
||||||
NONE, ABOUT, QUIT, FRILL, UNFRILL,
|
NONE, ABOUT, QUIT, FRILL, UNFRILL,
|
||||||
FILE_NEW, FILE_OPEN, FILE_CLOSE, FILE_SAVE, FILE_SAVE_AS, FILE_REVERT,
|
FILE_NEW, FILE_OPEN, FILE_CLOSE, FILE_SAVE, FILE_SAVE_AS, FILE_REVERT,
|
||||||
|
@@ -1,43 +1,33 @@
|
|||||||
|
|
||||||
#include "scen.menus.hpp"
|
#include "scen.menus.hpp"
|
||||||
#include <map>
|
|
||||||
#include <SFML/Graphics/RenderWindow.hpp>
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
#include "scenario.hpp"
|
#include <memory>
|
||||||
#include "winutil.hpp"
|
#include "scen.menu.hpp"
|
||||||
|
#include "undo.hpp"
|
||||||
// This is the index of each menu on the menubar
|
|
||||||
enum {
|
|
||||||
FILE_MENU_POS = 0,
|
|
||||||
EDIT_MENU_POS = 1,
|
|
||||||
SCEN_MENU_POS = 2,
|
|
||||||
TOWN_MENU_POS = 3,
|
|
||||||
OUT_MENU_POS = 4,
|
|
||||||
HELP_MENU_POS = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern sf::RenderWindow mainPtr;
|
extern sf::RenderWindow mainPtr;
|
||||||
extern cScenario scenario;
|
extern cUndoList undo_list;
|
||||||
std::map<int,eMenu> menuChoices;
|
|
||||||
|
|
||||||
|
std::shared_ptr <OpenBoESceneditMenu> menu_ptr;
|
||||||
|
|
||||||
void init_menubar() {
|
void init_menubar() {
|
||||||
|
menu_ptr.reset(new OpenBoESceneditMenu(mainPtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void shut_down_menus(short mode) {
|
void shut_down_menus(short mode) {
|
||||||
|
menu_ptr->update_for_mode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_edit_menu() {
|
void update_edit_menu() {
|
||||||
|
menu_ptr->update_edit_menu(undo_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "cursors.hpp"
|
bool menuBarProcessEvent(const sf::Event& event) {
|
||||||
|
return menu_ptr->handle_event(event);
|
||||||
|
}
|
||||||
|
|
||||||
#include "fileio.hpp"
|
void drawMenuBar() {
|
||||||
#include "scen.actions.hpp"
|
menu_ptr->draw();
|
||||||
|
}
|
||||||
|
|
||||||
extern short cur_town;
|
|
||||||
extern location cur_out;
|
|
||||||
extern cTown* town;
|
|
||||||
extern cOutdoors* current_terrain;
|
|
||||||
extern bool change_made, ae_loading;
|
|
||||||
void set_up_apple_events(int argc, char* argv[]) {
|
void set_up_apple_events(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
|
@@ -164,6 +164,13 @@ void update_edit_menu() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool menuBarProcessEvent(const sf::Event&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawMenuBar() {
|
||||||
|
}
|
||||||
|
|
||||||
@implementation MenuHandler
|
@implementation MenuHandler
|
||||||
-(void) menuChoice:(id) sender {
|
-(void) menuChoice:(id) sender {
|
||||||
handle_menu_choice(eMenu([[sender representedObject] intValue]));
|
handle_menu_choice(eMenu([[sender representedObject] intValue]));
|
||||||
|
@@ -253,3 +253,10 @@ void set_up_apple_events(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool menuBarProcessEvent(const sf::Event&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawMenuBar() {
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user