Skip to content

Commit afdc32f

Browse files
committed
New item selection list dialog
1 parent 9213025 commit afdc32f

File tree

16 files changed

+535
-363
lines changed

16 files changed

+535
-363
lines changed

modules/zquest/ZQuestGUI.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ src/dialog/set_password.cpp
3737
src/dialog/cheat_codes.cpp
3838
src/dialog/common.cpp
3939
src/dialog/info.cpp
40+
src/dialog/info_lister.cpp
4041
src/dialog/about.cpp
4142
src/dialog/subscr_props.cpp
4243
src/dialog/room.cpp

src/dialog/info_lister.cpp

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
#include "info_lister.h"
2+
#include <gui/builder.h>
3+
#include "itemeditor.h"
4+
#include "info.h"
5+
#include "zc_list_data.h"
6+
#include "zquest.h"
7+
#include "zq_misc.h"
8+
#include "zq_class.h"
9+
#include "zq_custom.h"
10+
#include "qst.h"
11+
#include <fmt/format.h>
12+
#include <utility>
13+
14+
extern char *item_string[];
15+
16+
static const std::string def_info_nosel =
17+
"Ctrl+C/Ctrl+V - Copy/Paste"
18+
"\nCtrl+S/Ctrl+L - Save/Load"
19+
"\nDouble-Click - Edit";
20+
static const std::string def_info_sel =
21+
"Ctrl+C/Ctrl+V - Copy/Paste"
22+
"\nCtrl+S/Ctrl+L - Save/Load"
23+
"\nDouble-Click - Confirm";
24+
25+
int lister_index = -1;
26+
27+
std::shared_ptr<GUI::Widget> BasicListerDialog::view()
28+
{
29+
using namespace GUI::Builder;
30+
using namespace GUI::Props;
31+
using namespace GUI::Key;
32+
33+
lister_index = start_ind;
34+
35+
std::shared_ptr<GUI::Widget> okbtn;
36+
if(selecting)
37+
okbtn = Button(
38+
text = "OK",
39+
topPadding = 0.5_em,
40+
minwidth = 90_px,
41+
onClick = message::OK);
42+
else okbtn = DummyWidget();
43+
44+
window = Window(
45+
title = titleTxt,
46+
onClose = message::EXIT,
47+
hPadding = 0_px,
48+
use_vsync = true,
49+
shortcuts={
50+
Ctrl+C=message::COPY,
51+
Ctrl+V=message::PASTE,
52+
Ctrl+S=message::SAVE,
53+
Ctrl+L=message::LOAD,
54+
},
55+
Column(
56+
hPadding = 0_px,
57+
Columns<2>(
58+
widgList = List(data = lister, isABC = true,
59+
selectedValue = selected_index,
60+
rowSpan = 2, fitParent = true,
61+
onSelectFunc = [&](int32_t val)
62+
{
63+
if(selected_index == val)
64+
return;
65+
selected_index = val;
66+
update();
67+
},
68+
onRClickFunc = [&](int32_t val, int32_t x, int32_t y)
69+
{
70+
if(selected_index != val)
71+
{
72+
selected_index = val;
73+
update();
74+
}
75+
forceDraw();
76+
rclick(x,y);
77+
},
78+
onDClick = selecting ? message::OK : message::EDIT),
79+
widgPrev = TileFrame(visible = false),
80+
widgInfo = Label(text = "", fitParent = true)
81+
),
82+
Row(padding = 0_px,
83+
okbtn,
84+
Button(
85+
text = "Edit",
86+
topPadding = 0.5_em,
87+
minwidth = 90_px,
88+
onClick = message::EDIT,
89+
focused = true),
90+
Button(
91+
text = selecting?"Cancel":"Done",
92+
topPadding = 0.5_em,
93+
minwidth = 90_px,
94+
onClick = message::EXIT)
95+
)
96+
)
97+
);
98+
postinit();
99+
update();
100+
return window;
101+
}
102+
103+
bool BasicListerDialog::handleMessage(const GUI::DialogMessage<message>& msg)
104+
{
105+
bool refresh = false;
106+
switch(msg.message)
107+
{
108+
case message::OK:
109+
lister_index = selected_index;
110+
return true;
111+
case message::EXIT:
112+
return true;
113+
case message::EDIT:
114+
edit();
115+
refresh = true;
116+
break;
117+
case message::COPY:
118+
copy();
119+
break;
120+
case message::PASTE:
121+
refresh = paste();
122+
break;
123+
case message::SAVE:
124+
save();
125+
break;
126+
case message::LOAD:
127+
refresh = load();
128+
break;
129+
}
130+
if(refresh)
131+
{
132+
rerun_dlg = true;
133+
return true;
134+
}
135+
return false;
136+
}
137+
138+
static MENU cpsl_rclick_menu[] =
139+
{
140+
{ "&Copy", NULL, NULL, 0, NULL },
141+
{ "Paste &v", NULL, NULL, 0, NULL },
142+
{ "&Save", NULL, NULL, 0, NULL },
143+
{ "&Load", NULL, NULL, 0, NULL },
144+
{ NULL, NULL, NULL, 0, NULL }
145+
};
146+
147+
ItemListerDialog::ItemListerDialog(int itemid, bool selecting):
148+
BasicListerDialog("Select Item",GUI::ZCListData::items(true),itemid,selecting)
149+
{
150+
if(!selecting)
151+
{
152+
lister.removeInd(0); //remove '(None)'
153+
if(selected_index < 0)
154+
selected_index = lister.getValue(0);
155+
}
156+
selected_index = vbound(selected_index, (selecting?-1:0), MAXITEMS-1);
157+
}
158+
void ItemListerDialog::postinit()
159+
{
160+
size_t len = 16;
161+
for(int q = 0; q < MAXITEMS; ++q)
162+
{
163+
size_t tlen = text_length(GUI_DEF_FONT,itemsbuf[q].get_name(true).c_str());
164+
if(tlen > len)
165+
len = tlen;
166+
tlen = text_length(GUI_DEF_FONT,item_string[q]);
167+
if(tlen > len)
168+
len = tlen;
169+
}
170+
widgInfo->minWidth(Size::pixels(len+8));
171+
window->setHelp(selecting ? def_info_sel : def_info_nosel);
172+
}
173+
static int copied_item_id = -1;
174+
void ItemListerDialog::update()
175+
{
176+
std::string copied_name = unsigned(copied_item_id) < MAXITEMS
177+
? itemsbuf[copied_item_id].get_name(true)
178+
: "(None)";
179+
if(unsigned(selected_index) < MAXITEMS)
180+
{
181+
itemdata const& itm = itemsbuf[selected_index];
182+
std::string display_name = itm.display_name[0]
183+
? itm.get_name(true)
184+
: "[No Display Name]";
185+
widgInfo->setText(fmt::format(
186+
"{}\n{}\n#{}\nPower: {}\nLevel: {}"
187+
"\nType: {}\nCSet: {}\nScripts:\nAction: {}\nPickup: {}\nSprite: {}\nWeapon: {}"
188+
"\n\nCopied:\n{}",
189+
item_string[selected_index], display_name, selected_index, itm.power, itm.fam_type,
190+
itm.family, itm.csets, itm.script, itm.collect_script, itm.sprite_script, itm.weaponscript,
191+
copied_name));
192+
widgPrev->setVisible(true);
193+
widgPrev->setDisabled(false);
194+
widgPrev->setTile(itm.tile);
195+
widgPrev->setCSet(itm.csets&0xF);
196+
widgPrev->setFrames(itm.frames);
197+
widgPrev->setSpeed(itm.speed);
198+
widgPrev->setDelay(itm.delay);
199+
widgPrev->setSkipX((itm.overrideFLAGS & itemdataOVERRIDE_TILEWIDTH)
200+
? itm.tilew-1 : 0);
201+
widgPrev->setSkipY((itm.overrideFLAGS & itemdataOVERRIDE_TILEHEIGHT)
202+
? itm.tileh-1 : 0);
203+
widgPrev->setDoSized(true);
204+
}
205+
else
206+
{
207+
widgInfo->setText(fmt::format(
208+
"\n\n\n\n"
209+
"\n\n\n\n\n\n\n"
210+
"\n\nCopied:\n{}",
211+
copied_name));
212+
widgPrev->setVisible(true);
213+
widgPrev->setDisabled(true);
214+
widgPrev->setTile(0);
215+
widgPrev->setCSet(0);
216+
widgPrev->setFrames(0);
217+
widgPrev->setSpeed(0);
218+
widgPrev->setDelay(0);
219+
widgPrev->setSkipX(0);
220+
widgPrev->setSkipY(0);
221+
widgPrev->setDoSized(true);
222+
}
223+
}
224+
void ItemListerDialog::edit()
225+
{
226+
call_item_editor(selected_index);
227+
}
228+
void ItemListerDialog::rclick(int x, int y)
229+
{
230+
SETFLAG(cpsl_rclick_menu[1].flags,D_DISABLED,copied_item_id<0);
231+
232+
int ret=popup_menu(cpsl_rclick_menu, x, y);
233+
234+
if(ret==0)
235+
copy();
236+
else if(ret==1)
237+
paste();
238+
else if(ret==2)
239+
save();
240+
else if(ret==3)
241+
load();
242+
}
243+
void ItemListerDialog::copy()
244+
{
245+
copied_item_id = selected_index;
246+
update();
247+
}
248+
bool ItemListerDialog::paste()
249+
{
250+
if(copied_item_id < 0 || selected_index < 0)
251+
return false;
252+
if(copied_item_id == selected_index)
253+
return false;
254+
itemsbuf[selected_index] = itemsbuf[copied_item_id];
255+
saved = false;
256+
return true;
257+
}
258+
int32_t readoneitem(PACKFILE *f, int32_t id);
259+
int32_t writeoneitem(PACKFILE *f, int32_t id);
260+
void ItemListerDialog::save()
261+
{
262+
if(selected_index < 0)
263+
return;
264+
if(!getname(fmt::format("Save Item '{}' #{} (.zitem)",itemsbuf[selected_index].get_name(true),selected_index).c_str(),"zitem",NULL,datapath,false))
265+
return;
266+
267+
PACKFILE *f=pack_fopen_password(temppath,F_WRITE,"");
268+
if(!f) return;
269+
if (!writeoneitem(f,selected_index))
270+
{
271+
Z_error("Could not write to .zitem packfile %s\n", temppath);
272+
InfoDialog("ZItem Error", "Could not save the specified item.").show();
273+
}
274+
pack_fclose(f);
275+
}
276+
bool ItemListerDialog::load()
277+
{
278+
if(selected_index < 0)
279+
return false;
280+
if(!getname(fmt::format("Load Item (replacing '{}' #{}) (.zitem)",itemsbuf[selected_index].get_name(true),selected_index).c_str(),"zitem",NULL,datapath,false))
281+
return false;
282+
283+
PACKFILE *f=pack_fopen_password(temppath,F_READ,"");
284+
if(!f) return false;
285+
if (!readoneitem(f,selected_index))
286+
{
287+
Z_error("Could not read from .zitem packfile %s\n", temppath);
288+
InfoDialog("ZItem Error", "Could not load the specified item.").show();
289+
}
290+
pack_fclose(f);
291+
saved = false;
292+
return true;
293+
}
294+

