First version of the new dialog engine added to the repository. It compiles, and links with one error. Because of this, it is untested as yet.

git-svn-id: http://openexile.googlecode.com/svn/trunk@73 4ebdad44-0ea0-11de-aab3-ff745001d230
This commit is contained in:
2009-05-26 03:17:17 +00:00
parent 6ef3b7c79d
commit 8507a3302b
20 changed files with 4050 additions and 46 deletions

View File

@@ -7,19 +7,67 @@
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>boesounds</string>
<key>CFBundleTypeName</key>
<string>Sounds</string>
<key>CFBundleTypeOSTypes</key>
<key>CFBundleTypeExtensions</key>
<array>
<string>beSN</string>
<string>.SAV</string>
</array>
<key>CFBundleTypeName</key>
<string>LegacyWinSaveGame</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.oldsounds</string>
<string>com.spidweb.bladesofexile.oldwinsave</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.boe</string>
<string>.mac</string>
</array>
<key>CFBundleTypeName</key>
<string>LegacyMacSaveGame</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>beSV</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.oldmacsave</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.bmp</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/x-bmp</string>
</array>
<key>CFBundleTypeName</key>
<string>LegacyWinGraphics</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>BMPf</string>
<string>BMP</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.bmp</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
@@ -34,13 +82,13 @@
<key>CFBundleTypeIconFile</key>
<string>boegraphics</string>
<key>CFBundleTypeName</key>
<string>Graphics</string>
<string>LegacyMacGraphics</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>beGR</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.oldgraphics</string>
@@ -50,6 +98,26 @@
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeIconFile</key>
<string>boesounds</string>
<key>CFBundleTypeName</key>
<string>LegacySounds</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>beSN</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.oldsounds</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
@@ -61,7 +129,7 @@
<string>Saved Game</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>beSV</string>
<string>game</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
@@ -101,17 +169,17 @@
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.exd</string>
<string>.exr</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>boegraphics</string>
<string>boeresources</string>
<key>CFBundleTypeName</key>
<string>Preset Graphics</string>
<string>Resource File</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.newgraphics</string>
<string>com.spidweb.bladesofexile.resources</string>
</array>
<key>LSTypeIsPackage</key>
<true/>
@@ -121,17 +189,35 @@
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.exr</string>
<string>.dlg</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>boeresources</string>
<key>CFBundleTypeName</key>
<string>Resource File</string>
<string>EncounterDialog</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.resources</string>
<string>com.spidweb.bladesofexile.dialog</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>NSPersistentStoreTypeKey</key>
<string>XML</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.exd</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>boegraphics</string>
<key>CFBundleTypeName</key>
<string>Preset Graphics</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.graphics</string>
</array>
<key>LSTypeIsPackage</key>
<true/>
@@ -148,10 +234,10 @@
<key>CFBundleTypeName</key>
<string>Preset Sounds</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.newsounds</string>
<string>com.spidweb.bladesofexile.sounds</string>
</array>
<key>LSTypeIsPackage</key>
<true/>

View File

