- Removed the SLEEP_TICKS and MOUSE_REGION macros (note: SLEEP_TICKS was at 2L, but I've changed it to 0; I think this should be fine, but I'm not sure)

- Stripped out the copying of external files (such as graphics, scenarios, bladbase) into a separate target which the other three are dependent on.
- Graphics.exd no longer included by reference; now the individual files are included directly.
- Added a recalcRect function to ledGroup, since it's a container.
- Added a special case to cLedGroup::setSelected to avoid a crash when no LED is initially selected.
- Added a few initializers to constructors.
- Changes to cDialog::parse<cPict> which were intended to prevent an access violation; unfortunately it doesn't work yet.
- Add cases to cDialog::parse<cPict> to handle PI_TER_MAP and PIC_STATUS.
- Fixed a stupid error in all specializations of cDialog::parse which resulted in an infinite loop.
- Fixed errors in some specializations of cDialog::parse in which an else statement belonged to a different if than it should have.
- Added code to cDialog::loadFromFile to turn the relative path in the argument into an absolute path.
- Fixed errors in cDialog::loadFromFile relating to incorrect use of the parser.
- Added exit statements to the catch clauses in cDialog::loadFromFile.
- Added definition of cDialog::init;
- Enclosed the WaitNextEvent call in cDialog::run in an if statement to ignore null events if they occur (I suspect they won't anyway though)
- Fixed errors in the Edit Terrain dialog definition which caused an exception to be thrown when parsing it: bold was changed to silom, key= was changed to def-key=
- Added status to the list of nullified GWorlPtrs in cPict::init.
- Changed the type of cPict::drawPict from map<ePicType,void(*)(short,GWorldPtr,Rect)> to void(*[])(short,GWorldPtr,Rect) - ie, it was changed from a map to an array because the map was causing an error for some reason.
- Fixed up the load_strings function, which didn't work at all due to a stupid logic error.

git-svn-id: http://openexile.googlecode.com/svn/trunk@96 4ebdad44-0ea0-11de-aab3-ff745001d230
This commit is contained in:
2009-06-16 22:43:51 +00:00
parent cd3b2cfc43
commit 269d6b0572
17 changed files with 727 additions and 120 deletions

View File

@@ -252,6 +252,19 @@ cLedGroup::~cLedGroup(){
}
}
void cLedGroup::recalcRect(){
ledIter iter = choices.begin();
while(iter != choices.end()){
if(iter->second->frame.right > frame.right)
frame.right = iter->second->frame.right;
if(iter->second->frame.bottom > frame.bottom)
frame.bottom = iter->second->frame.bottom;
iter++;
}
frame.right += 6;
frame.bottom += 6;
}
/** A click handler is called whenever a click is received, even on the currently selected element. */
void cLedGroup::attachClickHandler(click_callback_t f) throw() {
onClick = f;
@@ -358,22 +371,29 @@ void cLedGroup::setSelected(std::string id){
ledIter iter = choices.find(id);
if(iter == choices.end()) throw std::invalid_argument(id + " does not exist in the ledgroup.");
eLedState a, b;
a = choices[curSelect]->getState();
b = iter->second->getState();
choices[curSelect]->setState(led_off);
iter->second->setState(led_red);
if(!choices[curSelect]->triggerFocusHandler(*parent,curSelect,true)){
choices[curSelect]->setState(a);
iter->second->setState(b);
return;
if(curSelect == ""){
if(iter->second->triggerFocusHandler(*parent,curSelect,false)){
iter->second->setState(led_red);
curSelect = iter->first;
}
}else{
eLedState a, b;
a = choices[curSelect]->getState();
b = iter->second->getState();
choices[curSelect]->setState(led_off);
iter->second->setState(led_red);
if(!choices[curSelect]->triggerFocusHandler(*parent,curSelect,true)){
choices[curSelect]->setState(a);
iter->second->setState(b);
return;
}
if(!iter->second->triggerFocusHandler(*parent,curSelect,false)){
choices[curSelect]->setState(a);
iter->second->setState(b);
return;
}
curSelect = iter->first;
}
if(!iter->second->triggerFocusHandler(*parent,curSelect,false)){
choices[curSelect]->setState(a);
iter->second->setState(b);
return;
}
curSelect = iter->first;
}
std::string cLedGroup::getSelected(){

View File

@@ -118,6 +118,7 @@ public:
void setSelected(std::string id);
std::string getSelected();
std::string getPrevSelection(); // The id of the element that was last selected before the selection changed to the current selection.
void recalcRect();
typedef std::map<std::string,cLed*>::iterator ledIter;
protected:
void draw();

View File

@@ -233,7 +233,7 @@ void cControl::detachKey(){
this->key.c = 0;
}
cControl::cControl(cDialog* p, eControlType t) : parent(p), type(t) {}
cControl::cControl(cDialog* p, eControlType t) : parent(p), type(t), visible(true) {}
bool cControl::triggerClickHandler(cDialog& __attribute__((unused)), std::string __attribute__((unused)), eKeyMod __attribute__((unused)), Point __attribute__((unused))){
return true;

View File

@@ -5,8 +5,6 @@
* Created by Celtic Minstrel on 11/05/09.
*
*/
#define SLEEP_TICKS 2L
#define MOUSE_REGION 0L
#define IN_FRONT (WindowPtr)-1L
#include <Carbon/Carbon.h>
@@ -29,25 +27,30 @@ static std::string generateRandomString(){
int n_chars = rand() % 100;
std::string s;
while(n_chars > 0){
s += char(rand() % 223 + 32);
s += char(rand() % 223) + ' ';
n_chars--;
}
return s;
}
template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
pair<string,cPict*> p;
std::pair<std::string,cPict*> p;
Iterator<Attribute> attr;
string name, val;
int width = 0, height = 0;
std::string name, val;
std::istringstream sin(val);
bool wide = false, tall = false, custom = false;
int width = 0, height = 0;
printf("%p\n",p.second);
p.second = new cPict(this);
printf("%p\n",p.second);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
printf("%p\n",p.second);
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "type"){
printf("%p\n",p.second);
if(val == "blank"){
p.second->picType = PIC_TER;
p.second->picNum = -1;
@@ -75,30 +78,35 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
p.second->picType = PIC_MISSILE;
else if(val == "full")
p.second->picType = PIC_FULL;
else if(val == "map")
p.second->picType = PIC_TER_MAP;
else if(val == "status")
p.second->picType = PIC_STATUS;
else throw xBadVal("pict",name,val);
}else if(name == "custom") if(val == "true")
custom = true;
else if(name == "clickable") if(val == "true")
p.second->clickable = true;
else if(name == "size"){
}else if(name == "custom"){
if(val == "true") custom = true;
}else if(name == "clickable"){
if(val == "true") p.second->clickable = true;
}else if(name == "size"){
if(val == "wide") wide = true;
else if(val == "tall") tall = true;
else if(val == "large") wide = tall = true;
else throw xBadVal("pict",name,val);
}else if(name == "num"){
istringstream sin(val);
printf("%p\n",p.second);
sin.str(val);
sin >> p.second->picNum;
}else if(name == "top"){
istringstream sin(val);
sin.str(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin.str(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin(val);
sin.str(val);
sin >> width;
}else if(name == "height"){
istringstream sin(val);
sin.str(val);
sin >> height;
}else throw xBadAttr("pict",name);
}
@@ -109,6 +117,8 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
else if(p.second->picType == PIC_SCEN) p.second->picType = PIC_SCEN_LG;
else if(p.second->picType == PIC_DLOG) p.second->picType = PIC_DLOG_LG;
}
p.second->frame.right = p.second->frame.left;
p.second->frame.bottom = p.second->frame.top;
if(width > 0 || height > 0 || p.second->picType == PIC_FULL){
p.second->frame.right = p.second->frame.left + width;
p.second->frame.bottom = p.second->frame.top + height;
@@ -134,6 +144,14 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
p.second->frame.right = p.second->frame.left + 18;
p.second->frame.bottom = p.second->frame.top + 18;
break;
case PIC_TER_MAP:
p.second->frame.right = p.second->frame.left + 24;
p.second->frame.bottom = p.second->frame.top + 24;
break;
case PIC_STATUS:
p.second->frame.right = p.second->frame.left + 12;
p.second->frame.bottom = p.second->frame.top + 12;
break;
default:
p.second->frame.right = p.second->frame.left + 28;
p.second->frame.bottom = p.second->frame.top + 36;
@@ -143,7 +161,7 @@ template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -160,11 +178,11 @@ template<> pair<string,cTextMsg*> cDialog::parse(Element& who /*text*/){
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "framed") if(val == "true")
p.second->drawFramed = true;
else if(name == "clickable") if(val == "true")
p.second->clickable = true;
else if(name == "font"){
else if(name == "framed"){
if(val == "true") p.second->drawFramed = true;
}else if(name == "clickable"){
if(val == "true") p.second->clickable = true;
}else if(name == "font"){
if(val == "dungeon")
p.second->textFont = DUNGEON;
else if(val == "geneva")
@@ -222,7 +240,7 @@ template<> pair<string,cTextMsg*> cDialog::parse(Element& who /*text*/){
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -289,9 +307,9 @@ template<> pair<string,cButton*> cDialog::parse(Element& who /*button*/){
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "wrap") if(val == "true")
p.second->wrapLabel = true;
else if(name == "type"){
else if(name == "wrap"){
if(val == "true") p.second->wrapLabel = true;
}else if(name == "type"){
if(val == "small")
p.second->type = BTN_SM;
else if(val == "regular")
@@ -392,7 +410,7 @@ template<> pair<string,cButton*> cDialog::parse(Element& who /*button*/){
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -532,7 +550,7 @@ template<> pair<string,cLed*> cDialog::parse(Element& who /*LED*/){
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -565,10 +583,11 @@ template<> pair<string,cLedGroup*> cDialog::parse(Element& who /*group*/){
}
}
p.second->lbl = content;
p.second->recalcRect();
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -610,7 +629,7 @@ template<> pair<string,cTextField*> cDialog::parse(Element& who /*field*/){
if(p.first == ""){
do{
p.first = generateRandomString();
}while(controls.find(p.first) == controls.end());
}while(controls.find(p.first) != controls.end());
}
return p;
}
@@ -626,17 +645,30 @@ cDialog::cDialog(std::string path, cDialog* p) : parent(p){
}
void cDialog::loadFromFile(std::string path){
char cPath[512];
UniChar* ucpath = new UniChar[path.length()];
for(unsigned int i = 0; i < path.length(); i++) ucpath[i] = path[i];
CFBundleRef mainBundle=CFBundleGetMainBundle();
CFURLRef url = CFBundleCopyResourceURL(
mainBundle,
CFStringCreateWithCharacters(NULL, ucpath, path.length()),
CFSTR(""), CFSTR("dialogs")
);
delete ucpath;
CFStringRef cfpath = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
CFStringGetCString(cfpath, cPath, 512, kCFStringEncodingUTF8);
try{
Document xml(path);
printf("Loading dialog from: %s\n", cPath);
Document xml(cPath);
xml.LoadFile();
Iterator<Attribute> attr;
Iterator<Element> node;
string type, name, val;
xml.GetValue(&type);
xml.FirstChildElement()->GetValue(&type);
if(type != "dialog") throw xBadNode(type);
for(attr = attr.begin(&xml); attr != attr.end(); attr++){
for(attr = attr.begin(xml.FirstChildElement()); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "skin"){
@@ -672,12 +704,16 @@ void cDialog::loadFromFile(std::string path){
}
} catch(Exception& x){ // XML processing exception
printf(x.what());
exit(1);
} catch(xBadVal& x){ // Invalid value for an attribute
printf(x.what());
exit(1);
} catch(xBadAttr& x){ // Invalid attribute for an element
printf(x.what());
exit(1);
} catch(xBadNode& x){ // Invalid element
printf(x.what());
exit(1);
}
dialogNotToast = true;
bg = BG_DARK; // default is dark background
@@ -701,6 +737,7 @@ void cDialog::loadFromFile(std::string path){
void cDialog::recalcRect(){
ctrlIter iter = controls.begin();
while(iter != controls.end()){
printf("%s \"%s\"\n",typeid(*(iter->second)).name(),iter->first.c_str());
if(iter->second->frame.right > winRect.right)
winRect.right = iter->second->frame.right;
if(iter->second->frame.bottom > winRect.bottom)
@@ -711,6 +748,8 @@ void cDialog::recalcRect(){
winRect.bottom += 6;
}
cDialog::_init cDialog::init;
cDialog::_init::_init(){
cControl::init();
cButton::init();
@@ -757,7 +796,7 @@ void cDialog::run(){
ShowWindow(win);
BeginAppModalStateForWindow(win);
while(dialogNotToast){
WaitNextEvent(everyEvent, &currentEvent, SLEEP_TICKS, MOUSE_REGION);
if(!WaitNextEvent(everyEvent, &currentEvent, 0, NULL))continue;
switch(currentEvent.what){
case updateEvt:
BeginUpdate(win);

View File

@@ -34,6 +34,7 @@ class cDialog {
class _init {
_init();
~_init();
friend class cDialog;
};
static _init init;
cDialog* parent;

View File

@@ -21,9 +21,9 @@
<led name='obstructed' top='107' left='293' state='off' width='120'>Blocked, obstructed</led>
<led name='opaque' top='124' left='293' state='off' width='120'>Blocked, opaque</led>
</group>
<led name='flight' top='150' left='26' state='off' width='120' font='bold'>Can fly over?</led>
<led name='boat' top='150' left='154' state='off' width='120' font='bold'>Can boat over?</led>
<led name='horse' top='150' left='307' state='off' width='120' font='bold'>Blocked to horses?</led>
<led name='flight' top='150' left='26' state='off' width='120' font='silom'>Can fly over?</led>
<led name='boat' top='150' left='154' state='off' width='120' font='silom'>Can boat over?</led>
<led name='horse' top='150' left='307' state='off' width='120' font='silom'>Blocked to horses?</led>
<text top='165' left='8' height='14' width='91'>Step sound:</text>
<group name='sound'>
<led name="step" top='167' left='102' state='off' width='60'>Footstep</led>
@@ -92,10 +92,10 @@
<text top='385' left='470' width='60' height='14'>Map icon:</text>
<pict name='seemap' top='375' left='550' type='map' num='0'/>
<field name='map' top='406' left='470' width='100' height='16'/>
<button name='done' type='regular' key='enter' top='455' left='517'>OK</button>
<button name='cancel' type='regular' key='esc' top='455' left='451'>Cancel</button>
<button name='left' type='left' key='left' top='455' left='11'/>
<button name='right' type='right' key='right' top='455' left='74'/>
<button name='done' type='regular' def-key='enter' top='455' left='517'>OK</button>
<button name='cancel' type='regular' def-key='esc' top='455' left='451'>Cancel</button>
<button name='left' type='left' def-key='left' top='455' left='11'/>
<button name='right' type='right' def-key='right' top='455' left='74'/>
<text top='7' left='451' height='131' width='137'>Enter properties for this terrain type. For a detailed description of the fields, see the documentation. Note that, for terrain types 90 and below, only changes to the picture and shortcut key will be recorded.</text>
<button name='help' type='help' key='help' top='5' left='588'/>
<button name='help' type='help' def-key='help' top='5' left='588'/>
</dialog>

View File

@@ -93,7 +93,7 @@ short cTextMsg::getFormat(eFormat prop) throw(xUnsupportedProp){
return 0;
}
cTextMsg::cTextMsg(cDialog* parent) : cControl(parent,CTRL_TEXT) {}
cTextMsg::cTextMsg(cDialog* parent) : cControl(parent,CTRL_TEXT), drawFramed(true), textFont(SILOM), textSize(10) {}
bool cTextMsg::isClickable(){
return clickable;

View File

@@ -18,7 +18,7 @@ extern GWorldPtr bg_gworld;
void cPict::init(){
// TODO: Load or otherwise acquire the various GWorlds.
teranim = dlog = talk = scen = largeScen = item = tinyItem = pc = field = boom = missile = save = header = map = NULL;
teranim = dlog = talk = scen = largeScen = item = tinyItem = pc = field = boom = missile = save = header = map = status = NULL;
drawPict[PIC_TER] = drawPresetTer;
drawPict[PIC_TER_ANIM] = drawPresetTerAnim;
drawPict[PIC_MONST] = drawPresetMonstSm;
@@ -500,7 +500,8 @@ GWorldPtr cPict::item = NULL, cPict::tinyItem = NULL, cPict::pc = NULL, cPict::f
GWorldPtr cPict::missile = NULL, cPict::save = NULL, cPict::header = NULL, cPict::map = NULL, cPict::status = NULL;
std::vector<GWorldPtr> cPict::ter, cPict::monst, cPict::customSheets;
std::map<size_t,GWorldPtr> cPict::largeSheets;
std::map<ePicType,void(*)(short,GWorldPtr,Rect)> cPict::drawPict;
//std::map<ePicType,void(*)(short,GWorldPtr,Rect)> cPict::drawPict;
void(* cPict::drawPict[NUM_PIC_TYPES])(short,GWorldPtr,Rect);
short cPict::animFrame = 0;
void cPict::draw(){

View File

@@ -54,6 +54,7 @@ enum ePicType {
PIC_PARTY_MONST_WIDE = 223, // 56x36 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
PIC_PARTY_MONST_TALL = 243, // 28x72 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
PIC_PARTY_MONST_LG = 263, // 56x72 monster graphic from the savegame sheet, resized to fit in a 28x36 space
NUM_PIC_TYPES
};
enum ePicTypeMod {
@@ -153,7 +154,8 @@ private:
static void drawPartyScen(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyItem(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyPc(short num, GWorldPtr to_gw, Rect to_rect);
static std::map<ePicType,void(*)(short,GWorldPtr,Rect)> drawPict;
//static std::map<ePicType,void(*)(short,GWorldPtr,Rect)> drawPict;
static void(* drawPict[NUM_PIC_TYPES])(short,GWorldPtr,Rect);
click_callback_t onClick;
};