allow labeled cPictChoice variant

This commit is contained in:
2025-08-27 13:30:21 -05:00
parent c947029c5c
commit 456c05d4ff
5 changed files with 78 additions and 11 deletions

View File

@@ -0,0 +1,38 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!-- NOTE: This file should be updated to use relative positioning the next time it changes. -->
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<dialog defbtn='done' escbtn='cancel'>
<pict name='mainpic' type='dlog' num='16' top='6' left='6'/>
<text name='prompt' size='large' top='6' left='50' width='248' height='14'>Select a graphic:</text>
<group name='group'>
<led name='led1' state='off' top='29' left='55' width='57' height='36'/>
<led name='led2' state='off' top='74' left='55' width='57' height='36'/>
<led name='led3' state='off' top='119' left='55' width='57' height='36'/>
<led name='led4' state='off' top='164' left='55' width='57' height='36'/>
<led name='led5' state='off' top='209' left='55' width='57' height='36'/>
<led name='led6' state='off' top='254' left='55' width='57' height='36'/>
<led name='led7' state='off' top='29' left='251' width='57' height='36'/>
<led name='led8' state='off' top='74' left='251' width='57' height='36'/>
<led name='led9' state='off' top='119' left='251' width='57' height='36'/>
<led name='led10' state='off' top='164' left='251' width='57' height='36'/>
<led name='led11' state='off' top='209' left='251' width='57' height='36'/>
<led name='led12' state='off' top='254' left='251' width='57' height='36'/>
</group>
<pict name='pic1' type='ter' num='0' top='29' left='76'/>
<pict name='pic2' type='ter' num='1' top='74' left='76'/>
<pict name='pic3' type='ter' num='2' top='119' left='76'/>
<pict name='pic4' type='ter' num='3' top='164' left='76'/>
<pict name='pic5' type='ter' num='4' top='209' left='76'/>
<pict name='pic6' type='ter' num='5' top='254' left='76'/>
<pict name='pic7' type='ter' num='18' top='29' left='272'/>
<pict name='pic8' type='ter' num='19' top='74' left='272'/>
<pict name='pic9' type='ter' num='20' top='119' left='272'/>
<pict name='pic10' type='ter' num='21' top='164' left='272'/>
<pict name='pic11' type='ter' num='22' top='209' left='272'/>
<pict name='pic12' type='ter' num='23' top='254' left='272'/>
<text name='help' top='294' left='6' width='422' height='16'>Click button to left of graphic to select. Use arrows to change pages.</text>
<button name='left' type='left' top='314' left='6' def-key='left'/>
<button name='right' type='right' top='314' left='69' def-key='right'/>
<button name='done' type='done' top='314' left='393'/>
<button name='cancel' type='regular' top='314' left='322'>Cancel</button>
</dialog>

View File

@@ -935,6 +935,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;

View File

@@ -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<pic_num_t>& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {}
cPictChoice::cPictChoice(const std::vector<pic_num_t>& pics, const std::vector<std::string> 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<std::pair<pic_num_t,ePicType>>& 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<cPict&>(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);

View File

@@ -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<std::pair<pic_num_t,ePicType>> picts;
std::vector<std::string> labels;
size_t page, cur;
cLedGroup* leds;
std::function<void(cPictChoice&,int)> 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<pic_num_t>& 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<pic_num_t>& pics, const std::vector<std::string> 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.

View File

@@ -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<pic_num_t> pics = {3,0,2,1,5,4,3,3,6,1};
static const std::vector<std::string> damageNames = {"Weapon", "Fire", "Poison", "Magic", "Weird", "Cold", "Undead", "Demon", "Acid", "Unblockable"};
std::vector<pic_num_t> 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;