diff --git a/rsrc/dialogs/choose-pict-labeled.xml b/rsrc/dialogs/choose-pict-labeled.xml new file mode 100644 index 000000000..a42083e9a --- /dev/null +++ b/rsrc/dialogs/choose-pict-labeled.xml @@ -0,0 +1,38 @@ + + + + + + Select a graphic: + + + + + + + + + + + + + + + + + + + + + + + + + + + Click button to left of graphic to select. Use arrows to change pages. + + diff --git a/src/dialogxml/dialogs/dialog.cpp b/src/dialogxml/dialogs/dialog.cpp index 31470b27d..982c1fdbd 100644 --- a/src/dialogxml/dialogs/dialog.cpp +++ b/src/dialogxml/dialogs/dialog.cpp @@ -937,6 +937,7 @@ bool cDialog::addLabelFor(std::string key, std::string label, eLabelPos where, s cControl& ctrl = this->getControl(key); key += "-label"; rectangle labelRect = ctrl.getBounds(); + // TODO I think these are completely wrong? But am afraid of changing it having unintended impacts. switch(where) { case LABEL_LEFT: labelRect.right = labelRect.left; diff --git a/src/dialogxml/dialogs/pictchoice.cpp b/src/dialogxml/dialogs/pictchoice.cpp index 381f9ffb9..c5b24e55d 100644 --- a/src/dialogxml/dialogs/pictchoice.cpp +++ b/src/dialogxml/dialogs/pictchoice.cpp @@ -17,8 +17,21 @@ static DialogDefn& loadDefn() { return *ResMgr::dialogs.get("choose-pict"); } +static DialogDefn& loadDefnLabeled() { + return *ResMgr::dialogs.get("choose-pict-labeled"); +} + cPictChoice::cPictChoice(const std::vector& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {} +cPictChoice::cPictChoice(const std::vector& pics, const std::vector labels, ePicType t, cDialog* parent) + : dlg(loadDefnLabeled(),parent), labels(labels), per_page(PER_PAGE_LABELED) { + + for(auto iter = pics.begin(); iter != pics.end(); iter++) { + picts.push_back({*iter,t}); + } + attachHandlers(); +} + cPictChoice::cPictChoice(const std::vector>& pics,cDialog* parent) : dlg(loadDefn(),parent) { picts = pics; attachHandlers(); @@ -91,10 +104,16 @@ void cPictChoice::fillPage(){ clear_sstr(sout); sout << "pic" << i + 1; cPict& pic = dynamic_cast(dlg[sout.str()]); - if(page * per_page + i < picts.size()){ + int idx = page * per_page + i; + if(idx < picts.size()){ pic.show(); - ePicType tp = picts[per_page * page + i].second; - pic.setPict(picts[per_page * page + i].first, tp); + if(labels.size() > idx){ + // TODO clicking on the label text will not trigger the led/pict's click handler + dlg.addLabelFor(sout.str(), labels[idx], LABEL_RIGHT, 4, false); + // TODO the offset of 4 is not working + } + ePicType tp = picts[idx].second; + pic.setPict(picts[idx].first, tp); rectangle b = pic.getBounds(); if(tp == PIC_DLOG_LG || tp == PIC_CUSTOM_DLOG_LG || tp == PIC_SCEN_LG) { pic.setFormat(TXT_WRAP, false); diff --git a/src/dialogxml/dialogs/pictchoice.hpp b/src/dialogxml/dialogs/pictchoice.hpp index cd8f88ff9..b8876b9ae 100644 --- a/src/dialogxml/dialogs/pictchoice.hpp +++ b/src/dialogxml/dialogs/pictchoice.hpp @@ -20,7 +20,10 @@ /// A dialog that presents a list of icons with LEDs and allows you to choose one. /// The list may span several pages. class cPictChoice { - static const size_t per_page = 36; + static const size_t PER_PAGE_DEFAULT = 36; // 6 columns of 6 + static const size_t PER_PAGE_LABELED = 12; // 2 columns of 6 with space between + size_t per_page = PER_PAGE_DEFAULT; + bool didAccept; cDialog dlg; void attachHandlers(); @@ -31,6 +34,7 @@ class cPictChoice { bool onSelect(bool losing); void fillPage(); std::vector> picts; + std::vector labels; size_t page, cur; cLedGroup* leds; std::function select_handler; @@ -40,6 +44,12 @@ public: /// @param t The type of icons to show; all icons are assumed to be of the same type. /// @param parent Optionally, a parent dialog. cPictChoice(const std::vector& pics, ePicType t, cDialog* parent = nullptr); + /// Initializes a dialog from a list of icons with labels. + /// @param pics A list of all icons in the dialog. + /// @param labels A list of all icon labels + /// @param t The type of icons to show; all icons are assumed to be of the same type. + /// @param parent Optionally, a parent dialog. + cPictChoice(const std::vector& pics, const std::vector labels, ePicType t, cDialog* parent = nullptr); /// Initializes a dialog from a list of icons. /// @param pics A list of all icons in the dialog as {num,type} pairs. /// @param parent Optionally, a parent dialog. diff --git a/src/scenedit/scen.keydlgs.cpp b/src/scenedit/scen.keydlgs.cpp index 1625d4623..300541e88 100644 --- a/src/scenedit/scen.keydlgs.cpp +++ b/src/scenedit/scen.keydlgs.cpp @@ -1132,16 +1132,15 @@ short choose_field_type(short cur, cDialog* parent, bool includeSpec) { } pic_num_t choose_damage_type(short cur, cDialog* parent, bool allow_spec) { - static const char*const damageNames[] = {"Weapon", "Fire", "Poison", "Magic", "Weird", "Cold", "Undead", "Demon", "Acid", "Unblockable"}; - static const std::vector pics = {3,0,2,1,5,4,3,3,6,1}; + static const std::vector damageNames = {"Weapon", "Fire", "Poison", "Magic", "Weird", "Cold", "Undead", "Demon", "Acid", "Unblockable"}; + std::vector pics = {3,0,2,1,5,4,3,3,6,1}; short prev = cur; if(cur < 0 || cur >= pics.size()) cur = 0; - cPictChoice pic_dlg(pics.begin(), pics.end() - !allow_spec, PIC_BOOM, parent); + if(!allow_spec){ + pics.pop_back(); + } + cPictChoice pic_dlg(pics, damageNames, PIC_BOOM, parent); pic_dlg->getControl("prompt").setText("Select a damage type:"); - pic_dlg->getControl("help").setText(damageNames[cur]); - pic_dlg.attachSelectHandler([](cPictChoice& me, int n) { - me->getControl("help").setText(damageNames[n]); - }); bool made_choice = pic_dlg.show(cur); size_t item_hit = pic_dlg.getSelected(); return made_choice ? item_hit : prev;