Add dialog allowing you to alter the scenario's graphics sheets from within the scenario editor
- You can copy/paste images into the sheet, or import/export to/from png files Also: - Picture controls in the dialog engine have a new "scaled" flag; if set, the picture will be scaled into the provided bounds rather than overflowing. Currently, only full sheets honour the setting.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "scen.global.hpp"
|
||||
#include "scenario.hpp"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "stack.hpp"
|
||||
#include "spell.hpp"
|
||||
#include "mathutil.hpp"
|
||||
#include "winutil.hpp"
|
||||
|
||||
extern short cen_x, cen_y,cur_town;
|
||||
extern bool mouse_button_held;
|
||||
@@ -3305,3 +3307,103 @@ void edit_custom_pics_types() {
|
||||
}
|
||||
pic_dlg.run();
|
||||
}
|
||||
|
||||
void set_dlg_custom_sheet(cDialog& me, size_t sheet) {
|
||||
me["num"].setTextToNum(sheet);
|
||||
dynamic_cast<cPict&>(me["sheet"]).setPict(sheet, PIC_FULL);
|
||||
}
|
||||
|
||||
void edit_custom_sheets() {
|
||||
// TODO: What about "disconnected" sheets? eg, we have sheets 0-6, but also sheet 100.
|
||||
// First, make sure we even have custom graphics! Also make sure they're not legacy format.
|
||||
if(spec_scen_g.numSheets < 1) {
|
||||
} else if(spec_scen_g.is_old) {
|
||||
spec_scen_g.convert_sheets();
|
||||
}
|
||||
|
||||
set_cursor(watch_curs);
|
||||
|
||||
// Get image data from the sheets in memory
|
||||
size_t cur = 0;
|
||||
std::unordered_map<size_t, sf::Image> sheets;
|
||||
for(size_t i = 0; i < spec_scen_g.numSheets; i++) {
|
||||
sheets[i] = spec_scen_g.sheets[i].copyToImage();
|
||||
}
|
||||
auto sheetsSave = sheets;
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
cDialog pic_dlg("graphic-sheets");
|
||||
pic_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, _1, false));
|
||||
pic_dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, _1, true));
|
||||
pic_dlg["copy"].attachClickHandler([&sheets,&cur](cDialog&, std::string, eKeyMod) -> bool {
|
||||
set_clipboard_img(sheets[cur]);
|
||||
return true;
|
||||
});
|
||||
pic_dlg["paste"].attachClickHandler([&sheets,&cur](cDialog&, std::string, eKeyMod) -> bool {
|
||||
auto img = get_clipboard_img();
|
||||
if(img == nullptr) {
|
||||
beep();
|
||||
return true;
|
||||
}
|
||||
sheets[cur] = *img;
|
||||
spec_scen_g.replace_sheet(cur, *img);
|
||||
return true;
|
||||
});
|
||||
pic_dlg["open"].attachClickHandler([&sheets,&cur](cDialog&, std::string, eKeyMod) -> bool {
|
||||
fs::path fpath = nav_get_rsrc({"png", "bmp", "jpg", "jpeg", "gif", "psd"});
|
||||
if(fpath.empty()) return true;
|
||||
sf::Image img;
|
||||
if(!img.loadFromFile(fpath.string().c_str())) {
|
||||
beep();
|
||||
return true;
|
||||
}
|
||||
sheets[cur] = img;
|
||||
spec_scen_g.replace_sheet(cur, img);
|
||||
return true;
|
||||
});
|
||||
pic_dlg["save"].attachClickHandler([&sheets,&cur](cDialog&, std::string, eKeyMod) -> bool {
|
||||
fs::path fpath = nav_put_rsrc({"png", "bmp", "jpg", "jpeg"});
|
||||
if(fpath.empty()) return true;
|
||||
sheets[cur].saveToFile(fpath.string().c_str());
|
||||
return true;
|
||||
});
|
||||
|
||||
// TODO: These buttons not implemented yet
|
||||
pic_dlg["new"].hide();
|
||||
pic_dlg["del"].hide();
|
||||
|
||||
if(spec_scen_g.numSheets == 1) {
|
||||
pic_dlg["left"].hide();
|
||||
pic_dlg["right"].hide();
|
||||
} else pic_dlg.attachClickHandlers([&sheets,&cur](cDialog& me, std::string dir, eKeyMod) -> bool {
|
||||
if(dir == "left") {
|
||||
if(cur == 0)
|
||||
cur = spec_scen_g.numSheets - 1;
|
||||
else cur--;
|
||||
} else if(dir == "right") {
|
||||
cur++;
|
||||
if(cur >= spec_scen_g.numSheets)
|
||||
cur = 0;
|
||||
} else return true;
|
||||
set_dlg_custom_sheet(me, cur);
|
||||
return true;
|
||||
}, {"left", "right"});
|
||||
|
||||
set_dlg_custom_sheet(pic_dlg, cur);
|
||||
shut_down_menus(5); // So that cmd+O, cmd+N, cmd+S can work
|
||||
pic_dlg.run();
|
||||
|
||||
// Now, we need to restore the sheets if they pressed cancel
|
||||
if(!pic_dlg.accepted()) {
|
||||
for(auto p : sheetsSave) {
|
||||
spec_scen_g.replace_sheet(p.first, p.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore menus
|
||||
shut_down_menus(4);
|
||||
if(overall_mode <= MODE_MAIN_SCREEN)
|
||||
shut_down_menus(editing_town ? 2 : 1);
|
||||
else shut_down_menus(3);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
|
||||
class cDialog;
|
||||
|
||||
void edit_custom_sheets();
|
||||
void edit_custom_pics_types();
|
||||
bool edit_ter_type(ter_num_t which_ter);
|
||||
bool edit_monst_type(short which_monst);
|
||||
|
@@ -296,6 +296,10 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
set_starting_loc();
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::SCEN_SHEETS:
|
||||
edit_custom_sheets();
|
||||
change_made = true;
|
||||
break;
|
||||
case eMenu::SCEN_PICS:
|
||||
edit_custom_pics_types();
|
||||
change_made = true;
|
||||
|
@@ -23,7 +23,7 @@ enum class eMenu {
|
||||
SCEN_SAVE_ITEM_RECTS, SCEN_HORSES, SCEN_BOATS,
|
||||
TOWN_VARYING, SCEN_TIMERS, SCEN_ITEM_SHORTCUTS, TOWN_DELETE,
|
||||
SCEN_DATA_DUMP, SCEN_TEXT_DUMP,
|
||||
SCEN_PICS,
|
||||
SCEN_PICS, SCEN_SHEETS,
|
||||
// Town menu
|
||||
TOWN_DETAILS, TOWN_WANDERING, TOWN_BOUNDARIES, TOWN_AREAS,
|
||||
TOWN_ITEMS_RANDOM, TOWN_ITEMS_NOT_PROPERTY, TOWN_ITEMS_CLEAR,
|
||||
|
@@ -52,7 +52,7 @@ void init_menubar() {
|
||||
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::SCEN_PICS, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, 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,
|
||||
@@ -96,6 +96,7 @@ void init_menubar() {
|
||||
}
|
||||
|
||||
// mode 0 - initial shut down, 1 - no town, 2 - no out, 3 - no town or out 4 - all menus on
|
||||
// 5 - disable file/edit menus
|
||||
// TODO: Use an enum here
|
||||
void shut_down_menus(short mode) {
|
||||
if(mode == 0) {
|
||||
@@ -105,6 +106,8 @@ void shut_down_menus(short mode) {
|
||||
[[menu_bar_handle itemWithTitle: @"Outdoors"] setEnabled: NO];
|
||||
}
|
||||
if(mode == 4) {
|
||||
[[menu_bar_handle itemWithTitle: @"File"] setEnabled: YES];
|
||||
[[menu_bar_handle itemWithTitle: @"Edit"] setEnabled: YES];
|
||||
[[file_menu itemWithTitle: @"Save"] setEnabled: YES];
|
||||
[[menu_bar_handle itemWithTitle: @"Scenario"] setEnabled: YES];
|
||||
[[menu_bar_handle itemWithTitle: @"Town"] setEnabled: YES];
|
||||
@@ -130,6 +133,10 @@ void shut_down_menus(short mode) {
|
||||
if([[item title] length] > 0 && [[item title] characterAtIndex: 0] != ' ')
|
||||
[item setEnabled: NO];
|
||||
}
|
||||
if(mode == 5) {
|
||||
[[menu_bar_handle itemWithTitle: @"File"] setEnabled: NO];
|
||||
[[menu_bar_handle itemWithTitle: @"Edit"] setEnabled: NO];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation MenuHandler
|
||||
|
@@ -80,7 +80,7 @@ void init_menubar() {
|
||||
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::SCEN_PICS, eMenu::NONE, eMenu::NONE,
|
||||
eMenu::TOWN_CREATE, eMenu::NONE, eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::TOWN_START, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, 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,
|
||||
|
Reference in New Issue
Block a user