Lots of little tweaks and fixes to various things, mostly dialog stuff.

- LED groups now trigger their own click handler in addition to the clicked LED's click handler (provided the latter returns true). If the handler returns false, the click has no effect.
- LED groups now cancel the selection change if their focus handler returns false; this mimics the behaviour when an individual LED's focus handler returns false.
- Move the dialog getResult() definitions inline - since there's only two of them now that I'm using boost::any, having them in a separate file is pointless.
- Changed how the pict choice dialog returns its result - now it returns only whether the user clicked cancel and provides getters to obtain the number and type.
- Pict and string choice dialogs now hide the arrow buttons when there is only one page of options.
- Fix pict choice dialog always returning the initially selected value (similar to how the string choice dialog did before I fixed it)
- When passed an invalid starting selection, the pict choice dialog now always starts with the first icon selected
- Fix wrong bounds for several typs of custom graphics in dialogs
- Fix wrong /source/ bounds for custom 28x36 graphics /everywhere in the game/.
- Fix select PC graphic dialog having a second page with an invalid graphic that can be selected.
This commit is contained in:
2014-12-05 23:48:07 -05:00
parent 4db81f1403
commit 56f73cb156
15 changed files with 128 additions and 107 deletions

View File

@@ -342,29 +342,35 @@ bool cLedGroup::triggerClickHandler(cDialog& me, std::string id, eKeyMod mods){
clicking = "";
if(choices[which_clicked]->triggerClickHandler(me,which_clicked,mods)){
eLedState a, b;
if(curSelect.empty()) a = led_off;
else {
a = choices[curSelect]->getState();
if(onClick && !onClick(me,id,mods)) return false;
if(!curSelect.empty()) {
choices[curSelect]->setState(led_off);
if(!choices[curSelect]->triggerFocusHandler(me,curSelect,true)){
choices[curSelect]->setState(a);
choices[which_clicked]->setState(b);
choices[curSelect]->setState(led_red);
return false;
}
}
b = choices[which_clicked]->getState();
choices[which_clicked]->setState(led_red);
if(!choices[which_clicked]->triggerFocusHandler(me,which_clicked,false)){
if(!curSelect.empty())
choices[curSelect]->setState(a);
choices[which_clicked]->setState(b);
choices[curSelect]->setState(led_red);
choices[which_clicked]->setState(led_off);
return false;
}
curSelect = which_clicked;
}else return false;
return triggerFocusHandler(me,id,false);
std::string savePrevSelect = prevSelect;
prevSelect = curSelect;
curSelect = which_clicked;
if(!triggerFocusHandler(me,id,false)) {
if(!curSelect.empty())
choices[curSelect]->setState(led_red);
choices[which_clicked]->setState(led_off);
curSelect = prevSelect;
prevSelect = savePrevSelect;
return false;
}
return true;
}
bool cLedGroup::triggerFocusHandler(cDialog& me, std::string id, bool losingFocus){

View File

@@ -1152,6 +1152,7 @@ bool cDialog::toast(bool triggerFocus){
}
bool cDialog::setFocus(cTextField* newFocus, bool force) {
// TODO: Should check that there IS a currently focused field (which might not be the case if there are no fields at all).
if(!force) {
if(!this->getControl(currentFocus).triggerFocusHandler(*this, currentFocus, true)) return false;
}
@@ -1255,6 +1256,8 @@ std::string cDialog::process_keystroke(cKey keyHit){
}
std::string cDialog::process_click(location where){
// TODO: Return list of all controls whose bounding rect contains the clicked point.
// Then the return value of the click handler can mean "Don't pass this event on to other things below me".
ctrlIter iter = controls.begin();
while(iter != controls.end()){
if(iter->second->isVisible() && iter->second->isClickable() && where.in(iter->second->getBounds())){

View File

@@ -55,8 +55,12 @@ public:
bool remove(std::string key); // returns true if the key existed and was removed, false if the key did not exist
bool addLabelFor(std::string key, std::string label, eLabelPos where, short offset, bool bold); // returns true if the label was added
void run(); // cd_run_dialog
template<class type> type getResult();
template<class type> void setResult(const type& val);
template<typename type> type getResult(){
return boost::any_cast<type>(result);
}
template<typename type> void setResult(const type& val){
result = val;
}
void setBg(short n);
void setDefTextClr(sf::Color clr);
void setDefBtn(std::string defBtn);
@@ -132,6 +136,4 @@ public:
const char* what() throw();
};
#include "dialog.results.h" // public template definitions
#endif

View File

@@ -23,7 +23,7 @@ enum eSpecKey {
key_esc, key_enter, key_tab, key_help, // key_help should bind to the help key on Mac and the F1 key on Windows
key_bsp, key_del, key_home, key_end, key_pgup, key_pgdn, // TODO: Implement these
key_copy, key_cut, key_paste, key_selectall
// On Mac, command-left should trigger key_home; command-right should trigger key_end;
// TODO: On Mac, command-left should trigger key_home; command-right should trigger key_end;
// command-up should trigger key_pgup; and command-down should trigger key_pgdn.
// This is in addition to the home, end, pgup, pgdn keys triggering these.
};

View File

@@ -1,17 +0,0 @@
/*
* dialog.results.h
* BoE
*
* Created by Celtic Minstrel on 06/06/09.
*
*/
// Functions for allowing the dialog to have a result which can be of any type.
template<typename type> inline void cDialog::setResult(const type& val){
result = val;
}
template<typename type> inline type cDialog::getResult(){
return boost::any_cast<type>(result);
}

View File

@@ -26,7 +26,7 @@ const size_t cPictChoice::per_page = 36;
cPictChoice::cPictChoice(std::vector<pic_num_t>& pics,ePicType t,cDialog* parent) : cPictChoice(pics.begin(), pics.end(), t, parent) {}
cPictChoice::cPictChoice(std::vector<std::pair<pic_num_t,ePicType>>& pics,cDialog* parent) : dlg("choose-pict.xml",parent) {
attachClickHandlers();
attachHandlers();
picts = pics;
sort(picts.begin(),picts.end());
}
@@ -37,45 +37,49 @@ cPictChoice::cPictChoice(
ePicType t,
cDialog* parent
) : dlg("choose-pict.xml",parent) {
attachClickHandlers();
for(auto iter = begin; iter != end; iter++) {
picts.push_back({*iter,t});
}
sort(picts.begin(),picts.end());
attachHandlers();
}
cPictChoice::cPictChoice(pic_num_t first, pic_num_t last, ePicType t, cDialog* parent) : dlg("choose-pict.xml",parent) {
attachClickHandlers();
for(pic_num_t i = first; i <= last; i++) {
picts.push_back({i,t});
}
sort(picts.begin(),picts.end());
attachHandlers();
}
void cPictChoice::attachClickHandlers() {
void cPictChoice::attachHandlers() {
using namespace std::placeholders;
dlg["left"].attachClickHandler(std::bind(&cPictChoice::onLeft,this));
dlg["right"].attachClickHandler(std::bind(&cPictChoice::onRight,this));
dlg["done"].attachClickHandler(std::bind(&cPictChoice::onOkay,this));
dlg["cancel"].attachClickHandler(std::bind(&cPictChoice::onCancel,this));
leds = &dynamic_cast<cLedGroup&>(dlg["group"]);
leds->attachFocusHandler(std::bind(&cPictChoice::onSelect,this,_3));
if(picts.size() <= per_page) {
dlg["left"].hide();
dlg["right"].hide();
}
}
cDialog* cPictChoice::operator->() {
return &dlg;
}
pic_num_t cPictChoice::show(pic_num_t fallback, pic_num_t cur_sel){
dlg.setResult(fallback);
if(cur_sel < 0) cur = 0;
else if(cur_sel > picts.back().first)
cur = picts.back().first;
else cur = cur_sel;
bool cPictChoice::show(size_t cur_sel){
if(cur_sel >= picts.size())
cur_sel = 0;
cur = cur_sel;
dlg.setResult(picts[cur_sel]);
page = cur / per_page;
// TODO: Hide left/right buttons if only one page?
fillPage();
dlg.run();
return dlg.getResult<pic_num_t>();
}// returns the _number_ of the chosen picture, _not_ the index; there's no way to distinguish between duplicates
// returns fallback if the user cancels
return didAccept;
}
void cPictChoice::fillPage(){
cLedGroup& group = dynamic_cast<cLedGroup&>(dlg["group"]);
@@ -115,15 +119,32 @@ bool cPictChoice::onRight(){
bool cPictChoice::onCancel(){
dlg.toast(false);
didAccept = false;
return true;
}
bool cPictChoice::onOkay(){
dlg.setResult(picts[cur].first);
dlg.setResult(picts[cur]);
dlg.toast(true);
didAccept = true;
return true;
}
bool cPictChoice::onSelect(bool losing) {
if(losing) return true;
int i = boost::lexical_cast<int>(leds->getSelected().substr(3));
cur = page * per_page + i - 1;
return true;
}
pic_num_t cPictChoice::getPicChosen() {
return dlg.getResult<std::pair<pic_num_t,ePicType>>().first;
}
ePicType cPictChoice::getPicChosenType() {
return dlg.getResult<std::pair<pic_num_t,ePicType>>().second;
}
const size_t cStringChoice::per_page = 40;
cStringChoice::cStringChoice(
@@ -131,9 +152,9 @@ cStringChoice::cStringChoice(
std::string title,
cDialog* parent
) : dlg("choose-string.xml",parent) {
attachHandlers();
if(!title.empty()) dlg["title"].setText(title);
strings = strs;
attachHandlers();
}
cStringChoice::cStringChoice(
@@ -142,9 +163,9 @@ cStringChoice::cStringChoice(
std::string title,
cDialog* parent
) : dlg("choose-string.xml",parent) {
attachHandlers();
if(!title.empty()) dlg["title"].setText(title);
copy(begin,end,std::inserter(strings, strings.begin()));
attachHandlers();
}
void cStringChoice::attachHandlers() {
@@ -155,12 +176,10 @@ void cStringChoice::attachHandlers() {
dlg["cancel"].attachClickHandler(std::bind(&cStringChoice::onCancel,this,_1));
leds = &dynamic_cast<cLedGroup&>(dlg["strings"]);
leds->attachFocusHandler(std::bind(&cStringChoice::onSelect,this,_3));
}
size_t cStringChoice::show(std::string select){
dlg.setResult(strings.size());
std::vector<std::string>::iterator iter = find(strings.begin(),strings.end(),select);
return show(iter - strings.begin());
if(strings.size() <= per_page) {
dlg["left"].hide();
dlg["right"].hide();
}
}
size_t cStringChoice::show(size_t selectedIndex) {
@@ -170,8 +189,7 @@ size_t cStringChoice::show(size_t selectedIndex) {
dlg.setResult<size_t>(cur);
dlg.run();
return dlg.getResult<size_t>();
}// returns the _index_ of the chosen string, relative to begin if initialized from a range
// returns strs.size() if the user cancels
}
void cStringChoice::fillPage(){
cLedGroup& group = dynamic_cast<cLedGroup&>(dlg["strings"]);
@@ -220,7 +238,7 @@ bool cStringChoice::onOkay(cDialog& me){
bool cStringChoice::onSelect(bool losing) {
if(losing) return true;
int i = boost::lexical_cast<int>(leds->getSelected().substr(3));
cur = page * 40 + i - 1;
cur = page * per_page + i - 1;
return true;
}

View File

@@ -95,30 +95,33 @@ class cStringChoice {
public:
explicit cStringChoice(std::vector<std::string>& strs, std::string title, cDialog* parent = NULL);
cStringChoice(std::vector<std::string>::iterator begin, std::vector<std::string>::iterator end, std::string title, cDialog* parent = NULL);
size_t show(std::string select); // returns the _index_ of the chosen string, relative to begin
size_t show(size_t selectedIndex);
// returns strs.size() if the user cancels
};
class cPictChoice {
static const size_t per_page;
bool didAccept;
cDialog dlg;
void attachClickHandlers();
void attachHandlers();
bool onLeft();
bool onRight();
bool onCancel();
bool onOkay();
bool onSelect(bool losing);
void fillPage();
std::vector<std::pair<pic_num_t,ePicType>> picts;
size_t page, cur;
cLedGroup* leds;
public:
cPictChoice(std::vector<pic_num_t>& pics, ePicType t, cDialog* parent = NULL);
cPictChoice(std::vector<std::pair<pic_num_t,ePicType>>& pics, cDialog* parent = NULL);
cPictChoice(std::vector<pic_num_t>::iterator begin, std::vector<pic_num_t>::iterator end, ePicType t, cDialog* parent = NULL);
cPictChoice(pic_num_t first, pic_num_t last, ePicType t, cDialog* parent = NULL);
cDialog* operator->();
pic_num_t show(pic_num_t fallback, pic_num_t cur_sel); // returns the _number_ of the chosen picture, _not_ the index; there's no way to distinguish between duplicates
// returns fallback if the user cancels
bool show(size_t cur_sel);
pic_num_t getPicChosen();
ePicType getPicChosenType();
// returns the _number_ of the chosen picture, _not_ the index; there's no way to distinguish between duplicates
};
#endif

View File

@@ -781,7 +781,7 @@ void cPict::drawStatusIcon(short num, RECT to_rect){
void cPict::drawCustomTer(short num, RECT to_rect){
printf("Drawing graphic %i as a custom terrain pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
RECT from_rect;
sf::Texture* from_gw;
graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num);
@@ -791,7 +791,7 @@ void cPict::drawCustomTer(short num, RECT to_rect){
void cPict::drawCustomTerAnim(short num, RECT to_rect){
printf("Drawing graphic %i as a custom animated terrain pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
num += animFrame;
RECT from_rect;
sf::Texture* from_gw;
@@ -804,7 +804,7 @@ void cPict::drawCustomMonstSm(short num, RECT to_rect){
num += adj[animFrame];
printf("Drawing graphic %i as a custom space pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
fill_rect(*inWindow, to_rect, sf::Color::Black);
RECT from_rect;
@@ -925,7 +925,7 @@ void cPict::drawCustomTalk(short num, RECT to_rect){
void cPict::drawCustomItem(short num, RECT to_rect){
printf("Drawing graphic %i as a custom space pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
RECT from_rect;
sf::Texture* from_gw;
graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(num);
@@ -962,7 +962,7 @@ void cPict::drawCustomTerMap(short num, RECT to_rect){
void cPict::drawPartyMonstSm(short num, RECT to_rect){
printf("Drawing graphic %i as a custom space pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;
RECT from_rect;
@@ -1042,7 +1042,7 @@ void cPict::drawPartyScen(short num, RECT to_rect){
void cPict::drawPartyItem(short num, RECT to_rect){
printf("Drawing graphic %i as a custom space pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;
RECT from_rect;
@@ -1054,7 +1054,7 @@ void cPict::drawPartyItem(short num, RECT to_rect){
void cPict::drawPartyPc(short num, RECT to_rect){
printf("Drawing graphic %i as a custom space pic.\n",num);
to_rect.right = to_rect.left + 28;
to_rect.bottom = to_rect.top + 32;
to_rect.bottom = to_rect.top + 36;
sf::Texture* from_gw;
RECT from_rect;

View File

@@ -90,6 +90,7 @@ enum eSheetType {
SHEET_FULL,
SHEET_STATUS,
SHEET_CUSTOM,
// TODO: Vehicle sheet is missing.
NUM_SHEET_TYPES
};