Reform scenario editor menu -> command mapping so that the non-platform-dependent code doesn't need to know where the menuitem is
This commit is contained in:
@@ -90,7 +90,6 @@ BEGIN
|
||||
MENUITEM "&Scenario Details", IDM_SCEN_DETAILS
|
||||
MENUITEM "Scenario Intr&o Text", IDM_SCEN_INTRO
|
||||
MENUITEM "Set Starting &Location", IDM_SCEN_START
|
||||
MENUITEM "Change Password", IDM_SCEN_PASSWORD
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Advanced:", IDM_SCEN_NEW_TOWN, GRAYED
|
||||
MENUITEM " Edit Special &Nodes", IDM_SCEN_ADV_SPECIALS
|
||||
|
@@ -783,6 +783,7 @@ bool outdoor_move_monster(short num,location dest) {
|
||||
|
||||
if(!outd_is_blocked(dest) && !outd_is_special(dest) &&
|
||||
(dest != univ.party.p_loc) &&
|
||||
// TODO: Don't hard-code terrain types!
|
||||
((univ.out[dest.x][dest.y] > 21) || (univ.out[dest.x][dest.y] < 5))) {
|
||||
univ.party.out_c[num].direction =
|
||||
set_direction(univ.party.out_c[num].m_loc, dest);
|
||||
|
@@ -489,12 +489,15 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
working_rect.bottom = spot_hit.y;
|
||||
if((overall_mode == 1) || (overall_mode == MODE_FILLED_RECT)) {
|
||||
change_rect_terrain(working_rect,current_terrain_type,20,0);
|
||||
change_made = true;
|
||||
}
|
||||
else if(overall_mode == MODE_HOLLOW_RECT) {
|
||||
change_rect_terrain(working_rect,current_terrain_type,20,1);
|
||||
change_made = true;
|
||||
}
|
||||
else if(overall_mode == MODE_SET_TOWN_RECT) {
|
||||
town->in_town_rect = working_rect;
|
||||
change_made = true;
|
||||
}
|
||||
else { // MODE_ROOM_RECT
|
||||
if(editing_town) {
|
||||
@@ -520,6 +523,7 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
}
|
||||
if(x < 500)
|
||||
giveError("You have placed the maximum number of area rectangles (16 in town, 8 outdoors).");
|
||||
else change_made = true;
|
||||
}
|
||||
overall_mode = MODE_DRAWING;
|
||||
set_cursor(wand_curs);
|
||||
@@ -895,6 +899,7 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
scenario.out_start = spot_hit;
|
||||
set_cursor(wand_curs);
|
||||
overall_mode = MODE_DRAWING;
|
||||
change_made = true;
|
||||
break;
|
||||
case MODE_ERASE_CREATURE: //delete monst
|
||||
for(x = 0; x < 60; x++)
|
||||
|
@@ -50,14 +50,6 @@ void Initialize(void);
|
||||
void Handle_One_Event();
|
||||
void Handle_Activate();
|
||||
void Handle_Update();
|
||||
void handle_file_menu(int item_hit);
|
||||
void handle_edit_menu(int item_hit);
|
||||
void handle_scenario_menu(int item_hit);
|
||||
void handle_town_menu(int item_hit);
|
||||
void handle_outdoor_menu(int item_hit);
|
||||
void handle_item_menu(int item_hit);
|
||||
void handle_monst_menu(int item_hit);
|
||||
void handle_help_menu(int item_hit);
|
||||
void Mouse_Pressed();
|
||||
void close_program();
|
||||
void ding();
|
||||
@@ -217,10 +209,14 @@ void Handle_Update() {
|
||||
restore_cursor();
|
||||
}
|
||||
|
||||
void handle_file_menu(int item_hit) {
|
||||
void handle_menu_choice(eMenu item_hit) {
|
||||
bool isEdit = false, isHelp = false;
|
||||
std::string helpDlog;
|
||||
fs::path file_to_load;
|
||||
cKey editKey = {true};
|
||||
switch(item_hit) {
|
||||
case 1: // open
|
||||
case eMenu::NONE: return;
|
||||
case eMenu::FILE_OPEN:
|
||||
if(change_made && !save_check("save-before-load"))
|
||||
break;
|
||||
file_to_load = nav_get_scenario();
|
||||
@@ -235,50 +231,50 @@ void handle_file_menu(int item_hit) {
|
||||
set_up_main_screen();
|
||||
}
|
||||
break;
|
||||
case 2: // save
|
||||
case eMenu::FILE_SAVE:
|
||||
town->set_up_lights();
|
||||
save_scenario();
|
||||
break;
|
||||
case 3: // new scen
|
||||
case eMenu::FILE_NEW:
|
||||
if(build_scenario()) {
|
||||
overall_mode = MODE_MAIN_SCREEN;
|
||||
set_up_main_screen();
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: // quit
|
||||
case eMenu::QUIT: // quit
|
||||
if(!save_check("save-before-quit"))
|
||||
break;
|
||||
All_Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_edit_menu(int item_hit) {
|
||||
// Currently, this merely passes appropriate input to the frontmost dialog.
|
||||
// TODO: Handle edit menu operations when no dialog is onscreen.
|
||||
cKey key = {true};
|
||||
switch(item_hit) {
|
||||
case 1: key.k = key_undo; break;
|
||||
case 2: key.k = key_redo; break;
|
||||
case 4: key.k = key_cut; break;
|
||||
case 5: key.k = key_copy; break;
|
||||
case 6: key.k = key_paste; break;
|
||||
case 7: key.k = key_del; break;
|
||||
case 8: key.k = key_selectall; break;
|
||||
}
|
||||
if(!cDialog::sendInput(key)) {
|
||||
// Handle non-dialog edit operations here.
|
||||
switch(key.k) {}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_scenario_menu(int item_hit) {
|
||||
short i;
|
||||
fs::path file;
|
||||
|
||||
switch(item_hit) {
|
||||
case 1: // Create new town
|
||||
case eMenu::EDIT_UNDO:
|
||||
editKey.k = key_undo;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_REDO:
|
||||
editKey.k = key_redo;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_CUT:
|
||||
editKey.k = key_cut;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_COPY:
|
||||
editKey.k = key_copy;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_PASTE:
|
||||
editKey.k = key_paste;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_DELETE:
|
||||
editKey.k = key_del;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::EDIT_SELECT_ALL:
|
||||
editKey.k = key_selectall;
|
||||
isEdit = true;
|
||||
break;
|
||||
case eMenu::TOWN_CREATE:
|
||||
if(change_made) {
|
||||
giveError("You need to save the changes made to your scenario before you can add a new town.");
|
||||
return;
|
||||
@@ -289,36 +285,33 @@ void handle_scenario_menu(int item_hit) {
|
||||
}
|
||||
if(new_town(scenario.num_towns))
|
||||
set_up_main_screen();
|
||||
change_made = true;
|
||||
break;
|
||||
case 3: // Scenario Details
|
||||
case eMenu::SCEN_DETAILS:
|
||||
edit_scen_details();
|
||||
change_made = true;
|
||||
break;
|
||||
case 4: // Scenario Intro Text
|
||||
case eMenu::SCEN_INTRO:
|
||||
edit_scen_intro();
|
||||
change_made = true;
|
||||
break;
|
||||
case 5: // Set Starting Location
|
||||
case eMenu::TOWN_START:
|
||||
set_starting_loc();
|
||||
change_made = true;
|
||||
break;
|
||||
case 6: // Change Password
|
||||
// if(check_p(user_given_password)) {
|
||||
// user_given_password = get_password();
|
||||
// given_password = true;
|
||||
// }
|
||||
giveError("Passwords have been disabled; they are no longer necessary.");
|
||||
break;
|
||||
case 9: // Edit Special Nodes
|
||||
case eMenu::SCEN_SPECIALS:
|
||||
right_sbar->setPosition(0);
|
||||
start_special_editing(0,0);
|
||||
break;
|
||||
case 10: // Edit Scenario Text
|
||||
case eMenu::SCEN_TEXT:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(0,0);
|
||||
break;
|
||||
case 11: // Edit Journal Entries
|
||||
case eMenu::SCEN_JOURNALS:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(3,0);
|
||||
break;
|
||||
case 12: // Import Town
|
||||
case eMenu::TOWN_IMPORT:
|
||||
if(change_made) {
|
||||
giveError("You need to save the changes made to your scenario before you can add a new town.");
|
||||
return;
|
||||
@@ -330,25 +323,30 @@ void handle_scenario_menu(int item_hit) {
|
||||
redraw_screen();
|
||||
}
|
||||
break;
|
||||
case 13: // Edit Saved Item Rectangles
|
||||
case eMenu::SCEN_SAVE_ITEM_RECTS:
|
||||
edit_save_rects();
|
||||
change_made = true;
|
||||
break;
|
||||
case 14: // Edit Horses
|
||||
case eMenu::SCEN_HORSES:
|
||||
edit_horses();
|
||||
change_made = true;
|
||||
break;
|
||||
case 15: // Edit Boats
|
||||
case eMenu::SCEN_BOATS:
|
||||
edit_boats();
|
||||
change_made = true;
|
||||
break;
|
||||
case 16: // Set Variable Town Entry
|
||||
case eMenu::TOWN_VARYING:
|
||||
edit_add_town();
|
||||
change_made = true;
|
||||
break;
|
||||
case 17: // Set Scenario Event Timers
|
||||
case eMenu::SCEN_TIMERS:
|
||||
edit_scenario_events();
|
||||
change_made = true;
|
||||
break;
|
||||
case 18: // Edit Item Placement Shortcuts
|
||||
case eMenu::SCEN_ITEM_SHORTCUTS:
|
||||
edit_item_placement();
|
||||
break;
|
||||
case 19: // Delete Last Town
|
||||
case eMenu::TOWN_DELETE:
|
||||
if(change_made) {
|
||||
giveError("You need to save the changes made to your scenario before you can delete a town.");
|
||||
return;
|
||||
@@ -368,142 +366,146 @@ void handle_scenario_menu(int item_hit) {
|
||||
if(cChoiceDlog("delete-town-confirm", {"okay", "cancel"}).show() == "okay")
|
||||
delete_last_town();
|
||||
break;
|
||||
case 20: // Write Data to Text File
|
||||
case eMenu::SCEN_DATA_DUMP:
|
||||
if(cChoiceDlog("data-dump-confirm", {"okay", "cancel"}).show() == "okay")
|
||||
start_data_dump();
|
||||
break;
|
||||
case 21: // Do Full Text Dump
|
||||
case eMenu::SCEN_TEXT_DUMP:
|
||||
if(cChoiceDlog("text-dump-confirm", {"okay", "cancel"}).show() == "okay")
|
||||
scen_text_dump();
|
||||
redraw_screen();
|
||||
break;
|
||||
}
|
||||
if((item_hit != 18) && (item_hit != 19))
|
||||
change_made = true;
|
||||
}
|
||||
|
||||
void handle_town_menu(int item_hit) {
|
||||
short i;
|
||||
|
||||
change_made = true;
|
||||
switch(item_hit) {
|
||||
case 1:
|
||||
case eMenu::TOWN_DETAILS:
|
||||
edit_town_details();
|
||||
change_made = true;
|
||||
break;
|
||||
case 2:
|
||||
case eMenu::TOWN_WANDERING:
|
||||
edit_town_wand();
|
||||
change_made = true;
|
||||
break;
|
||||
case 3:
|
||||
case eMenu::TOWN_BOUNDARIES:
|
||||
overall_mode = MODE_SET_TOWN_RECT;
|
||||
mode_count = 2;
|
||||
set_cursor(topleft_curs);
|
||||
set_string("Set town boundary","Select upper left corner");
|
||||
break;
|
||||
case 4:
|
||||
case eMenu::FRILL:
|
||||
frill_up_terrain();
|
||||
change_made = true;
|
||||
break;
|
||||
case 5:
|
||||
case eMenu::UNFRILL:
|
||||
unfrill_terrain();
|
||||
change_made = true;
|
||||
break;
|
||||
case 6:
|
||||
case eMenu::TOWN_AREAS:
|
||||
edit_roomdescs(true);
|
||||
change_made = true;
|
||||
break;
|
||||
case 8:
|
||||
case eMenu::TOWN_ITEMS_RANDOM:
|
||||
if(cChoiceDlog("add-random-items", {"okay", "cancel"}).show() == "cancel")
|
||||
break;
|
||||
place_items_in_town();
|
||||
break; // add random
|
||||
case 9:
|
||||
for(i = 0; i < 64; i++)
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::TOWN_ITEMS_NOT_PROPERTY:
|
||||
for(int i = 0; i < 64; i++)
|
||||
town->preset_items[i].property = 0;
|
||||
cChoiceDlog("set-not-owned").show();
|
||||
draw_terrain();
|
||||
break; // set not prop
|
||||
case 10:
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::TOWN_ITEMS_CLEAR:
|
||||
if(cChoiceDlog("clear-items-confirm", {"okay", "cancel"}).show() == "cancel")
|
||||
break;
|
||||
for(i = 0; i < 64; i++)
|
||||
for(int i = 0; i < 64; i++)
|
||||
town->preset_items[i].code = -1;
|
||||
draw_terrain();
|
||||
break; // clear all items
|
||||
case 13:
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::TOWN_SPECIALS:
|
||||
right_sbar->setPosition(0);
|
||||
start_special_editing(2,0);
|
||||
break;
|
||||
case 14:
|
||||
case eMenu::TOWN_TEXT:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(2,0);
|
||||
break;
|
||||
case 15:
|
||||
case eMenu::TOWN_SIGNS:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(5,0);
|
||||
break;
|
||||
case 16:
|
||||
case eMenu::TOWN_ADVANCED:
|
||||
edit_advanced_town();
|
||||
change_made = true;
|
||||
break;
|
||||
case 17:
|
||||
case eMenu::TOWN_TIMERS:
|
||||
edit_town_events();
|
||||
change_made = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void handle_outdoor_menu(int item_hit) {
|
||||
change_made = true;
|
||||
switch(item_hit) {
|
||||
case 1:
|
||||
case eMenu::OUT_DETAILS:
|
||||
outdoor_details();
|
||||
change_made = true;
|
||||
break;
|
||||
case 2:
|
||||
case eMenu::OUT_WANDERING:
|
||||
edit_out_wand(0);
|
||||
change_made = true;
|
||||
break;
|
||||
case 3:
|
||||
case eMenu::OUT_ENCOUNTERS:
|
||||
edit_out_wand(1);
|
||||
change_made = true;
|
||||
break;
|
||||
case 4:
|
||||
frill_up_terrain();
|
||||
break;
|
||||
case 5:
|
||||
unfrill_terrain();
|
||||
break;
|
||||
case 6:
|
||||
case eMenu::OUT_AREAS:
|
||||
edit_roomdescs(false);
|
||||
change_made = true;
|
||||
break;
|
||||
case 8:
|
||||
case eMenu::OUT_START:
|
||||
overall_mode = MODE_SET_OUT_START;
|
||||
set_string("Select party starting location.","");
|
||||
break;
|
||||
case 11:
|
||||
case eMenu::OUT_SPECIALS:
|
||||
right_sbar->setPosition(0);
|
||||
start_special_editing(1,0);
|
||||
break;
|
||||
case 12:
|
||||
case eMenu::OUT_TEXT:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(1,0);
|
||||
break;
|
||||
case 13:
|
||||
case eMenu::OUT_SIGNS:
|
||||
right_sbar->setPosition(0);
|
||||
start_string_editing(4,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_help_menu(int item_hit) {
|
||||
switch(item_hit) {
|
||||
case 0:
|
||||
cChoiceDlog("about-scened").show();
|
||||
case eMenu::ABOUT:
|
||||
helpDlog = "about-scened";
|
||||
isHelp = true;
|
||||
break;
|
||||
case eMenu::HELP_INDEX:
|
||||
launchURL("https://calref.net/~sylae/boe-doc/editor/About.html");
|
||||
break;
|
||||
case eMenu::HELP_START:
|
||||
helpDlog = "help-editing";
|
||||
isHelp = true;
|
||||
break;
|
||||
case eMenu::HELP_TEST:
|
||||
helpDlog = "help-testing";
|
||||
isHelp = true;
|
||||
break;
|
||||
case eMenu::HELP_DIST:
|
||||
helpDlog = "help-distributing";
|
||||
isHelp = true;
|
||||
break;
|
||||
case eMenu::HELP_CONTEST:
|
||||
helpDlog = "help-contest";
|
||||
isHelp = true;
|
||||
break;
|
||||
case 1:
|
||||
cChoiceDlog("help-editing").show();
|
||||
break; // started
|
||||
case 2:
|
||||
cChoiceDlog("help-testing").show();
|
||||
break; // testing
|
||||
case 3:
|
||||
cChoiceDlog("help-distributing").show();
|
||||
break; // distributing
|
||||
case 5:
|
||||
cChoiceDlog("help-contest").show();
|
||||
break; // contest
|
||||
}
|
||||
if(isEdit) {
|
||||
if(!cDialog::sendInput(editKey)) {
|
||||
// Handle non-dialog edit operations here.
|
||||
switch(editKey.k) {}
|
||||
}
|
||||
}
|
||||
if(isHelp)
|
||||
cChoiceDlog(helpDlog).show();
|
||||
}
|
||||
|
||||
void handle_item_menu(int item_hit) {
|
||||
|
@@ -373,14 +373,6 @@
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="875998550">
|
||||
<reference key="NSMenu" ref="399390342"/>
|
||||
<string key="NSTitle">Change Password</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="229763992"/>
|
||||
<reference key="NSMixedImage" ref="909111550"/>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="1007446984">
|
||||
<reference key="NSMenu" ref="399390342"/>
|
||||
<bool key="NSIsDisabled">YES</bool>
|
||||
@@ -1383,7 +1375,6 @@
|
||||
<reference ref="174312674"/>
|
||||
<reference ref="344591363"/>
|
||||
<reference ref="580939217"/>
|
||||
<reference ref="875998550"/>
|
||||
<reference ref="949025402"/>
|
||||
<reference ref="72958416"/>
|
||||
</array>
|
||||
@@ -1484,11 +1475,6 @@
|
||||
<reference key="object" ref="799771914"/>
|
||||
<reference key="parent" ref="399390342"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">808</int>
|
||||
<reference key="object" ref="875998550"/>
|
||||
<reference key="parent" ref="399390342"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">809</int>
|
||||
<reference key="object" ref="1007446984"/>
|
||||
@@ -1913,7 +1899,6 @@
|
||||
<string key="805.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="806.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="807.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="808.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="809.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="811.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
|
@@ -13,4 +13,28 @@ void init_menubar();
|
||||
void update_item_menu();
|
||||
void shut_down_menus(short mode);
|
||||
|
||||
enum class eMenu {
|
||||
NONE, ABOUT, QUIT, FRILL, UNFRILL,
|
||||
FILE_NEW, FILE_OPEN, FILE_CLOSE, FILE_SAVE, FILE_REVERT,
|
||||
EDIT_UNDO, EDIT_REDO, EDIT_CUT, EDIT_COPY, EDIT_PASTE, EDIT_DELETE, EDIT_SELECT_ALL,
|
||||
HELP_INDEX, HELP_START, HELP_TEST, HELP_DIST, HELP_CONTEST,
|
||||
// Scenario menu
|
||||
TOWN_CREATE, SCEN_DETAILS, SCEN_INTRO, TOWN_START,
|
||||
SCEN_SPECIALS, SCEN_TEXT, SCEN_JOURNALS, TOWN_IMPORT,
|
||||
SCEN_SAVE_ITEM_RECTS, SCEN_HORSES, SCEN_BOATS,
|
||||
TOWN_VARYING, SCEN_TIMERS, SCEN_ITEM_SHORTCUTS, TOWN_DELETE,
|
||||
SCEN_DATA_DUMP, SCEN_TEXT_DUMP,
|
||||
// Town menu
|
||||
TOWN_DETAILS, TOWN_WANDERING, TOWN_BOUNDARIES, TOWN_AREAS,
|
||||
TOWN_ITEMS_RANDOM, TOWN_ITEMS_NOT_PROPERTY, TOWN_ITEMS_CLEAR,
|
||||
TOWN_SPECIALS, TOWN_TEXT, TOWN_SIGNS, TOWN_ADVANCED, TOWN_TIMERS,
|
||||
// Outdoors menu
|
||||
OUT_DETAILS, OUT_WANDERING, OUT_ENCOUNTERS, OUT_AREAS, OUT_START,
|
||||
OUT_SPECIALS, OUT_TEXT, OUT_SIGNS,
|
||||
};
|
||||
|
||||
void handle_item_menu(int item_hit);
|
||||
void handle_monst_menu(int item_hit);
|
||||
void handle_menu_choice(eMenu item_hit);
|
||||
|
||||
#endif
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "scen.menus.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include "scenario.h"
|
||||
#include "winutil.h"
|
||||
|
||||
using MenuHandle = NSMenu*;
|
||||
MenuHandle menu_bar_handle;
|
||||
@@ -18,15 +19,9 @@ MenuHandle file_menu, edit_menu, app_menu, scen_menu, town_menu, out_menu, help_
|
||||
extern cScenario scenario;
|
||||
|
||||
@interface MenuHandler : NSObject
|
||||
-(void) fileMenu:(id) sender;
|
||||
-(void) editMenu:(id) sender;
|
||||
-(void) scenMenu:(id) sender;
|
||||
-(void) townMenu:(id) sender;
|
||||
-(void) outMenu:(id) sender;
|
||||
-(void) menuChoice:(id) sender;
|
||||
-(void) itemMenu:(id) sender;
|
||||
-(void) monstMenu:(id) sender;
|
||||
-(void) helpMenu:(id) sender;
|
||||
-(void) onlineHelp:(id) sender;
|
||||
@end
|
||||
|
||||
static void setMenuCallback(NSMenuItem* item, id targ, SEL selector, int num) {
|
||||
@@ -61,26 +56,55 @@ void init_menubar() {
|
||||
mon_menu[2] = [[menu_bar_handle itemWithTitle: @"M3"] submenu];
|
||||
mon_menu[3] = [[menu_bar_handle itemWithTitle: @"M4"] submenu];
|
||||
|
||||
MenuHandler* handler = [[[MenuHandler alloc] init] retain];
|
||||
setMenuCallback([app_menu itemWithTitle: @"About BoE Scenario Editor"], handler, @selector(helpMenu:), 0);
|
||||
setMenuCallback([app_menu itemWithTitle: @"Quit BoE Scenario Editor"], handler, @selector(fileMenu:), 5);
|
||||
// TODO: Organize file menu function
|
||||
setMenuCallback([file_menu itemWithTitle: @"New Scenario…"], handler, @selector(fileMenu:), 3);
|
||||
setMenuCallback([file_menu itemWithTitle: @"Open…"], handler, @selector(fileMenu:), 1);
|
||||
setMenuCallback([file_menu itemWithTitle: @"Save"], handler, @selector(fileMenu:), 2);
|
||||
setMenuCallback([help_menu itemAtIndex: 0], handler, @selector(onlineHelp:), 0);
|
||||
static const eMenu file_choices[] = {
|
||||
eMenu::FILE_NEW, eMenu::FILE_OPEN, eMenu::NONE, eMenu::FILE_CLOSE, eMenu::FILE_SAVE, eMenu::FILE_REVERT,
|
||||
};
|
||||
static const eMenu edit_choices[] = {
|
||||
eMenu::EDIT_UNDO, eMenu::EDIT_REDO, eMenu::NONE,
|
||||
eMenu::EDIT_CUT, eMenu::EDIT_COPY, eMenu::EDIT_PASTE, eMenu::EDIT_DELETE, eMenu::EDIT_SELECT_ALL,
|
||||
};
|
||||
static const eMenu scen_choices[] = {
|
||||
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
|
||||
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
|
||||
};
|
||||
static const eMenu town_choices[] = {
|
||||
eMenu::TOWN_DETAILS, eMenu::TOWN_WANDERING, eMenu::TOWN_BOUNDARIES, eMenu::FRILL, eMenu::UNFRILL, eMenu::TOWN_AREAS,
|
||||
eMenu::NONE, eMenu::TOWN_ITEMS_RANDOM, eMenu::TOWN_ITEMS_NOT_PROPERTY, eMenu::TOWN_ITEMS_CLEAR, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::TOWN_SPECIALS, eMenu::TOWN_TEXT, eMenu::TOWN_SIGNS, eMenu::TOWN_ADVANCED, eMenu::TOWN_TIMERS,
|
||||
};
|
||||
static const eMenu out_choices[] = {
|
||||
eMenu::OUT_DETAILS, eMenu::OUT_WANDERING, eMenu::OUT_ENCOUNTERS, eMenu::FRILL, eMenu::UNFRILL, eMenu::OUT_AREAS,
|
||||
eMenu::NONE, eMenu::OUT_START, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::OUT_SPECIALS, eMenu::OUT_TEXT, eMenu::OUT_SIGNS,
|
||||
};
|
||||
static const eMenu help_choices[] = {
|
||||
eMenu::HELP_INDEX, eMenu::NONE, eMenu::HELP_START, eMenu::HELP_TEST, eMenu::HELP_DIST, eMenu::NONE, eMenu::HELP_CONTEST,
|
||||
};
|
||||
|
||||
for(int i = 0; i < [edit_menu numberOfItems]; i++)
|
||||
setMenuCallback([edit_menu itemAtIndex: i], handler, @selector(editMenu:), i + 1);
|
||||
for(int i = 0; i < [scen_menu numberOfItems]; i++)
|
||||
setMenuCallback([scen_menu itemAtIndex: i], handler, @selector(scenMenu:), i + 1);
|
||||
for(int i = 0; i < [town_menu numberOfItems]; i++)
|
||||
setMenuCallback([town_menu itemAtIndex: i], handler, @selector(townMenu:), i + 1);
|
||||
for(int i = 0; i < [out_menu numberOfItems]; i++)
|
||||
setMenuCallback([out_menu itemAtIndex: i], handler, @selector(outMenu:), i + 1);
|
||||
for(int i = 2; i < [help_menu numberOfItems]; i++)
|
||||
setMenuCallback([help_menu itemAtIndex: i], handler, @selector(helpMenu:), i - 1);
|
||||
// TODO: Item and monster menus
|
||||
MenuHandler* handler = [[[MenuHandler alloc] init] retain];
|
||||
setMenuCallback([app_menu itemWithTitle: @"About BoE Scenario Editor"], handler, @selector(menuChoice:), int(eMenu::ABOUT));
|
||||
setMenuCallback([app_menu itemWithTitle: @"Quit BoE Scenario Editor"], handler, @selector(menuChoice:), int(eMenu::QUIT));
|
||||
|
||||
int i = 0;
|
||||
for(eMenu opt : file_choices)
|
||||
setMenuCallback([file_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
i = 0;
|
||||
for(eMenu opt : edit_choices)
|
||||
setMenuCallback([edit_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
i = 0;
|
||||
for(eMenu opt : scen_choices)
|
||||
setMenuCallback([scen_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
i = 0;
|
||||
for(eMenu opt : town_choices)
|
||||
setMenuCallback([town_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
i = 0;
|
||||
for(eMenu opt : out_choices)
|
||||
setMenuCallback([out_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
i = 0;
|
||||
for(eMenu opt : help_choices)
|
||||
setMenuCallback([help_menu itemAtIndex: i++], handler, @selector(menuChoice:), int(opt));
|
||||
}
|
||||
|
||||
// mode 0 - initial shut down, 1 - no town, 2 - no out, 3 - no town or out 4 - all menus on
|
||||
@@ -170,38 +194,9 @@ void update_item_menu() {
|
||||
|
||||
}
|
||||
|
||||
void handle_file_menu(int item_hit);
|
||||
void handle_edit_menu(int item_hit);
|
||||
void handle_scenario_menu(int item_hit);
|
||||
void handle_town_menu(int item_hit);
|
||||
void handle_outdoor_menu(int item_hit);
|
||||
void handle_help_menu(int item_hit);
|
||||
void handle_item_menu(int item_hit);
|
||||
void handle_monst_menu(int item_hit);
|
||||
|
||||
@implementation MenuHandler
|
||||
-(void) fileMenu:(id) sender {
|
||||
handle_file_menu([[sender representedObject] intValue]);
|
||||
}
|
||||
|
||||
// TODO: Implement edit menu (much work to be done here!)
|
||||
// TODO: Fix edit menu being disabled while a modal dialog is onscreen.
|
||||
// This means setting autoenable to false for the Edit menu and finding a
|
||||
// way to make the menuitems work instead of just doing nothing.
|
||||
-(void) editMenu:(id) sender {
|
||||
handle_edit_menu([[sender representedObject] intValue]);
|
||||
}
|
||||
|
||||
-(void) scenMenu:(id) sender {
|
||||
handle_scenario_menu([[sender representedObject] intValue]);
|
||||
}
|
||||
|
||||
-(void) townMenu:(id) sender {
|
||||
handle_town_menu([[sender representedObject] intValue]);
|
||||
}
|
||||
|
||||
-(void) outMenu:(id) sender {
|
||||
handle_outdoor_menu([[sender representedObject] intValue]);
|
||||
-(void) menuChoice:(id) sender {
|
||||
handle_menu_choice(eMenu([[sender representedObject] intValue]));
|
||||
}
|
||||
|
||||
// TODO: Monster and item menus
|
||||
@@ -212,13 +207,4 @@ void handle_monst_menu(int item_hit);
|
||||
-(void) monstMenu:(id) sender {
|
||||
(void) sender; // Suppress "unused parameter" warning
|
||||
}
|
||||
|
||||
-(void) helpMenu:(id) sender {
|
||||
handle_help_menu([[sender representedObject] intValue]);
|
||||
}
|
||||
|
||||
-(void) onlineHelp:(id) sender {
|
||||
(void) sender;
|
||||
[[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: @"https://calref.net/~sylae/boe-doc/editor/About.html"]];
|
||||
}
|
||||
@end
|
||||
|
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "scen.menus.h"
|
||||
#include <map>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include "Resource.h"
|
||||
#include "scenario.h"
|
||||
@@ -25,9 +26,19 @@ extern sf::RenderWindow mainPtr;
|
||||
extern cScenario scenario;
|
||||
LONG_PTR mainProc;
|
||||
HMENU menuHandle = NULL;
|
||||
std::map<int,eMenu> menuChoices;
|
||||
|
||||
LRESULT CALLBACK menuProc(HWND handle, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void setMenuCommand(HMENU& menu, int i, eMenu cmd) {
|
||||
MENUITEMINFOA item;
|
||||
item.cbSize = sizeof(MENUITEMINFOA);
|
||||
item.fMask = MIIM_ID | MIIM_FTYPE;
|
||||
GetMenuItemInfoA(file_menu, i++, true, &item);
|
||||
if(info.fType == MFT_SEPARATOR) return;
|
||||
menuChoices[item.wID] = cmd;
|
||||
}
|
||||
|
||||
void init_menubar() {
|
||||
HWND winHandle = mainPtr.getSystemHandle();
|
||||
if(winHandle == NULL) return;
|
||||
@@ -43,6 +54,64 @@ void init_menubar() {
|
||||
double usableHeight = sz.y - menubarHeight;
|
||||
sf::View view(sf::FloatRect(0, 0, sz.x, usableHeight));
|
||||
mainPtr.setView(view);
|
||||
|
||||
// And now initialize the mapping from Windows menu commands to eMenu constants
|
||||
static bool inited = false;
|
||||
if(inited) return;
|
||||
inited = true;
|
||||
|
||||
static const eMenu file_choices[] = {
|
||||
eMenu::FILE_NEW, eMenu::FILE_OPEN, eMenu::NONE, eMenu::FILE_CLOSE, eMenu::FILE_SAVE, eMenu::FILE_REVERT, eMenu::NONE, eMenu::QUIT,
|
||||
};
|
||||
static const eMenu edit_choices[] = {
|
||||
eMenu::EDIT_UNDO, eMenu::EDIT_REDO, eMenu::NONE,
|
||||
eMenu::EDIT_CUT, eMenu::EDIT_COPY, eMenu::EDIT_PASTE, eMenu::EDIT_DELETE, eMenu::EDIT_SELECT_ALL,
|
||||
};
|
||||
static const eMenu scen_choices[] = {
|
||||
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::TOWN_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
|
||||
eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
|
||||
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
|
||||
};
|
||||
static const eMenu town_choices[] = {
|
||||
eMenu::TOWN_DETAILS, eMenu::TOWN_WANDERING, eMenu::TOWN_BOUNDARIES, eMenu::FRILL, eMenu::UNFRILL, eMenu::TOWN_AREAS,
|
||||
eMenu::NONE, eMenu::TOWN_ITEMS_RANDOM, eMenu::TOWN_ITEMS_NOT_PROPERTY, eMenu::TOWN_ITEMS_CLEAR, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::TOWN_SPECIALS, eMenu::TOWN_TEXT, eMenu::TOWN_SIGNS, eMenu::TOWN_ADVANCED, eMenu::TOWN_TIMERS,
|
||||
};
|
||||
static const eMenu out_choices[] = {
|
||||
eMenu::OUT_DETAILS, eMenu::OUT_WANDERING, eMenu::OUT_ENCOUNTERS, eMenu::FRILL, eMenu::UNFRILL, eMenu::OUT_AREAS,
|
||||
eMenu::NONE, eMenu::OUT_START, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::OUT_SPECIALS, eMenu::OUT_TEXT, eMenu::OUT_SIGNS,
|
||||
};
|
||||
static const eMenu help_choices[] = {
|
||||
eMenu::HELP_INDEX, eMenu::ABOUT, eMenu::NONE, eMenu::HELP_START, eMenu::HELP_TEST, eMenu::HELP_DIST,
|
||||
};
|
||||
|
||||
HMENU file_menu = GetSubMenu(menuHandle, FILE_MENU_POS);
|
||||
HMENU edit_menu = GetSubMenu(menuHandle, EDIT_MENU_POS);
|
||||
HMENU scen_menu = GetSubMenu(menuHandle, SCEN_MENU_POS);
|
||||
HMENU town_menu = GetSubMenu(menuHandle, TOWN_MENU_POS);
|
||||
HMENU out_menu = GetSubMenu(menuHandle, OUT_MENU_POS);
|
||||
HMENU help_menu = GetSubMenu(menuHandle, HELP_MENU_POS);
|
||||
|
||||
int i = 0;
|
||||
for(eMenu opt : file_choices)
|
||||
setMenuCommand(file_menu, i++, opt);
|
||||
i = 0;
|
||||
for(eMenu opt : edit_choices)
|
||||
setMenuCommand(edit_menu, i++, opt);
|
||||
i = 0;
|
||||
for(eMenu opt : scen_choices)
|
||||
setMenuCommand(scen_menu, i++, opt);
|
||||
i = 0;
|
||||
for(eMenu opt : town_choices)
|
||||
setMenuCommand(town_menu, i++, opt);
|
||||
i = 0;
|
||||
for(eMenu opt : out_choices)
|
||||
setMenuCommand(out_menu, i++, opt);
|
||||
i = 0;
|
||||
for(eMenu opt : help_choices)
|
||||
setMenuCommand(help_menu, i++, opt);
|
||||
}
|
||||
|
||||
void update_item_menu() {
|
||||
@@ -158,79 +227,7 @@ LRESULT CALLBACK menuProc(HWND handle, UINT message, WPARAM wParam, LPARAM lPara
|
||||
handle_item_menu(cmd - 10000);
|
||||
} else if(cmd >= 20000 && cmd < 30000) { // Monster menus
|
||||
handle_monst_menu(cmd - 20000);
|
||||
} else switch(cmd) {
|
||||
// File menu
|
||||
case IDM_FILE_NEW: handle_file_menu(3); break;
|
||||
case IDM_FILE_OPEN: handle_file_menu(1); break;
|
||||
case IDM_FILE_CLOSE: break;
|
||||
case IDM_FILE_SAVE: handle_file_menu(2); break;
|
||||
case IDM_FILE_REVERT: break;
|
||||
case IDM_FILE_QUIT: handle_file_menu(5); break;
|
||||
// Edit menu
|
||||
case IDM_EDIT_UNDO: handle_edit_menu(1); break;
|
||||
case IDM_EDIT_REDO: handle_edit_menu(2); break;
|
||||
case IDM_EDIT_CUT: handle_edit_menu(4); break;
|
||||
case IDM_EDIT_COPY: handle_edit_menu(5); break;
|
||||
case IDM_EDIT_PASTE: handle_edit_menu(6); break;
|
||||
case IDM_EDIT_DELETE: handle_edit_menu(7); break;
|
||||
case IDM_EDIT_SELECT: handle_edit_menu(8); break;
|
||||
// Scenario menu
|
||||
case IDM_SCEN_NEW_TOWN: handle_scenario_menu(1); break;
|
||||
case IDM_SCEN_DETAILS: handle_scenario_menu(3); break;
|
||||
case IDM_SCEN_INTRO: handle_scenario_menu(4); break;
|
||||
case IDM_SCEN_START: handle_scenario_menu(4); break;
|
||||
case IDM_SCEN_PASSWORD: break;
|
||||
// Scenario menu (advanced)
|
||||
case IDM_SCEN_ADV_SPECIALS: handle_scenario_menu(9); break;
|
||||
case IDM_SCEN_ADV_TEXT: handle_scenario_menu(10); break;
|
||||
case IDM_SCEN_ADV_JOURNAL: handle_scenario_menu(11); break;
|
||||
case IDM_SCEN_ADV_IMPORT_TOWN: handle_scenario_menu(12); break;
|
||||
case IDM_SCEN_ADV_SAVE_RECTS: handle_scenario_menu(13); break;
|
||||
case IDM_SCEN_ADV_HORSES: handle_scenario_menu(14); break;
|
||||
case IDM_SCEN_ADV_BOATS: handle_scenario_menu(15); break;
|
||||
case IDM_SCEN_ADV_TOWN_VARY: handle_scenario_menu(16); break;
|
||||
case IDM_SCEN_ADV_EVENTS: handle_scenario_menu(17); break;
|
||||
case IDM_SCEN_ADV_SHORTCUTS: handle_scenario_menu(18); break;
|
||||
case IDM_SCEN_ADV_DELETE_TOWN: handle_scenario_menu(19); break;
|
||||
case IDM_SCEN_ADV_DATA_DUMP: handle_scenario_menu(20); break;
|
||||
case IDM_SCEN_ADV_TEXT_DUMP: handle_scenario_menu(21); break;
|
||||
// Town menu
|
||||
case IDM_TOWN_DETAILS: handle_town_menu(1); break;
|
||||
case IDM_TOWN_WANDER: handle_town_menu(2); break;
|
||||
case IDM_TOWN_BOUNDS: handle_town_menu(3); break;
|
||||
case IDM_TOWN_FRILL: handle_town_menu(4); break;
|
||||
case IDM_TOWN_UNFRILL: handle_town_menu(5); break;
|
||||
case IDM_TOWN_AREAS: handle_town_menu(6); break;
|
||||
case IDM_TOWN_RANDOM_ITEMS: handle_town_menu(8); break;
|
||||
case IDM_TOWN_NOT_PROPERTY: handle_town_menu(9); break;
|
||||
case IDM_TOWN_CLEAR_ITEMS: handle_town_menu(10); break;
|
||||
// Town menu (advanced)
|
||||
case IDM_TOWN_ADV_SPECIALS: handle_town_menu(13); break;
|
||||
case IDM_TOWN_ADV_TEXT: handle_town_menu(14); break;
|
||||
case IDM_TOWN_ADV_SIGNS: handle_town_menu(15); break;
|
||||
case IDM_TOWN_ADV_DETAILS: handle_town_menu(16); break;
|
||||
case IDM_TOWN_ADV_EVENTS: handle_town_menu(17); break;
|
||||
case IDM_TOWN_ADV_REPORT: break;
|
||||
// Outdoors menu
|
||||
case IDM_OUT_DETAILS: handle_outdoor_menu(1); break;
|
||||
case IDM_OUT_WANDER: handle_outdoor_menu(2); break;
|
||||
case IDM_OUT_ENCOUNTER: handle_outdoor_menu(3); break;
|
||||
case IDM_OUT_FRILL: handle_outdoor_menu(4); break;
|
||||
case IDM_OUT_UNFRILL: handle_outdoor_menu(5); break;
|
||||
case IDM_OUT_AREAS: handle_outdoor_menu(6); break;
|
||||
case IDM_OUT_START: handle_outdoor_menu(8); break;
|
||||
// Outdoors menu (advanced)
|
||||
case IDM_OUT_ADV_SPECIALS: handle_outdoor_menu(11); break;
|
||||
case IDM_OUT_ADV_TEXT: handle_outdoor_menu(12); break;
|
||||
case IDM_OUT_ADV_SIGNS: handle_outdoor_menu(13); break;
|
||||
case IDM_OUT_ADV_REPORT: break;
|
||||
// Help menu
|
||||
case IDM_HELP_INDEX: ShellExecuteA(NULL, "open", "https://calref.net/~sylae/boe-doc/editor/About.html", NULL, NULL, SW_SHOWNORMAL); break;
|
||||
case IDM_HELP_ABOUT: handle_help_menu(0); break;
|
||||
case IDM_HELP_START: handle_help_menu(1); break;
|
||||
case IDM_HELP_TEST: handle_help_menu(2); break;
|
||||
case IDM_HELP_DISTRIBUTE: handle_help_menu(3); break;
|
||||
}
|
||||
} else handle_menu_choice(menuChoices[message]);
|
||||
} else if(message == WM_SETCURSOR) {
|
||||
// Windows resets the cursor to an arrow whenever the mouse moves, unless we do this.
|
||||
// Note: By handling this message, sf::Window::setMouseCursorVisible() will NOT work.
|
||||
|
@@ -20,6 +20,7 @@ void makeFrontWindow(sf::Window& win);
|
||||
void setWindowFloating(sf::Window& win, bool floating);
|
||||
|
||||
void init_fileio();
|
||||
void launchURL(std::string url);
|
||||
|
||||
fs::path nav_get_party();
|
||||
fs::path nav_put_party(fs::path def = "");
|
||||
|
@@ -145,6 +145,10 @@ void beep() {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
void launchURL(std::string url) {
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithCString:url.c_str() encoding:NSUTF8StringEncoding]]];
|
||||
}
|
||||
|
||||
int getMenubarHeight() {
|
||||
// Mac menubar isn't in the window, so we return 0 here.
|
||||
return 0;
|
||||
|
@@ -213,6 +213,10 @@ void beep() {
|
||||
MessageBeep(-1);
|
||||
}
|
||||
|
||||
void launchURL(std::string url) {
|
||||
ShellExecuteA(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
// TODO: Implement modal session.
|
||||
// It seems that Windows doesn't have anything similar to the Mac modal session, so I might have to somehow simulate it myself.
|
||||
void ModalSession::pumpEvents() {
|
||||
|
Reference in New Issue
Block a user