@@ -42,11 +42,6 @@
2BF04B2D0BF51924006C0831 /* boe.text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04B070BF51924006C0831 /* boe.text.cpp */; };
2BF04B2E0BF51924006C0831 /* boe.town.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04B090BF51924006C0831 /* boe.town.cpp */; };
2BF04DE90BF7A6FE006C0831 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BF04DE80BF7A6FE006C0831 /* Carbon.framework */; };
910BBA470FB8E34E001E34EA /* ticpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA270FB8C459001E34EA /* ticpp.cpp */; };
910BBA480FB8E34E001E34EA /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2E0FB8C459001E34EA /* tinystr.cpp */; };
910BBA490FB8E34F001E34EA /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2A0FB8C459001E34EA /* tinyxml.cpp */; };
910BBA4A0FB8E350001E34EA /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2C0FB8C459001E34EA /* tinyxmlerror.cpp */; };
910BBA4B0FB8E351001E34EA /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2D0FB8C459001E34EA /* tinyxmlparser.cpp */; };
9127903E0F9B7F49007B0D52 /* boe.actions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04ACF0BF51923006C0831 /* boe.actions.cpp */; };
9127903F0F9B7F50007B0D52 /* boe.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BF04AD30BF51923006C0831 /* boe.graphics.cpp */; };
912793640F9C107B007B0D52 /* viewdlog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF80F969BA700BF5B67 /* viewdlog.cpp */; };
@@ -93,6 +88,12 @@
913D05BD0FA1EA0A00184C18 /* pc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05BB0FA1EA0A00184C18 /* pc.cpp */; };
913D05BE0FA1EA0A00184C18 /* pc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 913D05BB0FA1EA0A00184C18 /* pc.cpp */; };
913D6C050FC57A8E00E12527 /* boeresources.icns in Resources */ = {isa = PBXBuildFile; fileRef = 913D6C040FC57A8E00E12527 /* boeresources.icns */; };
9141DAC00FCB95B80047D3A3 /* libticpp.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9141DAB50FCB94900047D3A3 /* libticpp.dylib */; };
9141DAC20FCB95C90047D3A3 /* ticpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA270FB8C459001E34EA /* ticpp.cpp */; };
9141DAC30FCB95C90047D3A3 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2E0FB8C459001E34EA /* tinystr.cpp */; };
9141DAC40FCB95CA0047D3A3 /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2A0FB8C459001E34EA /* tinyxml.cpp */; };
9141DAC50FCB95CA0047D3A3 /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2C0FB8C459001E34EA /* tinyxmlerror.cpp */; };
9141DAC60FCB95CB0047D3A3 /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA2D0FB8C459001E34EA /* tinyxmlparser.cpp */; };
91A79DC70FA797BF00A6A41F /* menu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 91A79DC60FA797BF00A6A41F /* menu.xib */; };
91AC60800FA26A3B00EEAE67 /* regtown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC607F0FA26A3B00EEAE67 /* regtown.cpp */; };
91AC60810FA26A3B00EEAE67 /* regtown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AC607F0FA26A3B00EEAE67 /* regtown.cpp */; };
@@ -132,6 +133,12 @@
91B3EF5B0F969F3000BF5B67 /* scen.dlgutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF60F969BA700BF5B67 /* scen.dlgutil.cpp */; };
91B3EF5D0F969F3500BF5B67 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BF04DE80BF7A6FE006C0831 /* Carbon.framework */; };
91B3F1850F97894A00BF5B67 /* scen.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF30F969BA700BF5B67 /* scen.graphics.cpp */; };
91C1FCA60FCB6F7000EBAA65 /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA890FB8EC57001E34EA /* button.cpp */; };
91C1FCA70FCB6F7100EBAA65 /* control.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA3C0FB8DA8E001E34EA /* control.cpp */; };
91C1FCA80FCB6F7100EBAA65 /* dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBA180FB8BECA001E34EA /* dialog.cpp */; };
91C1FCA90FCB6F7200EBAA65 /* field.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBAB50FB91A26001E34EA /* field.cpp */; };
91C1FCAA0FCB6F7200EBAA65 /* message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBAB90FB91ADB001E34EA /* message.cpp */; };
91C1FCAB0FCB6F7300EBAA65 /* pict.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910BBAA90FB8F733001E34EA /* pict.cpp */; };
91D62F340F8EB84800674AB3 /* bladesofexile.rsrc in Resources */ = {isa = PBXBuildFile; fileRef = 91D62F330F8EB84800674AB3 /* bladesofexile.rsrc */; };
91D634560F8FD77800674AB3 /* BoE.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2B8F435C0C0973680012E4A8 /* BoE.icns */; };
91D635B60F90E7D200674AB3 /* stealth.exs in CopyFiles */ = {isa = PBXBuildFile; fileRef = 91D635AA0F90E7B500674AB3 /* stealth.exs */; };
@@ -179,6 +186,13 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
9141DABB0FCB95030047D3A3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2BF04AA10BF51845006C0831 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 9141DAB40FCB94900047D3A3 /* ticpp */;
remoteInfo = ticpp;
};
91EBE9DD0F9A33A6002356F2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2BF04AA10BF51845006C0831 /* Project object */;
@@ -293,15 +307,15 @@
2BF04DE80BF7A6FE006C0831 /* Carbon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Carbon.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
910BBA170FB8BECA001E34EA /* dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dialog.h; path = dialogxml/dialog.h; sourceTree = "<group>"; };
910BBA180FB8BECA001E34EA /* dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dialog.cpp; path = dialogxml/dialog.cpp; sourceTree = "<group>"; };
910BBA270FB8C459001E34EA /* ticpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ticpp.cpp; path = "dialogxml/TinyXML++/ticpp.cpp"; sourceTree = "<group>"; };
910BBA280FB8C459001E34EA /* ticpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ticpp.h; path = "dialogxml/TinyXML++/ticpp.h"; sourceTree = "<group>"; };
910BBA290FB8C459001E34EA /* tinystr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinystr.h; path = "dialogxml/TinyXML++/tinystr.h"; sourceTree = "<group>"; };
910BBA2A0FB8C459001E34EA /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml.cpp; path = "dialogxml/TinyXML++/tinyxml.cpp"; sourceTree = "<group>"; };
910BBA2B0FB8C459001E34EA /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml.h; path = "dialogxml/TinyXML++/tinyxml.h"; sourceTree = "<group>"; };
910BBA2C0FB8C459001E34EA /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlerror.cpp; path = "dialogxml/TinyXML++/tinyxmlerror.cpp"; sourceTree = "<group>"; };
910BBA2D0FB8C459001E34EA /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlparser.cpp; path = "dialogxml/TinyXML++/tinyxmlparser.cpp"; sourceTree = "<group>"; };
910BBA2E0FB8C459001E34EA /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinystr.cpp; path = "dialogxml/TinyXML++/tinystr.cpp"; sourceTree = "<group>"; };
910BBA2F0FB8C470001E34EA /* ticpprc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ticpprc.h; path = "dialogxml/TinyXML++/ticpprc.h"; sourceTree = "<group>"; };
910BBA270FB8C459001E34EA /* ticpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ticpp.cpp; path = "dialogxml/xml-parser/ticpp.cpp"; sourceTree = "<group>"; };
910BBA280FB8C459001E34EA /* ticpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ticpp.h; path = "dialogxml/xml-parser/ticpp.h"; sourceTree = "<group>"; };
910BBA290FB8C459001E34EA /* tinystr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinystr.h; path = "dialogxml/xml-parser/tinystr.h"; sourceTree = "<group>"; };
910BBA2A0FB8C459001E34EA /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml.cpp; path = "dialogxml/xml-parser/tinyxml.cpp"; sourceTree = "<group>"; };
910BBA2B0FB8C459001E34EA /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml.h; path = "dialogxml/xml-parser/tinyxml.h"; sourceTree = "<group>"; };
910BBA2C0FB8C459001E34EA /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlerror.cpp; path = "dialogxml/xml-parser/tinyxmlerror.cpp"; sourceTree = "<group>"; };
910BBA2D0FB8C459001E34EA /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxmlparser.cpp; path = "dialogxml/xml-parser/tinyxmlparser.cpp"; sourceTree = "<group>"; };
910BBA2E0FB8C459001E34EA /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinystr.cpp; path = "dialogxml/xml-parser/tinystr.cpp"; sourceTree = "<group>"; };
910BBA2F0FB8C470001E34EA /* ticpprc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ticpprc.h; path = "dialogxml/xml-parser/ticpprc.h"; sourceTree = "<group>"; };
910BBA3B0FB8DA8E001E34EA /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = dialogxml/control.h; sourceTree = "<group>"; };
910BBA3C0FB8DA8E001E34EA /* control.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = control.cpp; path = dialogxml/control.cpp; sourceTree = "<group>"; };
910BBA880FB8EC57001E34EA /* button.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = button.h; path = dialogxml/button.h; sourceTree = "<group>"; };
@@ -344,6 +358,7 @@
913D05BA0FA1EA0A00184C18 /* pc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pc.h; path = classes/pc.h; sourceTree = "<group>"; };
913D05BB0FA1EA0A00184C18 /* pc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pc.cpp; path = classes/pc.cpp; sourceTree = "<group>"; };
913D6C040FC57A8E00E12527 /* boeresources.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = boeresources.icns; sourceTree = "<group>"; };
9141DAB50FCB94900047D3A3 /* libticpp.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libticpp.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
91A79DC60FA797BF00A6A41F /* menu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = menu.xib; sourceTree = "<group>"; };
91A79DDD0FA79DEE00A6A41F /* dialogs.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = dialogs.xib; sourceTree = "<group>"; };
91AC607E0FA26A3B00EEAE67 /* regtown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = regtown.h; path = classes/regtown.h; sourceTree = "<group>"; };
@@ -445,6 +460,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
9141DAB30FCB94900047D3A3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
91B3EF160F969C2200BF5B67 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -458,6 +480,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9141DAC00FCB95B80047D3A3 /* libticpp.dylib in Frameworks */,
91B3EF5D0F969F3500BF5B67 /* Carbon.framework in Frameworks */,
913D026A0FA0EB0500184C18 /* QuickTime.framework in Frameworks */,
);
@@ -489,6 +512,7 @@
91B3EF180F969C2200BF5B67 /* Blades of Exile Character Editor.app */,
91B3EF3F0F969F0000BF5B67 /* BoE Scenario Editor.app */,
912793480F9C0FE6007B0D52 /* ViewDlog.app */,
9141DAB50FCB94900047D3A3 /* libticpp.dylib */,
);
name = Products;
sourceTree = "<group>";
@@ -496,7 +520,7 @@
910BBA130FB8BE66001E34EA /* dialogs */ = {
isa = PBXGroup;
children = (
910BBA190FB8C43E001E34EA /* TinyXML++ */,
910BBA190FB8C43E001E34EA /* xml-parser */,
910BBA140FB8BE7D001E34EA /* headers */,
910BBA150FB8BE88001E34EA /* src */,
910BBA160FB8BE98001E34EA /* common */,
@@ -539,7 +563,7 @@
name = common;
sourceTree = "<group>";
};
910BBA190FB8C43E001E34EA /* TinyXML++ */ = {
910BBA190FB8C43E001E34EA /* xml-parser */ = {
isa = PBXGroup;
children = (
910BBA270FB8C459001E34EA /* ticpp.cpp */,
@@ -552,7 +576,7 @@
910BBA2D0FB8C459001E34EA /* tinyxmlparser.cpp */,
910BBA2E0FB8C459001E34EA /* tinystr.cpp */,
);
name = "TinyXML++";
name = "xml-parser";
sourceTree = "<group>";
};
91279BAB0F9CFB18007B0D52 /* classes */ = {
@@ -871,6 +895,16 @@
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
9141DAB10FCB94900047D3A3 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
2BF04AC00BF518D4006C0831 /* Blades of Exile */ = {
isa = PBXNativeTarget;
@@ -908,6 +942,23 @@
productReference = 912793480F9C0FE6007B0D52 /* ViewDlog.app */;
productType = "com.apple.product-type.application";
};
9141DAB40FCB94900047D3A3 /* ticpp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9141DAB80FCB94AE0047D3A3 /* Build configuration list for PBXNativeTarget "ticpp" */;
buildPhases = (
9141DAB10FCB94900047D3A3 /* Headers */,
9141DAB20FCB94900047D3A3 /* Sources */,
9141DAB30FCB94900047D3A3 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = ticpp;
productName = ticpp;
productReference = 9141DAB50FCB94900047D3A3 /* libticpp.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
91B3EF170F969C2200BF5B67 /* Blades of Exile Character Editor */ = {
isa = PBXNativeTarget;
buildConfigurationList = 91B3EF1D0F969C2400BF5B67 /* Build configuration list for PBXNativeTarget "Blades of Exile Character Editor" */;
@@ -937,6 +988,7 @@
buildRules = (
);
dependencies = (
9141DABC0FCB95030047D3A3 /* PBXTargetDependency */,
);
name = "BoE Scenario Editor";
productName = "BoE Scenario Editor";
@@ -964,6 +1016,7 @@
91B3EF3E0F969F0000BF5B67 /* BoE Scenario Editor */,
912793470F9C0FE5007B0D52 /* ViewDlog */,
91EBE9DA0F9A33A1002356F2 /* All */,
9141DAB40FCB94900047D3A3 /* ticpp */,
);
};
/* End PBXProject section */
@@ -1080,6 +1133,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
9141DAB20FCB94900047D3A3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9141DAC20FCB95C90047D3A3 /* ticpp.cpp in Sources */,
9141DAC30FCB95C90047D3A3 /* tinystr.cpp in Sources */,
9141DAC40FCB95CA0047D3A3 /* tinyxml.cpp in Sources */,
9141DAC50FCB95CA0047D3A3 /* tinyxmlerror.cpp in Sources */,
9141DAC60FCB95CB0047D3A3 /* tinyxmlparser.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
91B3EF150F969C2200BF5B67 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1155,17 +1220,23 @@
91AC60A90FA26C1B00EEAE67 /* tmpltown.cpp in Sources */,
91AC620C0FA2853700EEAE67 /* creatlist.cpp in Sources */,
91AC65520FA3441B00EEAE67 /* universe.cpp in Sources */,
910BBA470FB8E34E001E34EA /* ticpp.cpp in Sources */,
910BBA480FB8E34E001E34EA /* tinystr.cpp in Sources */,
910BBA490FB8E34F001E34EA /* tinyxml.cpp in Sources */,
910BBA4A0FB8E350001E34EA /* tinyxmlerror.cpp in Sources */,
910BBA4B0FB8E351001E34EA /* tinyxmlparser.cpp in Sources */,
91C1FCA60FCB6F7000EBAA65 /* button.cpp in Sources */,
91C1FCA70FCB6F7100EBAA65 /* control.cpp in Sources */,
91C1FCA80FCB6F7100EBAA65 /* dialog.cpp in Sources */,
91C1FCA90FCB6F7200EBAA65 /* field.cpp in Sources */,
91C1FCAA0FCB6F7200EBAA65 /* message.cpp in Sources */,
91C1FCAB0FCB6F7300EBAA65 /* pict.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
9141DABC0FCB95030047D3A3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 9141DAB40FCB94900047D3A3 /* ticpp */;
targetProxy = 9141DABB0FCB95030047D3A3 /* PBXContainerItemProxy */;
};
91EBE9DE0F9A33A6002356F2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 2BF04AC00BF518D4006C0831 /* Blades of Exile */;
@@ -1381,6 +1452,39 @@
};
name = Release;
};
9141DAB60FCB94900047D3A3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
EXECUTABLE_PREFIX = lib;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = TIXML_USE_TICPP;
INSTALL_PATH = /usr/local/lib;
PREBINDING = NO;
PRODUCT_NAME = ticpp;
ZERO_LINK = YES;
};
name = Debug;
};
9141DAB70FCB94900047D3A3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_PREFIX = lib;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_MODEL_TUNING = G5;
GCC_PREPROCESSOR_DEFINITIONS = TIXML_USE_TICPP;
INSTALL_PATH = /usr/local/lib;
PREBINDING = NO;
PRODUCT_NAME = ticpp;
ZERO_LINK = NO;
};
name = Release;
};
91B3EF1B0F969C2300BF5B67 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1464,6 +1568,11 @@
GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
INFOPLIST_FILE = "Scenario Editor/BoE Scenario Editor-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
);
LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
OTHER_CFLAGS = "-fpack-struct=2";
OTHER_CPLUSPLUSFLAGS = "-fpack-struct=2";
@@ -1500,6 +1609,11 @@
GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
INFOPLIST_FILE = "Scenario Editor/BoE Scenario Editor-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
);
LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
MACOSX_DEPLOYMENT_TARGET_i386 = 10.4;
OTHER_CFLAGS = "-fpack-struct=2";
OTHER_CPLUSPLUSFLAGS = "-fpack-struct=2";
@@ -1568,6 +1682,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9141DAB80FCB94AE0047D3A3 /* Build configuration list for PBXNativeTarget "ticpp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9141DAB60FCB94900047D3A3 /* Debug */,
9141DAB70FCB94900047D3A3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
91B3EF1D0F969C2400BF5B67 /* Build configuration list for PBXNativeTarget "Blades of Exile Character Editor" */ = {
isa = XCConfigurationList;
buildConfigurations = (

210
osx/dialogxml/button.cpp Normal file
View File

@@ -0,0 +1,210 @@
/*
* button.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#include <vector>
#include <map>
using namespace std;
#include "dialog.h"
#include "graphtool.h"
void cButton::attachFocusHandler(focus_callback_t f __attribute__((unused))) throw(xHandlerNotSupported){
throw xHandlerNotSupported(true);
}
void cButton::attachClickHandler(click_callback_t f) throw(){
onClick = f;
}
bool cButton::triggerClickHandler(cDialog& me, std::string id, eKeyMod mods){
if(onClick != NULL) return onClick(me,id,mods);
return false;
}
cButton::cButton(cDialog* parent) : cControl(parent) {}
bool cButton::isClickable(){
return true;
}
void cButton::draw(){
GrafPtr old_port;
Rect from_rect, to_rect;
GWorldPtr from_gw, to_gw;
GetPort(&old_port);
SetPortWindowPort(parent->win);
if(visible){
TextFont(font_nums[GENEVA]);
if(foundSilom())TextFace(normal);
else TextFace(bold);
if(type == BTN_TINY) TextSize(9);
else if(type == BTN_PUSH) TextSize(10);
else TextSize(12);
from_gw = buttons[btnGW[type]];
to_gw = (GWorldPtr) parent->win;
from_rect = btnRects[btnGW[type]][depressed];
to_rect = frame;
rect_draw_some_item(from_gw,from_rect,to_gw,to_rect,0,2);
RGBForeColor(&parent->defTextClr);
char_win_draw_string(parent->win,to_rect,lbl.c_str(),1,8,false);
// TODO: Adjust string location as appropriate
// Tiny button string location should be shifted right 20 pixels (or possibly 18)
// Push button string should be centred below the button
// Others may need adjustments too, not sure
ForeColor(blackColor);
if(key.spec && key.k == key_enter) drawFrame(2,0); // frame default button, to provide a visual cue that it's the default
}else{
FillCRect(&frame,bg[parent->bg]);
}
SetPort(old_port);
}
void cButton::setFormat(eFormat prop, short val) throw(xUnsupportedProp){
if(prop == TXT_WRAP) wrapLabel = val;
else throw xUnsupportedProp(prop);
if(isVisible()) draw();
}
short cButton::getFormat(eFormat prop) throw(xUnsupportedProp){
if(prop == TXT_WRAP) return wrapLabel;
else throw xUnsupportedProp(prop);
}
// Indices within the buttons array.
size_t cButton::btnGW[13] = {
0, // BTN_SM
1, // BTN_REG
2, // BTN_LG
4, // BTN_HELP
1, // BTN_LEFT
1, // BTN_RIGHT
1, // BTN_UP
1, // BTN_DOWN
5, // BTN_TINY
1, // BTN_DONE
3, // BTN_TALL
3, // BTN_TRAIT
6, // BTN_PUSH
};
GWorldPtr cButton::buttons[7] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
Rect cButton::btnRects[13][2];
void cButton::init(){
for(int i = 0; i < 7; i++)
buttons[i] = load_pict(i + 2030);
SetRect(&btnRects[BTN_SM][0],0,0,23,23);
SetRect(&btnRects[BTN_REG][0],0,0,63,23);
SetRect(&btnRects[BTN_LEFT][0],0,23,63,46);
SetRect(&btnRects[BTN_RIGHT][0],0,46,63,69);
SetRect(&btnRects[BTN_UP][0],0,69,63,92);
SetRect(&btnRects[BTN_DOWN][0],0,92,63,115);
SetRect(&btnRects[BTN_DONE][0],0,115,63,138);
SetRect(&btnRects[BTN_LG][0],0,0,104,23);
SetRect(&btnRects[BTN_HELP][0],0,0,16,13);
SetRect(&btnRects[BTN_TINY][0],42,0,56,10);
SetRect(&btnRects[BTN_TALL][0],0,0,63,40);
SetRect(&btnRects[BTN_TRAIT][0],0,40,63,80);
SetRect(&btnRects[BTN_PUSH][0],0,0,30,30);
for(int j = 0; j < 12; j++)
btnRects[j][1] = btnRects[j][0];
OffsetRect(&btnRects[BTN_SM][1],23,0);
OffsetRect(&btnRects[BTN_REG][1],63,0);
OffsetRect(&btnRects[BTN_LEFT][1],63,0);
OffsetRect(&btnRects[BTN_RIGHT][1],63,0);
OffsetRect(&btnRects[BTN_UP][1],63,0);
OffsetRect(&btnRects[BTN_DOWN][1],63,0);
OffsetRect(&btnRects[BTN_DONE][1],63,0);
OffsetRect(&btnRects[BTN_LG][1],104,0);
OffsetRect(&btnRects[BTN_HELP][1],16,0);
OffsetRect(&btnRects[BTN_TINY][1],0,10);
OffsetRect(&btnRects[BTN_TALL][1],63,0);
OffsetRect(&btnRects[BTN_TRAIT][1],63,0);
OffsetRect(&btnRects[BTN_PUSH][1],30,0);
}
Rect cLed::ledRects[3][2];
void cLed::init(){
Rect baseLed = {0,0,10,14};
for(int i = 0; i < 3; i++)
for(int j = 0; j < 2; j++){
ledRects[i][j] = baseLed;
OffsetRect(&ledRects[i][j],i * 14, j * 10);
}
}
cLed::cLed(cDialog* parent) : cButton(parent) {}
void cLed::attachClickHandler(click_callback_t f) throw(){
onClick = f;
}
void cLed::attachFocusHandler(focus_callback_t __attribute__((unused))) throw(xHandlerNotSupported){
throw xHandlerNotSupported(true);
}
bool cLed::triggerClickHandler(cDialog& me, std::string id, eKeyMod mods){
if(onClick != NULL) return onClick(me,id,mods);
return false;
}
void cLed::setFormat(eFormat prop __attribute__((unused)), short val __attribute__((unused))) throw(xUnsupportedProp){
throw xUnsupportedProp(prop);
}
short cLed::getFormat(eFormat prop __attribute__((unused))) throw(xUnsupportedProp){
throw xUnsupportedProp(prop);
}
void cLed::draw(){
GrafPtr old_port;
Rect from_rect, to_rect;
GWorldPtr from_gw, to_gw;
GetPort(&old_port);
SetPortWindowPort(parent->win);
if(visible){
TextFont(font_nums[GENEVA]);
if(foundSilom())TextFace(normal);
else TextFace(bold);
TextSize(9);
from_gw = buttons[BTN_LED];
to_gw = (GWorldPtr) parent->win;
from_rect = ledRects[state][depressed];
to_rect = frame;
rect_draw_some_item(from_gw,from_rect,to_gw,to_rect,0,2);
RGBForeColor(&parent->defTextClr);
char_win_draw_string(parent->win,to_rect,lbl.c_str(),1,8,false);
// TODO: Adjust string location as appropriate
// String location should be shifted right 20 pixels (or possibly 18)
ForeColor(blackColor);
}else{
FillCRect(&frame,bg[parent->bg]);
}
SetPort(old_port);
}
cLedGroup::cLedGroup(cDialog* parent) : cControl(parent) {}
cButton::~cButton() {}
cLed::~cLed() {}
cLedGroup::~cLedGroup(){
ledIter iter = choices.begin();
while(iter != choices.end()){
delete iter->second;
iter++;
}
}

113
osx/dialogxml/button.h Normal file
View File

@@ -0,0 +1,113 @@
/*
* button.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef BUTTON_H
#define BUTTON_H
#include <string>
#include <map>
#include <vector>
enum eBtnType { // w x h
BTN_SM = 0, // 23x23 (PICT id 2000 / 2001)
BTN_REG, // 63x23 (PICT id 2002 / 2003)
BTN_LG, // 102x23 (PICT id 2004 / 2005)
BTN_HELP, // 16x13 (PICT id 2006 / 2007) white bubble w/ ? mark
BTN_LEFT, // 63x23 (PICT id 2008 / 2009) with left arrow
BTN_RIGHT, // 63x23 (PICT id 2010 / 2011) with right arrow
BTN_UP, // 63x23 (PICT id 2012 / 2013) with up arrow
BTN_DOWN, // 63x23 (PICT id 2014 / 2015) with down arrow
BTN_TINY, // 14x10 (PICT id 2021)
BTN_DONE, // 63x23 (PICT id 2022 / 2023) says "Done"
BTN_TALL, // 63x40 (PICT id 2024 / 2025)
BTN_TRAIT, // 63x40 (PICT id 2026 / 2027) says "Race Good/Bad Traits"
BTN_PUSH, // 30x30 (PICT id 2028 / 2029) red round button
BTN_LED, // 14x10 (PICT id 2018 / 2019 / 2020)
};
enum eLedState {led_green = 0, led_red, led_off};
class cButton : public cControl {
public:
static void init();
void attachClickHandler(click_callback_t f) throw();
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
//virtual void setPict(short pict, short type) = 0;
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
cButton(cDialog* parent);
bool isClickable();
virtual ~cButton();
protected:
//friend class cDialog;
void draw();
private:
friend class cDialog;
click_callback_t onClick;
bool wrapLabel;
bool labelWithKey;
bool pressed;
eBtnType type;
std::string fromList;
static Rect btnRects[13][2];
static size_t btnGW[13];
protected:
static GWorldPtr buttons[7];
};
class cLed : public cButton {
public:
static void init();
void attachClickHandler(click_callback_t f) throw();
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
cLed(cDialog* parent);
virtual ~cLed();
protected:
void draw();
private:
friend class cDialog;
eLedState state;
eTextFont textFont;
RGBColor color;
short textSize;
static Rect ledRects[3][2];
click_callback_t onClick;
};
class cLedGroup : public cControl {
std::vector<cLed> btns;
click_callback_t onClick;
focus_callback_t onFocus;
std::map<std::string,cLed*> choices;
std::string fromList;
friend class cDialog;
public:
void attachClickHandler(click_callback_t f) throw(); // activated whenever a click is received, even on the currently active LED
void attachFocusHandler(focus_callback_t f) throw(); // activated only when the selection changes
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
void setSelected(std::string id);
std::string getSelected();
void disable(std::string id);
void enable(std::string id);
void hide(std::string id);
void show(std::string id);
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
cLedGroup(cDialog* parent);
bool isClickable();
virtual ~cLedGroup();
typedef std::map<std::string,cLed*>::iterator ledIter;
protected:
void draw();
};
#endif

298
osx/dialogxml/control.cpp Normal file
View File

@@ -0,0 +1,298 @@
/*
* control.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#include <sstream>
#include "dialog.h"
#include "soundtool.h"
extern bool play_sounds;
void cControl::setLabel(std::string l){
lbl = l;
if(isVisible()) draw();
}
std::string cControl::getLabel(){
return lbl;
}
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::setLabelToKey(){
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;
}
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;
}
cControl::cControl(cDialog* p){
parent = p;
}
bool cControl::triggerClickHandler(cDialog& me __attribute__((unused)), std::string id __attribute__((unused)), eKeyMod mods __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(&lt_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() {}

120
osx/dialogxml/control.h Normal file
View File

@@ -0,0 +1,120 @@
/*
* control.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef CONTROL_H
#define CONTROL_H
#include <string>
#include <exception>
//struct cPict {
// short pict;
// short type;
//};
enum eKeyMod {
mod_none = 0,
mod_alt = 1, mod_shift = 2, mod_ctrl = 4,
mod_altshift = mod_alt + mod_shift,
mod_altctrl = mod_alt + mod_ctrl,
mod_shiftctrl = mod_shift + mod_ctrl,
mod_all = mod_alt + mod_shift + mod_ctrl,
};
enum eSpecKey {
key_left, key_right, key_up, key_down,
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
// 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.
};
struct cKey {
bool spec;
union {
unsigned char c;
eSpecKey k;
};
eKeyMod mod;
};
bool operator== (cKey& a, cKey& b);
enum eFormat {
TXT_COLOR,
TXT_FRAME,
TXT_FONT,
TXT_SIZE,
TXT_WRAP,
};
enum eTextFont {DUNGEON, GENEVA, SILOM, MAIDENWORD};
class cDialog;
typedef bool (*click_callback_t)(cDialog&/*me*/,std::string/*id*/, eKeyMod/*mods*/);
typedef bool (*focus_callback_t)(cDialog&/*me*/,std::string/*id*/,bool/*losing*/); // losing is true if losing focus, false if gaining focus.
class xHandlerNotSupported : std::exception {
static const char* focusMsg;
static const char* clickMsg;
bool isFocus;
public:
xHandlerNotSupported(bool isFocus);
const char* what();
};
class xUnsupportedProp : std::exception {
eFormat whichProp;
char* msg;
public:
xUnsupportedProp(eFormat prop) throw();
~xUnsupportedProp() throw();
const char* what() throw();
};
class cControl {
public:
static void init();
void attachKey(cKey key);
virtual void attachClickHandler(click_callback_t f) throw(xHandlerNotSupported) = 0;
virtual void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported) = 0;
virtual bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
virtual bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
//virtual void setPict(short pict, short type) = 0;
virtual void show(); // cd_activate_item true
virtual void hide(); // cd_activate_item false
bool isVisible(); // cd_get_active
void setLabel(std::string l);
std::string getLabel();
void setLabelToKey();
virtual void setFormat(eFormat prop, short val) throw(xUnsupportedProp) = 0;
virtual short getFormat(eFormat prop) throw(xUnsupportedProp) = 0;
virtual bool isClickable() = 0;
bool handleClick();
cControl(cDialog* p);
virtual ~cControl();
protected:
cDialog* parent;
std::string lbl;
cKey key;
bool visible, depressed; // depressed is only applicable for clickable controls
Rect frame;
friend class cDialog;
virtual void draw() = 0;
static bool foundSilom();
static short font_nums[4];
void drawFrame(short amt, short med_or_lt);
private:
static bool found_silom;
};
eKeyMod operator + (eKeyMod lhs, eKeyMod rhs);
eKeyMod operator - (eKeyMod lhs, eKeyMod rhs);
eKeyMod&operator += (eKeyMod&lhs, eKeyMod rhs);
eKeyMod&operator -= (eKeyMod&lhs, eKeyMod rhs);
#endif