src/dialog/info_lister.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#ifndef ZC_DIALOG_INFOLISTER_H
2+
#define ZC_DIALOG_INFOLISTER_H
3+
4+
#include <gui/dialog.h>
5+
#include <gui/label.h>
6+
#include <gui/list.h>
7+
#include <gui/window.h>
8+
#include <zq/gui/tileanim_frame.h>
9+
#include <initializer_list>
10+
#include <string>
11+
#include <set>
12+
#include <string_view>
13+
14+
extern int lister_index;
15+
16+
class BasicListerDialog: public GUI::Dialog<BasicListerDialog>
17+
{
18+
public:
19+
enum class message { OK, EDIT, EXIT, COPY, PASTE, SAVE, LOAD };
20+
21+
BasicListerDialog(std::string title, int start_ind = 0, bool selecting = false) :
22+
titleTxt(title), start_ind(start_ind), selected_index(start_ind), selecting(selecting){};
23+
BasicListerDialog(std::string title, GUI::ListData lister, int start_ind = 0, bool selecting = false) :
24+
titleTxt(title), start_ind(start_ind), selected_index(start_ind), selecting(selecting), lister(lister){};
25+
26+
std::shared_ptr<GUI::Widget> view() override;
27+
virtual bool handleMessage(const GUI::DialogMessage<message>& msg);
28+
protected:
29+
virtual void postinit(){};
30+
virtual void update(){};
31+
virtual void edit(){};
32+
virtual void rclick(int x, int y){};
33+
virtual void copy(){};
34+
virtual bool paste(){return false;};
35+
virtual void save(){};
36+
virtual bool load(){return false;};
37+
38+
std::string titleTxt;
39+
GUI::ListData lister;
40+
int selected_index, start_ind;
41+
bool selecting;
42+
43+
std::shared_ptr<GUI::List> widgList;
44+
std::shared_ptr<GUI::Label> widgInfo;
45+
std::shared_ptr<GUI::TileFrame> widgPrev;
46+
std::shared_ptr<GUI::Window> window;
47+
};
48+
49+
class ItemListerDialog: public BasicListerDialog
50+
{
51+
public:
52+
ItemListerDialog(int itemid = -1, bool selecting = false);
53+
54+
protected:
55+
void postinit() override;
56+
void update() override;
57+
void edit() override;
58+
void rclick(int x, int y) override;
59+
void copy() override;
60+
bool paste() override;
61+
void save() override;
62+
bool load() override;
63+
};
64+
65+
#endif

