- 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
325 lines
8.8 KiB
C++
325 lines
8.8 KiB
C++
/*
|
|
* control.cpp
|
|
* BoE
|
|
*
|
|
* Created by Celtic Minstrel on 11/05/09.
|
|
*
|
|
*/
|
|
|
|
#include <Carbon/Carbon.h>
|
|
#include <sstream>
|
|
#include "dialog.h"
|
|
#include "soundtool.h"
|
|
|
|
extern bool play_sounds;
|
|
|
|
void cControl::setText(std::string l){
|
|
lbl = l;
|
|
if(isVisible()) draw();
|
|
}
|
|
|
|
std::string cControl::getText(){
|
|
return lbl;
|
|
}
|
|
|
|
const char* xHandlerNotSupported::focusMsg = "This control cannot handle focus events.\n";
|
|
const char* xHandlerNotSupported::clickMsg = "This control cannot handle click events.\n";
|
|
|
|
xHandlerNotSupported::xHandlerNotSupported(bool isFocus){
|
|
this->isFocus = isFocus;
|
|
}
|
|
const char* xHandlerNotSupported::what(){
|
|
if(isFocus) return focusMsg;
|
|
else return clickMsg;
|
|
}
|
|
|
|
xUnsupportedProp::xUnsupportedProp(eFormat prop) throw(){
|
|
whichProp = prop;
|
|
msg = NULL;
|
|
}
|
|
xUnsupportedProp::~xUnsupportedProp() throw(){
|
|
if(msg != NULL) delete msg;
|
|
}
|
|
const char* xUnsupportedProp::what() throw(){
|
|
if(msg == NULL){
|
|
msg = new char[60];
|
|
std::string s;
|
|
switch(whichProp){
|
|
case TXT_COLOR:
|
|
s = "TXT_COLOR";
|
|
break;
|
|
case TXT_FRAME:
|
|
s = "TXT_FRAME";
|
|
break;
|
|
case TXT_FONT:
|
|
s = "TXT_FONT";
|
|
break;
|
|
case TXT_SIZE:
|
|
s = "TXT_SIZE";
|
|
break;
|
|
case TXT_WRAP:
|
|
s = "TXT_WRAP";
|
|
break;
|
|
}
|
|
sprintf(msg,"Format property %s not valid for this control.\n",s.c_str());
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
eKeyMod operator + (eKeyMod lhs, eKeyMod rhs){
|
|
if(lhs == rhs) return lhs;
|
|
else if(lhs == mod_none) return rhs;
|
|
else if(lhs == mod_alt){
|
|
if(rhs == mod_shift || rhs == mod_altshift) return mod_altshift;
|
|
else if(rhs == mod_ctrl || rhs == mod_altctrl) return mod_altctrl;
|
|
else if(rhs == mod_shiftctrl || rhs == mod_all) return mod_all;
|
|
else return mod_alt;
|
|
}else if(lhs == mod_shift){
|
|
if(rhs == mod_alt || rhs == mod_altshift) return mod_altshift;
|
|
else if(rhs == mod_ctrl || rhs == mod_shiftctrl) return mod_shiftctrl;
|
|
else if(rhs == mod_altctrl || rhs == mod_all) return mod_all;
|
|
else return mod_shift;
|
|
}else if(lhs == mod_ctrl){
|
|
if(rhs == mod_alt || rhs == mod_altctrl) return mod_altctrl;
|
|
else if(rhs == mod_shift || rhs == mod_shiftctrl) return mod_shiftctrl;
|
|
else if(rhs == mod_altshift || rhs == mod_all) return mod_all;
|
|
else return mod_ctrl;
|
|
}else return rhs + lhs;
|
|
}
|
|
|
|
eKeyMod operator - (eKeyMod lhs, eKeyMod rhs){
|
|
if(lhs == rhs || lhs == mod_none || rhs == mod_all) return mod_none;
|
|
else if(rhs == mod_none) return lhs;
|
|
else if(lhs == mod_all){
|
|
if(rhs == mod_alt) return mod_shiftctrl;
|
|
else if(rhs == mod_shift) return mod_altctrl;
|
|
else if(rhs == mod_ctrl) return mod_altshift;
|
|
else if(rhs == mod_altshift) return mod_ctrl;
|
|
else if(rhs == mod_altctrl) return mod_shift;
|
|
else if(rhs == mod_shiftctrl) return mod_alt;
|
|
else return mod_all;
|
|
}else if(lhs == mod_shiftctrl){
|
|
if(rhs == mod_shift || rhs == mod_altshift) return mod_ctrl;
|
|
else if(rhs == mod_ctrl || rhs == mod_altctrl) return mod_shift;
|
|
else return mod_shiftctrl;
|
|
}else if(lhs == mod_altctrl){
|
|
if(rhs == mod_alt || rhs == mod_altshift) return mod_ctrl;
|
|
else if(rhs == mod_ctrl || rhs == mod_shiftctrl) return mod_alt;
|
|
else return mod_altctrl;
|
|
}else if(lhs == mod_altshift){
|
|
if(rhs == mod_alt || rhs == mod_altctrl) return mod_shift;
|
|
else if(rhs == mod_shift || rhs == mod_shiftctrl) return mod_alt;
|
|
else return mod_altshift;
|
|
}else if(lhs == mod_alt && (rhs == mod_altshift || rhs == mod_altctrl))
|
|
return mod_none;
|
|
else if(lhs == mod_shift && (rhs == mod_altshift || rhs == mod_shiftctrl))
|
|
return mod_none;
|
|
else if(lhs == mod_ctrl && (rhs == mod_altctrl || rhs == mod_shiftctrl))
|
|
return mod_none;
|
|
else return lhs;
|
|
}
|
|
|
|
eKeyMod& operator += (eKeyMod&lhs, eKeyMod rhs){
|
|
lhs = lhs + rhs;
|
|
return lhs;
|
|
}
|
|
|
|
eKeyMod& operator -= (eKeyMod&lhs, eKeyMod rhs){
|
|
lhs = lhs - rhs;
|
|
return lhs;
|
|
}
|
|
|
|
bool operator== (cKey& a, cKey& b){
|
|
if(a.spec != b.spec) return false;
|
|
if(a.mod != b.mod) return false;
|
|
return a.spec ? a.k == b.k : a.c == b.c;
|
|
}
|
|
|
|
void cControl::show(){
|
|
visible = true;
|
|
if(isVisible()) draw();
|
|
}
|
|
|
|
void cControl::hide(){
|
|
visible = false;
|
|
if(isVisible()) draw();
|
|
}
|
|
|
|
bool cControl::isVisible(){
|
|
if(parent->dialogNotToast)
|
|
return visible;
|
|
else return false;
|
|
}
|
|
|
|
bool cControl::handleClick(){
|
|
EventRecord e;
|
|
unsigned long dummy;
|
|
bool done = false, clicked = false;
|
|
GrafPtr old_port;
|
|
GetPort(&old_port);
|
|
SetPortWindowPort(parent->win);
|
|
RgnHandle in_region = NewRgn(), out_region = NewRgn();
|
|
RectRgn(in_region,&frame);
|
|
RectRgn(out_region,&parent->winRect);
|
|
DiffRgn(out_region,in_region,out_region);
|
|
depressed = true;
|
|
draw();
|
|
while(!done){
|
|
WaitNextEvent(mUpMask,&e,0L,depressed ? in_region : out_region);
|
|
if(e.what == mouseUp){
|
|
done = true;
|
|
clicked = PtInRect(e.where, &frame);
|
|
depressed = false;
|
|
}else if(e.message >> 8 == mouseMovedMessage){
|
|
depressed = !depressed;
|
|
draw();
|
|
}
|
|
}
|
|
if (play_sounds) {
|
|
if(typeid(this) == typeid(cLed*))
|
|
play_sound(34);
|
|
else play_sound(37);
|
|
Delay(6,&dummy);
|
|
}
|
|
else Delay(14,&dummy);
|
|
draw();
|
|
SetPort(old_port);
|
|
return clicked;
|
|
}
|
|
|
|
static unsigned char applyShift(unsigned char c){
|
|
static const char afterShift[] = {
|
|
' ', '!', '"', '#', '$', '%', '&', '"', '(', ')', '*', '+', '<', '_', '>', '?',
|
|
')', '!', '@', '#', '$', '%', '^', '&', '*', '(', ':', ':', '<', '+', '>', '?',
|
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '^', '_',
|
|
'~', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~',
|
|
};
|
|
return afterShift[c - ' '];
|
|
}
|
|
|
|
static unsigned char removeShift(unsigned char c){
|
|
static const char afterUnShift[] = {
|
|
' ', '1', '\'','3', '4', '5', '7', '\'','9', '0', '8', '=', ',', '-', '.', '/',
|
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';', ';', ',', '=', '.', '/',
|
|
'2', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\',']', '6', '-',
|
|
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\',']', '`',
|
|
};
|
|
return afterUnShift[c - ' '];
|
|
}
|
|
|
|
void cControl::setTextToKey(){
|
|
if(key.spec); // TODO: Handle this case
|
|
else{
|
|
unsigned char c = key.c;
|
|
if(key.mod - mod_shift != key.mod) c = applyShift(c);
|
|
else c = removeShift(c);
|
|
if(key.mod - mod_ctrl != key.mod) lbl = "^" + c;
|
|
else if(key.mod - mod_alt != key.mod) lbl = "*" + c;
|
|
else lbl = c;
|
|
}
|
|
if(isVisible()) draw();
|
|
}
|
|
|
|
void cControl::attachKey(cKey key){
|
|
this->key = key;
|
|
}
|
|
|
|
void cControl::detachKey(){
|
|
this->key.spec = false;
|
|
this->key.c = 0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool cControl::triggerFocusHandler(cDialog& me __attribute__((unused)), std::string id __attribute__((unused)), bool losingFocus __attribute__((unused))){
|
|
return true;
|
|
}
|
|
|
|
short cControl::font_nums[4];
|
|
|
|
void cControl::init(){
|
|
Str255 fnGeneva = "\pGeneva";
|
|
Str255 fnDungeon = "\pDungeon Bold";
|
|
Str255 fnMaiden = "\pMaidenWord";
|
|
Str255 fnSilom = "\pSilom";
|
|
Str255 fnPalatino = "\pPalatino";
|
|
Str255 fnChancery = "\pApple Chancery";
|
|
|
|
GetFNum(fnGeneva,&font_nums[GENEVA]);
|
|
if(font_nums[GENEVA] == 0)
|
|
GetFNum(fnPalatino,&font_nums[GENEVA]);
|
|
GetFNum(fnDungeon,&font_nums[DUNGEON]);
|
|
if(font_nums[DUNGEON] == 0)
|
|
GetFNum(fnChancery,&font_nums[DUNGEON]);
|
|
GetFNum(fnSilom,&font_nums[SILOM]);
|
|
if(font_nums[SILOM] == 0){
|
|
GetFNum(fnPalatino,&font_nums[SILOM]);
|
|
found_silom = false;
|
|
}else found_silom = true;
|
|
GetFNum(fnMaiden,&font_nums[MAIDENWORD]);
|
|
if(font_nums[MAIDENWORD] == 0)
|
|
GetFNum(fnChancery,&font_nums[MAIDENWORD]);
|
|
}
|
|
|
|
void cControl::drawFrame(short amt, short med_or_lt){
|
|
static RGBColor lt_gray = {57344,57344,57344},dk_gray = {12287,12287,12287},med_gray = {24574,24574,24574};
|
|
GrafPtr old_port;
|
|
Rect rect = frame;
|
|
|
|
GetPort(&old_port);
|
|
SetPortWindowPort(parent->win);
|
|
|
|
InsetRect(&rect,-1 * amt,-1 * amt);
|
|
|
|
RGBForeColor(&dk_gray);
|
|
MoveTo(rect.left,rect.top);
|
|
LineTo(rect.right,rect.top);
|
|
if (med_or_lt == 1) // hDlg == GetWindowPort(mainPtr) // ie for the pc editor only
|
|
RGBForeColor(&med_gray);
|
|
else RGBForeColor(<_gray);
|
|
LineTo(rect.right,rect.bottom);
|
|
LineTo(rect.left,rect.bottom);
|
|
RGBForeColor(&dk_gray);
|
|
LineTo(rect.left,rect.top);
|
|
ForeColor(blackColor);
|
|
SetPort(old_port);
|
|
}
|
|
|
|
bool cControl::found_silom;
|
|
|
|
bool cControl::foundSilom(){
|
|
return found_silom;
|
|
}
|
|
|
|
cControl::~cControl() {}
|
|
|
|
eControlType cControl::getType(){
|
|
return type;
|
|
}
|
|
|
|
void cControl::setTextToNum(long what){
|
|
std::ostringstream sout;
|
|
sout << what;
|
|
setText(sout.str());
|
|
}
|
|
|
|
long cControl::getTextAsNum(){
|
|
std::istringstream sin(getText());
|
|
long n;
|
|
sin >> n;
|
|
return n;
|
|
}
|
|
|
|
bool cControl::hasKey(){
|
|
if(key.spec) return true;
|
|
return key.c != 0;
|
|
}
|