920
osx/dialogxml/dialog.cpp Normal file
View File

@@ -0,0 +1,920 @@
/*
* dialog.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#define SLEEP_TICKS 2L
#define MOUSE_REGION 0L
#define IN_FRONT (WindowPtr)-1L
#include "dialog.h"
#include "graphtool.h"
#include "soundtool.h"
using namespace std;
using namespace ticpp;
extern bool play_sounds;
const short cDialog::BG_DARK = 5, cDialog::BG_LIGHT = 16;
template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){
pair<string,cPict*> p;
Iterator<Attribute> attr;
string name, val;
int width = 0, height = 0;
bool wide = false, tall = false, custom = false;
p.second = new cPict(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "type"){
if(val == "blank"){
p.second->picType = PIC_TER;
p.second->picNum = -1;
}else if(val == "ter")
p.second->picType = PIC_TER;
else if(val == "teranim")
p.second->picType = PIC_TER_ANIM;
else if(val == "monst")
p.second->picType = PIC_MONST;
else if(val == "dlog")
p.second->picType = PIC_DLOG;
else if(val == "talk")
p.second->picType = PIC_TALK;
else if(val == "scen")
p.second->picType = PIC_SCEN;
else if(val == "item")
p.second->picType = PIC_ITEM;
else if(val == "pc")
p.second->picType = PIC_PC;
else if(val == "field")
p.second->picType = PIC_FIELD;
else if(val == "boom")
p.second->picType = PIC_BOOM;
else if(val == "missile")
p.second->picType = PIC_MISSILE;
else if(val == "full")
p.second->picType = PIC_FULL;
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"){
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);
sin >> p.second->picNum;
}else if(name == "top"){
istringstream sin(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin(val);
sin >> width;
}else if(name == "height"){
istringstream sin(val);
sin >> height;
}else throw xBadAttr("pict",name);
}
if(wide && !tall && p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_WIDE;
else if(!wide && tall && p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_TALL;
else if(wide && tall){
if(p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_LG;
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;
}
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;
}else switch(p.second->picType){
case PIC_DLOG:
p.second->frame.right = p.second->frame.left + 36;
p.second->frame.bottom = p.second->frame.top + 36;
break;
case PIC_DLOG_LG:
p.second->frame.right = p.second->frame.left + 72;
p.second->frame.bottom = p.second->frame.top + 72;
break;
case PIC_SCEN:
case PIC_TALK:
p.second->frame.right = p.second->frame.left + 32;
p.second->frame.bottom = p.second->frame.top + 32;
break;
case PIC_SCEN_LG:
p.second->frame.right = p.second->frame.left + 64;
p.second->frame.bottom = p.second->frame.top + 64;
break;
case PIC_MISSILE:
p.second->frame.right = p.second->frame.left + 18;
p.second->frame.bottom = p.second->frame.top + 18;
break;
default:
p.second->frame.right = p.second->frame.left + 28;
p.second->frame.bottom = p.second->frame.top + 36;
break;
}
if(custom) p.second->picType += PIC_CUSTOM;
return p;
}
template<> pair<string,cTextMsg*> cDialog::parse(Element& who /*text*/){
pair<string,cTextMsg*> p;
Iterator<Attribute> attr;
Iterator<Node> node;
string name, val;
int width = 0, height = 0;
p.second = new cTextMsg(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
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"){
if(val == "dungeon")
p.second->textFont = DUNGEON;
else if(val == "geneva")
p.second->textFont = GENEVA;
else if(val == "silom")
p.second->textFont = SILOM;
else if(val == "maidenword")
p.second->textFont = MAIDENWORD;
else throw xBadVal("text",name,val);
}else if(name == "size"){
if(val == "large")
p.second->textSize = 12;
else if(val == "small")
p.second->textSize = 10;
else throw xBadVal("text",name,val);
}else if(name == "color" || name == "colour"){
RGBColor clr;
try{
clr = parseColor(val);
}catch(int){
throw xBadVal("text",name,val);
}
p.second->color = clr;
}else if(name == "top"){
istringstream sin(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin(val);
sin >> width;
}else if(name == "height"){
istringstream sin(val);
sin >> height;
}else if(name == "fromlist"){
p.second->fromList = val;
}else throw xBadAttr("pict",name);
}
p.second->frame.right = p.second->frame.left + width;
p.second->frame.bottom = p.second->frame.top + height;
string content;
for(node = node.begin(&who); node != node.end(); node++){
string val;
int type = node->Type();
node->GetValue(&val);
if(type == TiXmlNode::ELEMENT && val == "br") content += '|'; // because vertical bar is replaced by a newline when drawing strings
else if(type == TiXmlNode::TEXT) content += val;
else{
val = '<' + val + '>';
throw xBadVal("text","<content>",content + val);
}
}
p.second->lbl = content;
return p;
}
/**
* Parses an HTML-style colour string, recognizing three-digit hex, six-digit hex, and HTML colour names.
*/
RGBColor cDialog::parseColor(string what){
RGBColor clr;
if(what[0] == '#'){
unsigned int r,g,b;
if(sscanf(what.c_str(),"#%2x%2x%2x",&r,&g,&b) < 3)
if(sscanf(what.c_str(),"#%1x%1x%1x",&r,&g,&b) < 3)
throw -1;
clr.red = r, clr.green = g, clr.blue = b;
}else if(what == "black")
clr.red = 0x00, clr.green = 0x00, clr.blue = 0x00;
else if(what == "red")
clr.red = 0xFF, clr.green = 0x00, clr.blue = 0x00;
else if(what == "lime")
clr.red = 0x00, clr.green = 0xFF, clr.blue = 0x00;
else if(what == "blue")
clr.red = 0x00, clr.green = 0x00, clr.blue = 0xFF;
else if(what == "yellow")
clr.red = 0xFF, clr.green = 0xFF, clr.blue = 0x00;
else if(what == "aqua")
clr.red = 0x00, clr.green = 0xFF, clr.blue = 0xFF;
else if(what == "fuchsia")
clr.red = 0xFF, clr.green = 0x00, clr.blue = 0xFF;
else if(what == "white")
clr.red = 0xFF, clr.green = 0xFF, clr.blue = 0xFF;
else if(what == "gray" || what == "grey")
clr.red = 0x80, clr.green = 0x80, clr.blue = 0x80;
else if(what == "maroon")
clr.red = 0x80, clr.green = 0x00, clr.blue = 0x00;
else if(what == "green")
clr.red = 0x00, clr.green = 0x80, clr.blue = 0x00;
else if(what == "navy")
clr.red = 0x00, clr.green = 0x00, clr.blue = 0x80;
else if(what == "olive")
clr.red = 0x80, clr.green = 0x80, clr.blue = 0x00;
else if(what == "teal")
clr.red = 0x00, clr.green = 0x80, clr.blue = 0x80;
else if(what == "purple")
clr.red = 0x80, clr.green = 0x00, clr.blue = 0x80;
else if(what == "silver")
clr.red = 0xC0, clr.green = 0xC0, clr.blue = 0xC0;
else throw -1;
clr.red *= clr.red;
clr.green *= clr.green;
clr.blue *= clr.blue;
return clr;
}
template<> pair<string,cButton*> cDialog::parse(Element& who /*button*/){
pair<string,cButton*> p;
Iterator<Attribute> attr;
Iterator<Node> node;
string name, val;
int width = 0, height = 0;
p.second = new cButton(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
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")
p.second->type = BTN_REG;
else if(val == "large")
p.second->type = BTN_LG;
else if(val == "help")
p.second->type = BTN_HELP;
else if(val == "left")
p.second->type = BTN_LEFT;
else if(val == "right")
p.second->type = BTN_RIGHT;
else if(val == "up")
p.second->type = BTN_UP;
else if(val == "down")
p.second->type = BTN_DOWN;
else if(val == "tiny")
p.second->type = BTN_TINY;
else if(val == "done")
p.second->type = BTN_DONE;
else if(val == "tall")
p.second->type = BTN_TALL;
else if(val == "trait")
p.second->type = BTN_TRAIT;
else if(val == "push")
p.second->type = BTN_PUSH;
}else if(name == "def-key"){
try{
p.second->key = parseKey(val);
}catch(int){
throw xBadVal("button",name,val);
}
}else if(name == "fromlist")
p.second->fromList = val;
else if(name == "top"){
istringstream sin(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin;
sin >> width;
}else if(name == "height"){
istringstream sin;
sin >> height;
}else throw xBadAttr("button",name);
}
if(width > 0 || height > 0) {
p.second->frame.right = p.second->frame.left + width;
p.second->frame.bottom = p.second->frame.top + height;
}else switch(p.second->type){
case BTN_SM:
p.second->frame.right = p.second->frame.left + 23;
p.second->frame.bottom = p.second->frame.top + 23;
break;
case BTN_LG:
p.second->frame.right = p.second->frame.left + 102;
p.second->frame.bottom = p.second->frame.top + 23;
break;
case BTN_HELP:
p.second->frame.right = p.second->frame.left + 16;
p.second->frame.bottom = p.second->frame.top + 13;
break;
case BTN_TINY:
case BTN_LED: // this should never happen
p.second->frame.right = p.second->frame.left + 14;
p.second->frame.bottom = p.second->frame.top + 10;
break;
case BTN_TALL:
case BTN_TRAIT:
p.second->frame.right = p.second->frame.left + 63;
p.second->frame.bottom = p.second->frame.top + 40;
break;
case BTN_PUSH:
p.second->frame.right = p.second->frame.left + 30;
p.second->frame.bottom = p.second->frame.top + 30;
break;
default:
p.second->frame.right = p.second->frame.left + 63;
p.second->frame.bottom = p.second->frame.top + 23;
}
string content;
for(node = node.begin(&who); node != node.end(); node++){
string val;
int type = node->Type();
node->GetValue(&val);
if(type == TiXmlNode::ELEMENT && val == "key"){
if(content.length() > 0) throw xBadVal("button","<content>",content + val);
p.second->labelWithKey = true;
}else if(type == TiXmlNode::TEXT) content += val;
else{
val = '<' + val + '>';
throw xBadVal("text","<content>",val);
}
}
p.second->lbl = content;
return p;
}
cKey cDialog::parseKey(string what){
cKey key;
key.spec = false;
key.c = 0;
key.mod = mod_none;
istringstream sin(what);
string parts[4];
sin >> parts[0] >> parts[1] >> parts[2] >> parts[3];
for(int i = 0; i < 4; i++){
if(parts[i] == "ctrl") key.mod += mod_ctrl;
else if(parts[i] == "alt") key.mod += mod_alt;
else if(parts[i] == "shift") key.mod += mod_shift;
else if(parts[i] == "left") {
key.spec = true;
key.k = key_left;
break;
}else if(parts[i] == "right") {
key.spec = true;
key.k = key_right;
break;
}else if(parts[i] == "up") {
key.spec = true;
key.k = key_up;
break;
}else if(parts[i] == "down") {
key.spec = true;
key.k = key_down;
break;
}else if(parts[i] == "esc") {
key.spec = true;
key.k = key_esc;
break;
}else if(parts[i] == "enter" || parts[i] == "return") {
key.spec = true;
key.k = key_enter;
break;
}else if(parts[i] == "tab") {
key.spec = true;
key.k = key_tab;
break;
}else if(parts[i] == "help") {
key.spec = true;
key.k = key_help;
break;
}else if(parts[i] == "space") {
key.c = ' ';
break;
}else if(parts[i].length() == 1) {
key.c = parts[i][0];
break;
}else throw -1;
}
return key;
}
template<> pair<string,cLed*> cDialog::parse(Element& who /*LED*/){
pair<string,cLed*> p;
Iterator<Attribute> attr;
Iterator<Node> node;
string name, val;
int width = 0, height = 0;
p.second = new cLed(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "state"){
if(val == "red") p.second->state = led_red;
else if(val == "green") p.second->state = led_green;
else if(val == "off") p.second->state = led_off;
else throw xBadVal("led",name,val);
}else if(name == "fromlist")
p.second->fromList = val;
else if(name == "font"){
if(val == "dungeon")
p.second->textFont = DUNGEON;
else if(val == "geneva")
p.second->textFont = GENEVA;
else if(val == "silom")
p.second->textFont = SILOM;
else if(val == "maidenword")
p.second->textFont = MAIDENWORD;
else throw xBadVal("text",name,val);
}else if(name == "size"){
if(val == "large")
p.second->textSize = 12;
else if(val == "small")
p.second->textSize = 10;
else throw xBadVal("text",name,val);
}else if(name == "color" || name == "colour"){
RGBColor clr;
try{
clr = parseColor(val);
}catch(int){
throw xBadVal("text",name,val);
}
p.second->color = clr;
}else if(name == "top"){
istringstream sin(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin;
sin >> width;
}else if(name == "height"){
istringstream sin;
sin >> height;
}else throw xBadAttr("button",name);
}
if(width > 0 || height > 0) {
p.second->frame.right = p.second->frame.left + width;
p.second->frame.bottom = p.second->frame.top + height;
}else{
p.second->frame.right = p.second->frame.left + 14;
p.second->frame.bottom = p.second->frame.top + 10;
}
string content;
for(node = node.begin(&who); node != node.end(); node++){
string val;
int type = node->Type();
node->GetValue(&val);
if(type == TiXmlNode::TEXT) content += val;
else{
val = '<' + val + '>';
throw xBadVal("text","<content>",content + val);
}
}
p.second->lbl = content;
return p;
}
template<> pair<string,cLedGroup*> cDialog::parse(Element& who /*group*/){
pair<string,cLedGroup*> p;
Iterator<Attribute> attr;
Iterator<Element> node;
string name, val;
p.second = new cLedGroup(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "fromlist")
p.second->fromList = val;
else throw xBadAttr("button",name);
}
string content;
for(node = node.begin(&who); node != node.end(); node++){
string val;
int type = node->Type();
node->GetValue(&val);
if(type == TiXmlNode::ELEMENT && val == "led"){
p.second->choices.insert(parse<cLed>(*node));
}else{
val = '<' + val + '>';
throw xBadVal("text","<content>", content + val);
}
}
p.second->lbl = content;
return p;
}
template<> pair<string,cTextField*> cDialog::parse(Element& who /*field*/){
pair<string,cTextField*> p;
Iterator<Attribute> attr;
Iterator<Node> node;
string name, val;
int width = 0, height = 0;
p.second = new cTextField(this);
for(attr = attr.begin(&who); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "name")
p.first = val;
else if(name == "type"){
if(val == "num")
p.second->isNumericField = true;
else if(val == "text")
p.second->isNumericField = false;
else throw xBadVal("field",name,val);
}else if(name == "top"){
istringstream sin(val);
sin >> p.second->frame.top;
}else if(name == "left"){
istringstream sin(val);
sin >> p.second->frame.left;
}else if(name == "width"){
istringstream sin;
sin >> width;
}else if(name == "height"){
istringstream sin;
sin >> height;
}else throw xBadAttr("button",name);
}
p.second->frame.right = p.second->frame.left + width;
p.second->frame.bottom = p.second->frame.top + height;
return p;
}
cDialog::cDialog(string path){
try{
Document xml(path);
xml.LoadFile();
Iterator<Attribute> attr;
Iterator<Element> node;
string type, name, val;
xml.GetValue(&type);
if(type != "dialog") throw xBadNode(type);
for(attr = attr.begin(&xml); attr != attr.end(); attr++){
attr->GetName(&name);
attr->GetValue(&val);
if(name == "skin"){
if(val == "light") bg = BG_LIGHT;
else if(val == "dark") bg = BG_DARK;
else{
istringstream sin(val);
sin >> bg;
if(sin.fail()) throw xBadVal(type,name,val);
}
}else if(name != "debug")
throw xBadAttr(type,name);
}
for(node = node.begin(xml.FirstChildElement()); node != node.end(); node++){
node->GetValue(&type);
// Yes, I'm using insert instead of [] to add elements to the map.
// In this situation, it's actually easier that way; the reason being, the
// map key is obtained from the name attribute of each element.
if(type == "field")
controls.insert(parse<cTextField>(*node));
else if(type == "text")
controls.insert(parse<cTextMsg>(*node));
else if(type == "pict")
controls.insert(parse<cPict>(*node));
else if(type == "button")
controls.insert(parse<cButton>(*node));
else if(type == "led")
controls.insert(parse<cLed>(*node));
else if(type == "group")
controls.insert(parse<cLedGroup>(*node));
else throw xBadNode(type);
}
} catch(Exception& x){ // XML processing exception
printf(x.what());
} catch(xBadVal& x){ // Invalid value for an attribute
printf(x.what());
} catch(xBadAttr& x){ // Invalid attribute for an element
printf(x.what());
} catch(xBadNode& x){ // Invalid element
printf(x.what());
}
dialogNotToast = true;
bg = BG_DARK; // default is dark background
// now calculate window rect
SetRect(&winRect,0,0,0,0);
ctrlIter iter = controls.begin();
currentFocus = NULL;
while(iter != controls.end()){
if(iter->second->frame.right > winRect.right)
winRect.right = iter->second->frame.right;
if(iter->second->frame.bottom > winRect.bottom)
winRect.bottom = iter->second->frame.bottom;
if(typeid(iter->second) == typeid(cTextField*)){
cTextField* fld = (cTextField*) iter->second;
if(currentFocus == NULL) currentFocus = fld;
// TODO: Should probably create controls and put them in the window?
}
iter++;
}
winRect.right += 4;
winRect.bottom += 4;
win = NewCWindow(NULL, &winRect, (unsigned char*) "", false, dBoxProc, IN_FRONT, false, 0);
}
void cDialog::init(){
cControl::init();
cButton::init();
cLed::init();
cPict::init();
}
cDialog::~cDialog(){
ctrlIter iter = controls.begin();
while(iter != controls.end()){
delete iter->second;
iter++;
}
DisposeWindow(win);
}
bool cDialog::add(cControl* what, std::string key){
// First make sure the key is not already present.
// If it is, we can't add the control, so return false.
if(controls.find(key) != controls.end()) return false;
controls.insert(std::make_pair(key,what));
return true;
}
bool cDialog::remove(std::string key){
ctrlIter ctrl = controls.find(key);
if(ctrl == controls.end()) return false;
delete ctrl->second;
controls.erase(ctrl);
return true;
}
void cDialog::run(){
char c, k;
cKey key;
EventRecord currentEvent;
std::string itemHit = "";
dialogNotToast = true;
ShowWindow(win);
BeginAppModalStateForWindow(win);
while(dialogNotToast){
WaitNextEvent(everyEvent, &currentEvent, SLEEP_TICKS, MOUSE_REGION);
switch(currentEvent.what){
case updateEvt:
BeginUpdate(win);
draw();
EndUpdate(win);
break;
case keyDown:
case autoKey:
c = currentEvent.message & charCodeMask;
k = (currentEvent.message & keyCodeMask) >> 8;
switch(k){
case 126:
key.spec = true;
key.k = key_up;
break;
case 124:
key.spec = true;
key.k = key_right;
break;
case 123:
key.spec = true;
key.k = key_left;
break;
case 125:
key.spec = true;
key.k = key_down;
break;
case 53:
key.spec = true;
key.k = key_esc;
break;
case 36: case 76:
key.spec = true;
key.k = key_enter;
break;
// TODO: Add cases for key_tab and key_help
default:
key.spec = false;
key.c = c;
break;
}
key.mod = mod_none;
if(currentEvent.modifiers & cmdKey){
if(key.spec){
if(key.k == key_left) key.k = key_home;
else if(key.k == key_right) key.k = key_end;
else if(key.k == key_up) key.k = key_pgup;
else if(key.k == key_down) key.k = key_pgdn;
else key.mod += mod_ctrl;
}else key.mod += mod_ctrl;
}if(currentEvent.modifiers & shiftKey) key.mod += mod_shift;
if(currentEvent.modifiers & alphaLock) key.mod += mod_shift;
if(currentEvent.modifiers & optionKey) key.mod += mod_alt;
if(currentEvent.modifiers & controlKey) key.mod += mod_ctrl;
if(currentEvent.modifiers & rightShiftKey) key.mod += mod_shift;
if(currentEvent.modifiers & rightOptionKey) key.mod += mod_alt;
if(currentEvent.modifiers & rightControlKey) key.mod += mod_ctrl;
itemHit = process_keystroke(key); // TODO: This should be a separate check from the fields thing?
if(typeid(controls[itemHit]) == typeid(cTextField*)){
if(!key.spec || key.k == key_bsp || key.k == key_del || key.k == key_home ||
key.k == key_end || key.k == key_pgup || key.k == key_pgdn ||
key.k == key_left || key.k == key_right || key.k == key_up || key.k == key_down){
// TODO: If the dialog contains a field, handle it here.
// Basically, we should end up here if the user is typing into the field.
itemHit = "";
}else if(key.spec && key.k == key_tab){
// TODO: Tabbing through fields, and trigger focus events.
ctrlIter cur = controls.find(itemHit), iter;
if(!cur->second->triggerFocusHandler(*this,itemHit,true)) break;
iter = cur;
while(iter != cur){
if(typeid(iter->second) == typeid(cTextField*)){
if(iter->second->triggerFocusHandler(*this,iter->first,false)){
currentFocus = (cTextField*) iter->second;
itemHit = "";
break;
}
}
iter++;
if(iter == controls.end()) iter = controls.begin();
}
if(iter == cur) // no focus change occured!
; // TODO: Surely something should happen here?
}
}
break;
case mouseDown:
if(!PtInRect(currentEvent.where,&winRect)) break; // may be superfluous?
key.mod = mod_none;
if(currentEvent.modifiers & cmdKey) key.mod += mod_ctrl;
if(currentEvent.modifiers & shiftKey) key.mod += mod_shift;
if(currentEvent.modifiers & alphaLock) key.mod += mod_shift;
if(currentEvent.modifiers & optionKey) key.mod += mod_alt;
if(currentEvent.modifiers & controlKey) key.mod += mod_ctrl;
if(currentEvent.modifiers & rightShiftKey) key.mod += mod_shift;
if(currentEvent.modifiers & rightOptionKey) key.mod += mod_alt;
if(currentEvent.modifiers & rightControlKey) key.mod += mod_ctrl;
itemHit = process_click(currentEvent.where,key.mod);
break;
}
ctrlIter ctrl = controls.find(itemHit);
if(ctrl != controls.end()) ctrl->second->triggerClickHandler(*this,itemHit,key.mod);
}
EndAppModalStateForWindow(win);
HideWindow(win);
}
void cDialog::setBg(short n){
bg = n;
}
void cDialog::setDefTextClr(RGBColor clr){
defTextClr = clr;
}
void cDialog::toast(){
dialogNotToast = false;
}
std::string cDialog::process_keystroke(cKey keyHit){
unsigned long dummy;
ctrlIter iter = controls.begin();
while(iter != controls.end()){
if(iter->second->visible && iter->second->isClickable() && iter->second->key == keyHit){
iter->second->depressed = true;
iter->second->draw();
if (play_sounds) {
if(typeid(iter->second) == typeid(cLed*))
play_sound(34);
else play_sound(37);
Delay(6,&dummy);
}
else Delay(14,&dummy);
iter->second->depressed = false;
iter->second->draw();
Delay(8,&dummy);
return iter->first;
}
iter++;
}
// If you get an escape and it isn't processed, make it an enter.
if(keyHit.spec && keyHit.k == key_esc){
keyHit.k = key_enter;
return process_keystroke(keyHit);
}
return "";
}
std::string cDialog::process_click(Point where, eKeyMod mods){
ctrlIter iter = controls.begin();
while(iter != controls.end()){
if(iter->second->visible && iter->second->isClickable() && PtInRect(where,&iter->second->frame)){
if(iter->second->handleClick())
return iter->first;
else return "";
}
iter++;
}
return "";
}
xBadNode::xBadNode(std::string t) throw() : type(t), msg(NULL) {}
const char* xBadNode::what() throw() {
if(msg == NULL){
char* s = new (nothrow) char[100];
if(s == NULL){
printf("Allocation of memory for error message failed, bailing out...");
abort();
}
sprintf(s,"XML Parse Error: Unknown element %s encountered.",type.c_str());
msg = s;
}
return msg;
}
xBadNode::~xBadNode() throw(){
if(msg != NULL) delete msg;
}
xBadAttr::xBadAttr(std::string t, std::string n) throw() : type(t), name(n), msg(NULL) {}
const char* xBadAttr::what() throw() {
if(msg == NULL){
char* s = new (nothrow) char[100];
if(s == NULL){
printf("Allocation of memory for error message failed, bailing out...");
abort();
}
sprintf(s,"XML Parse Error: Unknown attribute %s encountered on element %s.",name.c_str(),type.c_str());
msg = s;
}
return msg;
}
xBadAttr::~xBadAttr() throw(){
if(msg != NULL) delete msg;
}
xBadVal::xBadVal(std::string t, std::string n, std::string v) throw() : type(t), name(n), val(v), msg(NULL) {}
const char* xBadVal::what() throw() {
if(msg == NULL){
char* s = new (nothrow) char[100];
if(s == NULL){
printf("Allocation of memory for error message failed, bailing out...");
abort();
}
sprintf(s,"XML Parse Error: Invalid value %s for attribute %s encountered on element %s.",val.c_str(),name.c_str(),type.c_str());
msg = s;
}
return msg;
}
xBadVal::~xBadVal() throw(){
if(msg != NULL) delete msg;
}
void cDialog::draw(){
GrafPtr old_port;
GetPort(&old_port);
SetPortWindowPort(win);
FillCRect(&winRect,::bg[bg]);
ctrlIter iter = controls.begin();
while(iter != controls.end()){
iter->second->draw();
iter++;
}
SetPort(old_port);
}