src/dialog/itemeditor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern script_data *lwpnscripts[NUMSCRIPTWEAPONS];
2727
#define ISCRDATA_ALL 0x07
2828
void call_item_editor(int32_t index)
2929
{
30+
if(unsigned(index) >= MAXITEMS) return;
3031
item_use_script_data = zc_get_config("zquest","show_itemscript_meta_type",ISCRDATA_ALL)&ISCRDATA_ALL;
3132
_reset_default = false;
3233
ItemEditorDialog(index).show();

src/gui/builder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ ZCGUI_BUILDER_START(List)
336336
ZCGUI_ACCEPT_PROP(selectedValue, setSelectedValue, int32_t)
337337
ZCGUI_ACCEPT_PROP(selectedIndex, setSelectedIndex, int32_t)
338338
ZCGUI_ACCEPT_PROP(onSelectionChanged, onSelectionChanged, Dialog::message)
339+
ZCGUI_ACCEPT_PROP(onRClick, onRClick, Dialog::message)
340+
ZCGUI_ACCEPT_PROP(onDClick, onDClick, Dialog::message)
341+
ZCGUI_ACCEPT_PROP(onRClickFunc, setOnRClickFunc, std::function<void(int32_t,int32_t,int32_t)>)
342+
ZCGUI_ACCEPT_PROP(onDClickFunc, setOnDClickFunc, std::function<void(int32_t,int32_t,int32_t)>)
339343
ZCGUI_ACCEPT_PROP(onSelectFunc, setOnSelectFunc, std::function<void(int32_t)>)
340344
ZCGUI_ACCEPT_PROP(isABC, setIsABC, bool)
341345

0 commit comments

Comments
 (0)