145
osx/dialogxml/dialog.css Normal file
View File

@@ -0,0 +1,145 @@
* {
position: absolute;
display: block;
margin: 0px;
}
.debug {
border: dotted black thin;
}
title {
display:none;
}
.dialog {
border: dashed green thin;
}
.text, .led, .button, .field {
overflow: hidden ! important;
}
.pict {
padding: 2px;
border: inset black thin;
background-repeat: no-repeat;
background-position: center;
}
.pict.dlog {
width: 36px;
height: 36px;
}
.pict.ter , .pict.teranim , .pict.item ,
.pict.monst , .pict.field , .pict.boom ,
.pict.pc {
width: 28px;
height: 36px;
}
.pict.scen , .pict.talk {
width: 32px;
height: 32px;
}
.pict.missile {
width: 18px;
height: 18px;
}
.pict.scen.large {
width: 64px;
height: 64px;
}
.pict.dlog.large {
width: 72px;
height: 72px;
}
.button , .led {
padding: 0px;
background-repeat: no-repeat;
background-position: center;
text-align: center;
font-size: 12px;
font-family: Silom;
vertical-align: middle;
padding-top: 6px;
}
.button.small {
width: 23px;
height: 23px;
}
.button.regular , .button.left , .button.right ,
.button.up , .button.down , .button.done {
width: 63px;
height: 23px;
}
.button.large {
width: 102px;
height: 23px;
}
.button.help {
width: 16px;
height: 13px;
}
.button.tiny , .led {
min-width: 14px;
height: 10px;
text-align: left;
background-position: left center;
padding-left: 18px;
padding-top: 0px;
padding-bottom: 5px;
font-family: Geneva;
font-size: 10px;
}
.button.tall , .button.trait {
width: 63px;
height: 40px;
padding-top: 22px;
}
.button.push {
min-width: 30px;
height: 30px;
background-position: top center;
padding-top: 30px;
}
.field {
padding: 2px;
border: solid black thin;
}
.field-inner {
background-color:white;
}
.text {
font-size: 10px;
font-family: Silom;
line-height: 12px;
}
.text.framed {
padding: 2px;
border: inset thin black;
}
.text.large {
font-size: 12px;
}
.text.plain {
font-family: Geneva;
}

77
osx/dialogxml/dialog.dtd Normal file
View File

@@ -0,0 +1,77 @@
<!ELEMENT dialog ((field | text | pict | button | led | group)*)>
<!ELEMENT field EMPTY>
<!ELEMENT br EMPTY>
<!ELEMENT text ((#PCDATA|br)*)>
<!ELEMENT pict EMPTY>
<!ELEMENT key EMPTY>
<!ELEMENT button (#PCDATA*|key)>
<!ELEMENT led (CDATA)>
<!ELEMENT group (led+)>
<!ENTITY % num 'NUMBER'>
<!ENTITY % bool '(true|false)'>
<!ENTITY % picttype '(blank|ter|teranim|monst|dlog|talk|scen|item|pc|field|boom|missile|full)'>
<!ENTITY % rect '
top %num; #REQUIRED
left %num; #REQUIRED
width %num; #IMPLIED
height %num; #IMPLIED'
>
<!ENTITY % font "
font (dungeon|geneva|silom|maidenword) 'silom'
size (small|large) 'small'
color CDATA '#000000'"
colour CDATA '#000000'"
>
<!ENTITY % btntype '(small|regular|large|help|left|right|up|down|tiny|done|tall|trait|push)'>
<!ENTITY % digit '(0|1|2|3|4|5|6|7|8|9)'>
<!ENTITY % letter '(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)'>
<!ENTITY % symbol '(`|-|=|[|]|\|;|'|,|.|/)'>
<!ENTITY % mod '((ctrl|shift|alt)*)'>
<!ENTITY % key '(%mod; (%digit;|%letter;|%symbol;|left|right|up|down|esc|enter|return|tab|help|space))'>
<!ATTLIST dialog
skin (light|dark) 'dark'
debug %bool; 'false'
>
<!ATTLIST field
name ID #IMPLIED
type (num|text) 'text'
%rect;
>
<!ATTLIST text
name ID #IMPLIED
framed %bool; 'true'
%font;
clickable %bool; 'false'
fromlist (none|CDATA) 'none'
%rect;
>
<!ATTLIST pict
name ID #IMPLIED
type %picttype; #REQUIRED
custom %bool; 'false'
size (small|wide|tall|large) #IMPLIED
clickable %bool; 'false'
num %num; #REQUIRED
%rect;
>
<!ATTLIST button
name ID #IMPLIED
type %btntype; #REQUIRED
wrap %bool; 'false'
def-key %key; 'none'
fromlist (none|CDATA) 'none'
%rect;
>
<!ATTLIST led
name ID #IMPLIED
state (red|green|off) 'off'
fromlist (none|CDATA) 'none'
%rect;
%font;
>
<!ATTLIST group
name ID #IMPLIED
fromlist (none|CDATA) 'none'
>

88
osx/dialogxml/dialog.h Normal file
View File

@@ -0,0 +1,88 @@
/*
* dialog.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef DIALOG_H
#define DIALOG_H
#include <string>
#include <map>
#include <exception>
#include "ticpp.h"
#include "control.h"
#include "button.h"
#include "field.h"
#include "pict.h"
#include "message.h"
class cDialog {
typedef std::map<std::string,cControl*>::iterator ctrlIter;
std::map<std::string,cControl*> controls;
short bg;
RGBColor defTextClr;
template<class T> std::pair<std::string,T*> parse(ticpp::Element& who);
RGBColor parseColor(std::string what);
cKey parseKey(std::string what);
WindowRef win;
cTextField* currentFocus;
public:
static const short BG_LIGHT, BG_DARK;
static void init(); // must call this before constructing any dialogs
cDialog(std::string path); // cd_create_dialog
cDialog(std::string path,cDialog parent); // cd_create_dialog_parent_num
~cDialog(); // cd_kill_dialog
bool add(cControl* what, std::string key); // returns false if the key is used, true if the control was added
bool remove(std::string key); // returns true if the key existed and was removed, false if the key did not exist
void run(); // cd_run_dialog
//template<class type> type getResult(); // This seems like an unimplementable function
void setBg(short n);
void setDefTextClr(RGBColor clr);
void toast();
private:
void draw();
std::string process_keystroke(cKey keyHit);
std::string process_click(Point where, eKeyMod mods);
bool dialogNotToast;
Rect winRect;
friend class cControl;
friend class cButton;
friend class cLed;
friend class cLedGroup;
friend class cPict;
friend class cTextField;
friend class cTextMsg;
};
class xBadNode : std::exception {
std::string type;
const char* msg;
public:
xBadNode(std::string t) throw();
~xBadNode() throw();
const char* what() throw();
};
class xBadAttr : std::exception {
std::string type, name;
const char* msg;
public:
xBadAttr(std::string t,std::string n) throw();
~xBadAttr() throw();
const char* what() throw();
};
class xBadVal : std::exception {
std::string type, name, val;
const char* msg;
public:
xBadVal(std::string t,std::string n,std::string v) throw();
~xBadVal() throw();
const char* what() throw();
};
#endif

164
osx/dialogxml/dialog.xsl Normal file
View File

@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- <?xml-stylesheet href="http://www.w3.org/StyleSheets/TR/W3C-REC.css" type="text/css"?>
<?xml-stylesheet href="" type="text/css"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match='/'>
<html> <!-- xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" -->
<head>
<title>Dialog Preview</title>
<link rel='stylesheet' type='text/css' href='dialog.css'/>
</head>
<body>
<xsl:attribute name='style'>
background-image: url('bg/<xsl:value-of select='/dialog/@skin'/>.png');
</xsl:attribute>
<div class='dialog'>
<xsl:for-each select='dialog/pict'>
<xsl:choose>
<xsl:when test='@type = "full"'>
<div>
<xsl:attribute name='class'>pict <xsl:value-of select='./@type'/></xsl:attribute>
<xsl:attribute name='style'>
background-image: url('other/<xsl:value-of select='./@num'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
width: <xsl:value-of select='./@width'/>px; height: <xsl:value-of select='./@height'/>px;
</xsl:attribute>
</div>
</xsl:when>
<xsl:when test='@type = "blank"'>
<div>
<xsl:attribute name='class'>pict <xsl:value-of select='./@type'/></xsl:attribute>
<xsl:attribute name='style'>
background-color: black;
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
</xsl:attribute>
</div>
</xsl:when>
<xsl:when test='@size = "large" and @type != "monst"'>
<div>
<xsl:attribute name='class'>pict large <xsl:value-of select='./@type'/></xsl:attribute>
<xsl:attribute name='style'>
background-image: url('<xsl:value-of select='./@type'/>/large<xsl:value-of select='./@num'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
</xsl:attribute>
</div>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:attribute name='class'>pict <xsl:value-of select='./@type'/></xsl:attribute>
<xsl:attribute name='style'>
background-image: url('<xsl:value-of select='./@type'/>/<xsl:value-of select='./@num'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
</xsl:attribute>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select='dialog/button'>
<div>
<xsl:attribute name='class'>
button <xsl:value-of select='./@type'/>
</xsl:attribute>
<xsl:attribute name='style'>
background-image: url('button/<xsl:value-of select='./@type'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
<xsl:if test='@type = "push"'>width: <xsl:value-of select='./@width'/>;</xsl:if>
</xsl:attribute>
<xsl:value-of select='.'/>
</div>
</xsl:for-each>
<xsl:for-each select='dialog/led'>
<div>
<xsl:attribute name='class'>
led
<xsl:if test='/dialog/@debug = "true"'>debug</xsl:if>
</xsl:attribute>
<xsl:attribute name='style'>
color: <xsl:value-of select='./@color'/>;
font-family:
<xsl:choose>
<xsl:when test='@font = "plain"'>Geneva</xsl:when>
<xsl:when test='@font = "bold"'>Silom</xsl:when>
<xsl:otherwise><xsl:value-of select='./@font'/></xsl:otherwise>
</xsl:choose>;
background-image: url('button/led-<xsl:value-of select='./@state'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
width: <xsl:value-of select='./@width'/>px;
</xsl:attribute>
<xsl:value-of select='.'/>
</div>
</xsl:for-each>
<xsl:for-each select='dialog/group/led'>
<div>
<xsl:attribute name='class'>
led
<xsl:if test='/dialog/@debug = "true"'>debug</xsl:if>
</xsl:attribute>
<xsl:attribute name='style'>
color: <xsl:value-of select='./@color'/>;
font-family:
<xsl:choose>
<xsl:when test='@font = "plain"'>Geneva</xsl:when>
<xsl:when test='@font = "bold"'>Silom</xsl:when>
<xsl:otherwise><xsl:value-of select='./@font'/></xsl:otherwise>
</xsl:choose>;
border-color: red;
background-image: url('button/led-<xsl:value-of select='./@state'/>.png');
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
width: <xsl:value-of select='./@width'/>px;
</xsl:attribute>
<xsl:value-of select='.'/>
</div>
</xsl:for-each>
<xsl:for-each select='dialog/text'>
<div>
<xsl:attribute name='class'>
text
<xsl:if test='@framed = "true"'>framed </xsl:if>
<xsl:if test='@size = "large"'>large </xsl:if>
<xsl:if test='/dialog/@debug = "true"'>debug</xsl:if>
</xsl:attribute>
<xsl:attribute name='style'>
color: <xsl:value-of select='./@color'/>;
font-family: <xsl:value-of select='./@font'/>;
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
width: <xsl:value-of select='./@width'/>px; height: <xsl:value-of select='./@height'/>px;
</xsl:attribute>
<xsl:value-of select='.'/>
</div>
</xsl:for-each>
<xsl:for-each select='dialog/field'>
<div class='field'>
<xsl:attribute name='style'>
left: <xsl:value-of select='./@left'/>px; top: <xsl:value-of select='./@top'/>px;
width: <xsl:value-of select='./@width'/>px; height: <xsl:value-of select='./@height'/>px;
</xsl:attribute>
<div class='field-inner'>
<xsl:attribute name='style'>
width: <xsl:value-of select='./@width'/>px; height: <xsl:value-of select='./@height'/>px;
font-family: Geneva;
font-size: 12px;
</xsl:attribute>
(<xsl:value-of select='@name'/>)
</div>
</div>
</xsl:for-each>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,14 @@
/*
* dlogutil.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#include <string>
using namespace std;
#include "dialog.h"
#include "dlogutil.h"

82
osx/dialogxml/dlogutil.h Normal file
View File

@@ -0,0 +1,82 @@
/*
* dlogutil.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef DIALOG_UTIL_H
#define DIALOG_UTIL_H
#include <string>
#include <vector>
typedef void (*record_callback_t)(std::string,std::string);
class cStrDlog {
cDialog dlg, *parent;
std::string str1, str2, title;
short sound;
record_callback_t rec_f;
bool onRecord(cDialog& me, std::string id);
bool onDismiss(cDialog& me, std::string id);
public:
cStrDlog(std::string str) : dlg("1str.xml") {}
cStrDlog(std::string str1, std::string str2, bool hasTitle) : dlg(hasTitle ? "1str-title.xml" : "2str.xml") {}
cStrDlog(std::string str1, std::string str2, std::string title) : dlg("2str-title.xml") {}
cStrDlog& setPict(short num, ePicType type);
cStrDlog& setSound(short num);
cStrDlog& setParent(cDialog* parent);
void show();
};
class cChoiceDlog {
cDialog dlg, *parent;
bool onClick(cDialog& me, std::string id);
public:
cChoiceDlog(std::string str) : dlg(str) {}
cChoiceDlog& setParent(cDialog* parent);
std::string show();
};
class cThreeChoice : public cChoiceDlog {
public:
cThreeChoice(std::string str) : cChoiceDlog("1str-3-c.xml") {}
cThreeChoice(std::string str1, std::string str2) : cChoiceDlog("2str-3-c.xml") {}
cThreeChoice(std::string str1, std::string str2, std::string str3) : cChoiceDlog("3str-3-c.xml") {}
cThreeChoice(std::string str1, std::string str2, std::string str3, std::string str4) : cChoiceDlog("4str-3-c.xml") {}
cThreeChoice(std::string str1, std::string str2, std::string str3, std::string str4, std::string str5) : cChoiceDlog("5str-3-c.xml") {}
cThreeChoice(std::string str1, std::string str2, std::string str3, std::string str4, std::string str5, std::string str6) : cChoiceDlog("6str-3-c.xml") {}
cThreeChoice& setPict(short num, ePicType type);
cThreeChoice& setParent(cDialog* parent);
string show();
};
class cStringChoice {
cDialog dlg, *parent;
bool onLeft(cDialog& me, std::string id);
bool onRight(cDialog& me, std::string id);
bool onCancel(cDialog& me, std::string id);
bool onOkay(cDialog& me, std::string id);
public:
cStringChoice(std::vector<std::string>& strs);
cStringChoice(std::vector<std::string>::iterator begin, std::vector<std::string>::iterator end);
size_t show(); // returns the _index_ of the chosen string
};
class cPictChoice {
cDialog dlg, *parent;
bool onLeft(cDialog& me, std::string id);
bool onRight(cDialog& me, std::string id);
bool onCancel(cDialog& me, std::string id);
bool onOkay(cDialog& me, std::string id);
public:
cPictChoice(std::vector<short>& pics, ePicType type);
cPictChoice(std::vector<short>::iterator begin, std::vector<short>::iterator end, ePicType type);
short show(); // returns the _number_ of the chosen picture, _not_ the index; there's no way to distinguish between duplicates
};
#endif
void giveError(std::string str1, std::string str2, short err, cDialog* parent = NULL);
void oopsError(short error,short code = 0, short mode = 0);

View File

@@ -0,0 +1,82 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<!DOCTYPE dialog SYSTEM "dialog.dtd">
<dialog skin='light' debug='true'>
<field name='name' top='30' left='186' height='16' width='186'/>
<field name='key' top='193' left='109' height='16' width='52' />
<field name='trans' top='193' left='467' height='16' width='52' />
<field name='pict' top='62' left='141' height='16' width='52' />
<field name='flag1' top='361' left='329' height='16' width='64' />
<field name='flag2' top='386' left='329' height='16' width='64' />
<field name='light' top='193' left='271' height='16' width='52' />
<button type='regular' key='enter' top='432' left='517'>OK</button>
<button type='regular' key='esc' top='432' left='451'>Cancel</button>
<button type='left' key='left' top='432' left='11'/>
<button type='right' key='right' top='432' left='74'/>
<text top='8' left='340' height='14' width='37'>*num</text>
<button type='large' top='59' left='205'>Pick Picture</button>
<pict type='ter' num='0' top='8' left='8'/>
<text size='large' top='6' left='50' height='17' width='138'>Edit Terrain Type</text>
<text top='8' left='222' height='14' width='111'>Terrain number:</text>
<text top='31' left='50' height='14' width='120'>Terrain type name:</text>
<text top='63' left='9' height='14' width='120'>Terrain picture:</text>
<text top='90' left='8' height='14' width='120'>Terrain blockage:</text>
<group>
<led top='90' left='132' state='off' width='120'>Clear</led>
<led top='107' left='132' state='off' width='120'>Walk through, opaque</led>
<led top='124' left='132' state='off' width='120'>Clear, special</led>
<led top='90' left='293' state='off' width='120'>Clear, blocked</led>
<led top='107' left='293' state='off' width='120'>Blocked, obstructed</led>
<led top='124' left='293' state='off' width='120'>Blocked, opaque</led>
</group>
<led top='150' left='26' state='off' width='120' font='bold'>Can fly over?</led>
<led top='150' left='154' state='off' width='120' font='bold'>Can boat over?</led>
<led top='150' left='307' state='off' width='120' font='bold'>Blocked to horses?</led>
<text top='165' left='8' height='14' width='91'>Step on sound:</text>
<group>
<led top='167' left='102' state='off' width='120'>Footstep</led>
<led top='167' left='182' state='off' width='120'>Squish</led>
<led top='167' left='282' state='off' width='120'>Crunch</led>
<led top='167' left='386' state='off' width='120'>Silence</led>
<led top='167' left='497' state='off' width='120'>Big Splash</led>
</group>
<text size='large' top='215' left='8' height='14' width='175'>Special properties:</text>
<group>
<led top='231' left='8' state='off' width='120'>None</led>
<led top='246' left='8' state='off' width='120'>Change when step on</led>
<led top='261' left='8' state='off' width='120'>Damaging terrain</led>
<led top='276' left='8' state='off' width='120'>Is a bridge</led>
<led top='291' left='8' state='off' width='120'>Change while occupied</led>
<led top='306' left='8' state='off' width='120'>Dangerous terrain</led>
<led top='321' left='8' state='off' width='120'>Reserved</led>
<led top='336' left='8' state='off' width='120'>Crumbling terrain</led>
<led top='231' left='146' state='off' width='120'>Lockable terrain</led>
<led top='246' left='146' state='off' width='120'>Unlockable terrain</led>
<led top='261' left='146' state='off' width='120'>Reserved</led>
<led top='276' left='146' state='off' width='120'>Is a sign</led>
<led top='291' left='146' state='off' width='120'>Call special when step</led>
<led top='306' left='146' state='off' width='120'>Reserved</led>
<led top='321' left='146' state='off' width='120'>Is a container</led>
<led top='336' left='146' state='off' width='120'>Waterfall</led>
<led top='231' left='285' state='off' width='120'>Conveyor belt</led>
<led top='246' left='285' state='off' width='120'>Reserved</led>
<led top='261' left='285' state='off' width='120'>Reserved</led>
<led top='276' left='285' state='off' width='120'>Reserved</led>
<led top='291' left='285' state='off' width='120'>Blocked to monsters</led>
<led top='306' left='285' state='off' width='120'>Town entrance</led>
<led top='321' left='285' state='off' width='120'>Change when used</led>
<led top='336' left='285' state='off' width='120'>Call special when used</led>
</group>
<text top='194' left='8' height='14' width='91'>Shortcut key:</text>
<text top='194' left='171' height='14' width='91'>Light radius:</text>
<text top='193' left='333' height='14' width='128'>Transform to what?</text>
<text top='362' left='9' height='14' width='91'>Extra values:</text>
<text framed='true' top='362' left='109' height='14' width='209'>*flag1</text>
<field name='flag1' top='361' left='329' height='16' width='64' />
<text framed='true' top='387' left='109' height='14' width='209'>*flag2</text>
<field name='flag2' top='386' left='329' height='16' width='64' />
<text framed='true' top='412' left='109' height='14' width='209'>*flag3</text>
<field name='flag3' top='411' left='329' height='16' width='64' />
<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 type='large' top='59' left='319'>Animated</button>
</dialog>

87
osx/dialogxml/field.cpp Normal file
View File

@@ -0,0 +1,87 @@
/*
* field.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#include <sstream>
#include "dialog.h"
void cTextField::attachClickHandler(click_callback_t f __attribute__((unused))) throw(xHandlerNotSupported){
throw xHandlerNotSupported(false);
}
void cTextField::attachFocusHandler(focus_callback_t f __attribute__((unused))) throw(){
onFocus = f;
}
bool cTextField::triggerFocusHandler(cDialog& me, std::string id, bool losingFocus){
// TODO: If isNumericField, verify that the contents are in fact a number.
if(onFocus != NULL) onFocus(me,id,losingFocus);
return true;
}
void cTextField::setFormat(eFormat prop, short val __attribute__((unused))) throw(xUnsupportedProp){
throw xUnsupportedProp(prop);
}
short cTextField::getFormat(eFormat prop) throw(xUnsupportedProp){
throw xUnsupportedProp(prop);
}
void cTextField::setText(std::string what){
char message[1024];
strcpy(message,what.c_str());
c2pstr(message);
OSErr err = SetControlData(theField,kControlEditTextPart,kControlEditTextTextTag,what.size() + 1,message);
if(isVisible()) draw();
}
std::string cTextField::getText(){
unsigned char message[1024];
OSErr err = GetControlData(theField,kControlEditTextPart,kControlEditTextTextTag,1024,message,NULL);
p2cstr(message);
return std::string((char*)message);
}
void cTextField::setTextToNum(short what){
std::ostringstream sout;
sout << what;
setText(sout.str());
}
short cTextField::getTextAsNum(){
std::istringstream sin(getText());
short n;
sin >> n;
return n;
}
bool cTextField::isClickable(){
return false;
}
cTextField::cTextField(cDialog* parent) : cControl(parent) {
OSStatus err;
err = CreateEditTextControl(parent->win,&frame,NULL,false,true/*useInlineInput*/,NULL,&theField);
}
cTextField::~cTextField(){
DisposeControl(theField);
}
void cTextField::show(){
ShowControl(theField);
cControl::show();
}
void cTextField::hide(){
HideControl(theField);
cControl::hide();
}
void cTextField::draw(){
Draw1Control(theField);
}

38
osx/dialogxml/field.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* field.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef FIELD_H
#define FIELD_H
#include <string>
class cTextField : public cControl {
public:
void attachClickHandler(click_callback_t f) throw(xHandlerNotSupported);
void attachFocusHandler(focus_callback_t f) throw();
bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
std::string getText();
void setText(std::string what);
short getTextAsNum();
void setTextToNum(short what);
cTextField(cDialog* parent);
bool isClickable();
virtual ~cTextField();
void show();
void hide();
protected:
void draw();
private:
friend class cDialog;
bool isNumericField;
focus_callback_t onFocus;
ControlRef theField;
};
#endif

140
osx/dialogxml/message.cpp Normal file
View File

@@ -0,0 +1,140 @@
/*
* message.cpp
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#include "graphtool.h"
#include "mathutil.h"
#include "dialog.h"
void cTextMsg::attachClickHandler(click_callback_t f) throw(){
onClick = f;
}
void cTextMsg::attachFocusHandler(focus_callback_t f __attribute__((unused))) throw(xHandlerNotSupported){
throw xHandlerNotSupported(true);
}
bool cTextMsg::triggerClickHandler(cDialog& me, std::string id, eKeyMod mods){
if(onClick != NULL) return onClick(me,id,mods);
return false;
}
void cTextMsg::setFormat(eFormat prop, short val) throw(xUnsupportedProp){
switch(prop){
case TXT_COLOR:
{ // TODO: Test this and see if it works as imagined
RGBColor clr;
unsigned char red, green, blue, bright;
red = (val & 0xF000) >> 12;
green = (val & 0x0F00) >> 8;
blue = (val & 0x00F0) >> 4;
bright = val & 0x000F;
red *= bright;
green *= bright;
blue *= bright;
clr.red = red * 257;
clr.green = green * 257;
clr.blue = blue * 257;
color = clr;
}
break;
case TXT_FRAME:
drawFramed = val;
break;
case TXT_SIZE:
textSize = val;
break;
case TXT_FONT:
if(val == DUNGEON) textFont = DUNGEON;
else if(val == GENEVA) textFont = GENEVA;
else if(val == MAIDENWORD) textFont = MAIDENWORD;
else textFont = SILOM; // Defaults to Silom if an invalid value is provided.
break;
case TXT_WRAP:
throw xUnsupportedProp(prop);
}
}
short cTextMsg::getFormat(eFormat prop) throw(xUnsupportedProp){
switch(prop){
case TXT_COLOR:
{
unsigned char red, green, blue, bright;
short val;
red = color.red / 257;
green = color.green / 257;
blue = color.green / 257;
bright = gcd(red,gcd(green,blue));
red /= bright;
green /= bright;
blue /= bright;
val |= bright;
val |= blue << 4;
val |= green << 8;
val |= red << 12;
return val;
}
case TXT_FRAME:
return drawFramed;
case TXT_SIZE:
return textSize;
case TXT_FONT:
return textFont;
case TXT_WRAP:
throw xUnsupportedProp(prop);
}
return 0;
}
std::string cTextMsg::getText(){
return getLabel();
}
void cTextMsg::setText(std::string what){
setLabel(what);
}
cTextMsg::cTextMsg(cDialog* parent) : cControl(parent) {}
bool cTextMsg::isClickable(){
return clickable;
}
void cTextMsg::draw(){
GrafPtr old_port;
Rect to_rect = frame;
GetPort(&old_port);
SetPortWindowPort(parent->win);
FillCRect(&frame,bg[parent->bg]);
if(visible){
TextFont(font_nums[textFont]);
if(textFont == SILOM && !foundSilom()) TextFace(bold);
else TextFace(normal);
TextSize(textSize);
if(drawFramed) drawFrame(2,0);
RGBColor draw_color = color;
if(clickable && depressed){
color.red = 65535 - color.red;
color.green = 65535 - color.green;
color.blue = 65535 - color.blue;
}
RGBForeColor(&draw_color);
if (to_rect.bottom - to_rect.top < 20) { // essentially, it's a single line
to_rect.left += 3;
char_win_draw_string(parent->win,to_rect,lbl.c_str(),3,12,false);
}else {
InsetRect(&to_rect,4,4);
char_win_draw_string(parent->win,to_rect,lbl.c_str(),0,textSize + 2,false);
}
}
SetPort(old_port);
}
cTextMsg::~cTextMsg() {}

37
osx/dialogxml/message.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* message.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef MESSAGE_H
#define MESSAGE_H
#include <string>
class cTextMsg : public cControl {
public:
void attachClickHandler(click_callback_t f) throw();
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
std::string getText();
void setText(std::string what);
cTextMsg(cDialog* parent);
bool isClickable();
virtual ~cTextMsg();
protected:
void draw();
private:
friend class cDialog;
bool drawFramed, clickable;
short textSize;
eTextFont textFont;
RGBColor color;
std::string fromList;
click_callback_t onClick;
};
#endif

1020
osx/dialogxml/pict.cpp Normal file

File diff suppressed because it is too large Load Diff

160
osx/dialogxml/pict.h Normal file
View File

@@ -0,0 +1,160 @@
/*
* pict.h
* BoE
*
* Created by Celtic Minstrel on 11/05/09.
*
*/
#ifndef PICT_H
#define PICT_H
#include <vector>
#include <map>
enum ePicType {
PIC_TER = 1, // 28x36 terrain graphic from the preset sheets
PIC_TER_ANIM = 2, // 28x36 terrain graphic from the preset animated terrain sheet
PIC_MONST = 3, // 28x36 monster graphic from the preset sheets
PIC_DLOG = 4, // 36x36 dialog graphic from the preset sheet
PIC_TALK = 5, // 32x32 talking portrait from the preset sheet
PIC_SCEN = 6, // 32x32 scenario graphic from the scenario sheet
PIC_ITEM = 7, // 28x36 item graphic from the large item sheet, or 18x18 item graphic from the small sheet centred in a 28x36 space
PIC_PC = 8, // 28x36 pc graphic from the player sheet
PIC_FIELD = 9, // 28x36 field graphic from the fields sheet
PIC_BOOM = 10, // 28x36 boom graphic from the booms sheet
PIC_FULL = 11, // entire sheet graphic; number is the resource ID
PIC_MISSILE = 12, // 18x18 missile graphic from the missiles sheet
PIC_DLOG_LG = 13, // 72x72 dialog graphic from the dialog sheet
PIC_SCEN_LG = 14, // 64x64 scenario graphic (currently each is on its own sheet)
PIC_TER_MAP = 15, // 12x12 map graphic... or should it be 6x6?
PIC_MONST_WIDE = 23, // 56x36 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
PIC_MONST_TALL = 43, // 28x72 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
PIC_MONST_LG = 63, // 56x72 monster graphic from the preset sheets, resized to fit in a 28x36 space
PIC_CUSTOM_TER = 101, // 28x36 custom graphic from the custom sheets
PIC_CUSTOM_TER_ANIM = 102,
PIC_CUSTOM_MONST = 103,
PIC_CUSTOM_DLOG = 104, // 36x36 dialog graphic drawn from two 18x26 halves in the custom sheets
PIC_CUSTOM_TALK = 105, // 32x32 talking portrait drawn from two 16x32 halves in the custom sheets
PIC_CUSTOM_SCEN = 106, // 32x32 scenario portrait loading from scenname.exr/scenario.png
PIC_CUSTOM_ITEM = 107,
PIC_CUSTOM_FULL = 111, // entire sheet graphic, drawn from scenname.exr/sheetxxx.png where xxx is the number
PIC_CUSTOM_MISSILE = 112, // 18x18 missile graphic drawn from the the custom sheets
PIC_CUSTOM_DLOG_LG = 113, // 72x72 dialog graphic from the custom sheet, taken from 8 successive slots
PIC_CUSTOM_TER_MAP = 115, // 12x12 map graphic (should it be 6x6?) taken from the custom sheet
PIC_CUSTOM_MONST_WIDE = 123, // 56x36 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
PIC_CUSTOM_MONST_TALL = 143, // 28x72 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
PIC_CUSTOM_MONST_LG = 163, // 56x72 monster graphic from the custom sheets, resized to fit in a 28x36 space
PIC_PARTY_MONST = 203, // 28x36 graphic drawn from the savegame sheet
PIC_PARTY_SCEN = 206, // 32x32 graphic drawn from the scenario headers sheet
PIC_PARTY_ITEM = 207,
PIC_PARTY_PC = 208,
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
};
enum ePicTypeMod {
// Can be added to or subtracted from ePicType enums, returning an ePicType.
PIC_PRESET = 0, // just for good measure
PIC_WIDE = 20, // if applied to any derivative of PIC_MONST, makes the x-dimension 2 instead of 1
PIC_TALL = 40, // if applied to any derivative of PIC_MONST, makes the y-dimension 2 instead of 1
PIC_CUSTOM = 100, // if applied to any customizable graphic, makes it custom instead of preset
PIC_PARTY = 200, // similar to above
};
enum eSheetType {
SHEET_TER,
SHEET_TER_ANIM,
SHEET_MONST,
SHEET_DLOG,
SHEET_TALK,
SHEET_SCEN,
SHEET_SCEN_LG,
SHEET_ITEM,
SHEET_TINY_ITEM,
SHEET_PC,
SHEET_FIELD,
SHEET_BOOM,
SHEET_MISSILE,
SHEET_PARTY,
SHEET_HEADER,
SHEET_TER_MAP,
SHEET_FULL,
SHEET_CUSTOM,
};
class cPict : public cControl {
public:
static void init();
void attachClickHandler(click_callback_t f) throw();
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
short getFormat(eFormat prop) throw(xUnsupportedProp);
static void setSheet(eSheetType type, short n, GWorldPtr sheet);
static bool isSheetSet(eSheetType type, size_t n);
void setPict(short num, ePicType type);
cPict(cDialog* parent);
bool isClickable();
static void advanceAnim();
virtual ~cPict();
protected:
void draw();
private:
static short animFrame;
short picNum;
ePicType picType;
bool clickable, drawFramed;
friend class cDialog;
static GWorldPtr teranim, dlog, talk, scen, largeScen, item, tinyItem, pc, field, boom, missile, save, header, map;
static std::vector<GWorldPtr> ter, monst, customSheets;
static std::map<size_t,GWorldPtr> largeSheets; // map instead of vector because it'll be a sparse array
static void drawPresetTer(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetTerAnim(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetMonstSm(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetMonstWide(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetMonstTall(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetMonstLg(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetDlog(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetDlogLg(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetTalk(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetScen(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetScenLg(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetItem(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetPc(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetField(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetBoom(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetMissile(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPresetTerMap(short num, GWorldPtr to_gw, Rect to_rect);
static void drawFullSheet(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomTer(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomTerAnim(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomMonstSm(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomMonstWide(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomMonstTall(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomMonstLg(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomDlog(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomDlogLg(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomTalk(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomItem(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomMissile(short num, GWorldPtr to_gw, Rect to_rect);
static void drawCustomTerMap(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyMonstSm(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyMonstWide(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyMonstTall(short num, GWorldPtr to_gw, Rect to_rect);
static void drawPartyMonstLg(short num, GWorldPtr to_gw, Rect to_rect);
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;
click_callback_t onClick;
};
ePicType operator + (ePicType lhs, ePicTypeMod rhs);
ePicType operator - (ePicType lhs, ePicTypeMod rhs);
ePicType operator + (ePicTypeMod lhs, ePicType rhs);
ePicType operator - (ePicTypeMod lhs, ePicType rhs);
ePicType&operator +=(ePicType&lhs, ePicTypeMod rhs);
ePicType&operator -=(ePicType&lhs, ePicTypeMod rhs);
#endif