From 5dfa0d7b92dc64a7e48bd31358298a2213a4f0cd Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 23 Feb 2017 05:30:15 +0800 Subject: [PATCH] add preliminary dialog system, add ability to specify window icon, add ability to pagejump to previous loaded page. --- DOCS/overview.txt | 2 +- DZU-ENG1.py | 130 ++++++++++++++++++++++++++++++++++++++++++++-- ENGSYSTEM.xml | 18 ++++++- README.md | 2 +- about.xml | 2 +- icon.png | Bin 0 -> 2100 bytes test0.xml | 32 ++++++++++++ test1.xml | 6 +++ 8 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 icon.png diff --git a/DOCS/overview.txt b/DOCS/overview.txt index cf04ccc..e488a31 100644 --- a/DOCS/overview.txt +++ b/DOCS/overview.txt @@ -1,6 +1,6 @@ Desutezeoid Technical Documentation. Overview: -Desutezeoid v1.2.0 +Desutezeoid v1.2.1 (c) 2015-2017 Thomas Leathers diff --git a/DZU-ENG1.py b/DZU-ENG1.py index cc46567..a5731d7 100755 --- a/DZU-ENG1.py +++ b/DZU-ENG1.py @@ -13,11 +13,24 @@ pygame.display.init() pygame.font.init() pygame.mixer.init() -print "Desutezeoid arbitrary point and click engine v1.2.0" +print "Desutezeoid arbitrary point and click engine v1.2.1" print "parsing ENGSYSTEM.xml" conftree = ET.parse("ENGSYSTEM.xml") confroot = conftree.getroot() screentag=confroot.find("screen") +uitag=confroot.find("ui") +uicolorstag=uitag.find("main") +uifgcolor=pygame.Color(uicolorstag.attrib.get("FGCOLOR", "#000000")) +uibgcolor=pygame.Color(uicolorstag.attrib.get("BGCOLOR", "#FFFFFF")) +uifgcolorstr=uicolorstag.attrib.get("FGCOLOR", "#000000") +uibgcolorstr=uicolorstag.attrib.get("BGCOLOR", "#FFFFFF") +uitextsize=int(uicolorstag.attrib.get("textsize", "24")) + +uiquittag=uitag.find("quit") +uiquitmsg=uiquittag.attrib.get("MSG", "Are you sure you want to quit?") + + + print "populate keylist with null keyid, add any keys in initkeys." initkeystag=confroot.find("initkeys") keylist=list(["0"]) @@ -38,10 +51,15 @@ globalcoretag=confroot.find("globalcore") globalforkstag=confroot.find("globalforks") +icontag=titletag.attrib.get("icon", "NULL") +if icontag!="NULL": + windowicon=pygame.image.load(icontag) + pygame.display.set_icon(windowicon) + print "config parsed." titlebase=titletag.attrib.get("base", "Desutezeoid: ") class clicktab: - def __init__(self, box, reftype, ref, keyid, takekey, sfxclick, sound): + def __init__(self, box, reftype, ref, keyid, takekey, sfxclick, sound, quitab=0): self.box=box self.ref=ref self.keyid=keyid @@ -49,6 +67,7 @@ def __init__(self, box, reftype, ref, keyid, takekey, sfxclick, sound): self.reftype=reftype self.sfxclick=sfxclick self.sound=sound + self.quitab=quitab class timeouttab: def __init__(self, seconds, keyid, postkey): self.keyid=keyid @@ -56,6 +75,8 @@ def __init__(self, seconds, keyid, postkey): self.seconds=seconds self.postkey=postkey + + #class keyobj: # def __init__(self, keyid): # self=keyid @@ -73,12 +94,64 @@ def keyprint(): screensurf=pygame.display.set_mode((scrnx, scrny)) quitflag=0 clicklist=list() +#simple dialog popup generator. used by uipop forks and the engine quit dialogs. +def qpop(qmsg, xpos, ypos, keyid="0", nokey="0", quyn=0, specialquit=0, fgcol=uifgcolor, bgcol=uibgcolor, uipoptextsize=uitextsize): + qfnt=pygame.font.SysFont(None, uipoptextsize) + + qtext1=qfnt.render(qmsg, True, fgcol, bgcol) + xpos=((xpos - int(qtext1.get_width() / 2)) - 3) + qboxwidth=(6 + (qtext1.get_width())) + qboxhight=(uipoptextsize + uipoptextsize + 20) + if qboxwidth<100: + qboxwidth=100 + qbox=pygame.Surface((qboxwidth, qboxhight)) + qbox.fill((bgcol)) + boxtrace=screensurf.blit(qbox, (xpos, ypos)) + screensurf.blit(qtext1, ((xpos + 3), (ypos + 3))) + pygame.draw.rect(screensurf, fgcol, boxtrace, 3) + if quyn==1: + qytext=qfnt.render("Yes", True, bgcol, fgcol) + qntext=qfnt.render("No", True, bgcol, fgcol) + yesclick=screensurf.blit(qytext, ((xpos + 10), (ypos + 10 + uipoptextsize))) + noclick=screensurf.blit(qntext, ((xpos + 50), (ypos + 10 + uipoptextsize))) + ref="none" + takekey="0" + clicksoundflg=0 + soundname=0 + if specialquit==1: + yesdat=clicktab(yesclick, "quitx", ref, keyid, takekey, clicksoundflg, soundname) + nodat=clicktab(noclick, "key", ref, nokey, takekey, clicksoundflg, soundname, quitab=1) + else: + yesdat=clicktab(yesclick, "key", ref, keyid, takekey, clicksoundflg, soundname, quitab=2) + nodat=clicktab(noclick, "key", ref, nokey, takekey, clicksoundflg, soundname, quitab=2) + retclicks=([]) + retclicks.extend([yesdat]) + retclicks.extend([nodat]) + + return(retclicks, quyn) + else: + qytext=qfnt.render("Ok", True, bgcol, fgcol) + yesclick=screensurf.blit(qytext, ((xpos + 10), (ypos + 10 + uipoptextsize))) + ref="none" + takekey="0" + clicksoundflg=0 + soundname=0 + yesdat=clicktab(yesclick, "key", ref, keyid, takekey, clicksoundflg, soundname, quitab=2) + retclicks=([]) + retclicks.extend([yesdat]) + return(retclicks, quyn) + + + timeoutlist=list() keybak=list(keylist) forksanitycheck=0 forksanity=0 +cachepage=prevpage print "done. begin mainloop." +uiquit=0 +qpopflg=0 while quitflag==0: huris=0 clicklist=list() @@ -90,6 +163,7 @@ def keyprint(): tree = ET.parse(curpage) root = tree.getroot() + cachepage=prevpage prevpage=curpage coretag=root.find('core') forktag=root.find('forks') @@ -206,10 +280,37 @@ def keyprint(): masterkey=fork.attrib.get("keyid") if masterkey in keylist: keylist.remove(masterkey) + useprvpge=int(fork.attrib.get('useprev', '0')) curpage=fork.attrib.get("page") - print ("iref: loading page '" + f.ref + "'") + if useprvpge==1 and cachepage!="NULL": + curpage=cachepage + + + print ("iref: loading page '" + curpage + "'") pagejumpflag=1 break + for fork in forktag.findall("uipop"): + masterkey=fork.attrib.get("keyid") + msg=fork.attrib.get("msg") + qpopx=int(fork.attrib.get("x",(screensurf.get_rect().centerx))) + qpopy=int(fork.attrib.get("y",(screensurf.get_rect().centery))) + FGCOL=pygame.Color(fork.attrib.get("FGCOLOR", uifgcolorstr)) + BGCOL=pygame.Color(fork.attrib.get("BGCOLOR", uibgcolorstr)) + QFNTSIZE=int(fork.attrib.get("textsize", uitextsize)) + if masterkey in keylist: + keylist.remove(masterkey) + ynflag=int(fork.attrib.get("ynflag", "0")) + if ynflag==1: + yeskey=fork.attrib.get("yeskey", "0") + nokey=fork.attrib.get("nokey", "0") + #poppost=qpop(msg, qpopx, qpopy, keyid=yeskey, nokey=nokey, quyn=1) + qpopdat=(msg, qpopx, qpopy, yeskey, nokey, 1, FGCOL, BGCOL, QFNTSIZE) + qpopflg=1 + else: + okkey=fork.attrib.get("okkey", "0") + #poppost=qpop(msg, qpopx, qpopy, keyid=okkey, quyn=0) + qpopdat=(msg, qpopx, qpopy, okkey, "0", 0, FGCOL, BGCOL, QFNTSIZE) + qpopflg=1 for fork in forktag.findall("timeout"): masterkey=fork.attrib.get("keyid") if masterkey in keylist: @@ -446,6 +547,17 @@ def keyprint(): clicklist.extend([datstr]) #else: #time.sleep(0.04) + if uiquit==1: + quitxpos=screensurf.get_rect().centerx + quitypos=screensurf.get_rect().centery + poppost=qpop(uiquitmsg, quitxpos, quitypos, quyn=1, specialquit=1) + clicklist=(poppost[0]) + + if qpopflg==1: + poppost=qpop(qpopdat[0], qpopdat[1], qpopdat[2], keyid=(qpopdat[3]), nokey=(qpopdat[4]), quyn=(qpopdat[5]), fgcol=(qpopdat[6]), bgcol=(qpopdat[7]), uipoptextsize=(qpopdat[8])) + clicklist=(poppost[0]) + + if clickfields==1: for f in clicklist: pygame.draw.rect(screensurf, cfcolor, f.box, 1) @@ -454,8 +566,7 @@ def keyprint(): #print "nominal" eventhappen=1 if event.type == QUIT: - quitflag=1 - print ("quit: OS or WM quit") + uiquit=1 break if event.type==MOUSEBUTTONDOWN: #print "nominal2" @@ -475,14 +586,23 @@ def keyprint(): keylist.remove(f.takekey) #print keylist keyprint() + + if f.reftype=="iref": curpage=f.ref print ("iref: loading page '" + f.ref + "'") break if f.reftype=="quit": + uiquit=1 + break + if f.reftype=="quitx": print ("quit: onclick quit") quitflag=1 break + if f.quitab==1: + uiquit=0 + if f.quitab==2: + qpopflg=0 if eventhappen==0: time.sleep(0.1) diff --git a/ENGSYSTEM.xml b/ENGSYSTEM.xml index 61f593b..48aee9e 100644 --- a/ENGSYSTEM.xml +++ b/ENGSYSTEM.xml @@ -2,14 +2,20 @@ - - + <!--Game/program Title/windown icon.--> + <title base="Desutezeoid v1.2.1 test program. " icon="icon.png" /> <!--page to load at engine start.--> <beginref>test0.xml</beginref> <!--debug settings. used in development and testing. printkeys controls keyid list printing. clickfields uses cfcolor to show outlines around each click field. useful for debugging.--> <debug debug="1" printkeys="1" clickfields="0" cfcolor="#FFFF00"/> + <!--settings for desutezeoid's internal User Interface.--> + <ui> + <main BGCOLOR="#BBCFE6" FGCOLOR="#000000" textsize="24"/> + <quit MSG="Are you sure you want to quit?"/> + </ui> <!--keyids loaded into the keyid enviornment at startup.--> + <initkeys> <k keyid="timeloop1"/> <k keyid="testkey1"/> @@ -24,6 +30,9 @@ <timeout keyid="timeloop1" seconds="0.5" post="timeloop2"/> <timeout keyid="timeloop2" seconds="0.5" post="timeloop3"/> <timeout keyid="timeloop3" seconds="0.5" post="timeloop1"/> + <!--The useprev attribute causes a jump to the previous page loaded.--> + <pagejump keyid="pagejumptestB" useprev="1" page="test0.xml"/> + </globalforks> <!--these core objects are present on each page--> <globalcore> @@ -40,5 +49,10 @@ <con>Home</con> <act type="iref" ref="test0.xml"/> </label> + <label x="120" y="580" size="20" BGCOLOR="#008800" keyid="pagejumptestB" FGCOLOR="#FFFFFF" > + <con>Prev</con> + <act type="key"/> + </label> + </globalcore> </conf> \ No newline at end of file diff --git a/README.md b/README.md index cc2b144..633f602 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Desutezeoid -v1.2.0 +v1.2.1 an arbitrary point and click engine. (c) 2015-2017 Thomas Leathers diff --git a/about.xml b/about.xml index fc0ab0c..dffbb8d 100644 --- a/about.xml +++ b/about.xml @@ -13,7 +13,7 @@ <act type="none"/> </label> <!--notice how the "text" object has similar attributes to the label tag, but lacking click and hover related, attribues. It still has onkey and offkey though. do note this can take longer to process than other core objects.--> - <text x="10" y="30" size="20" transp="1" FGCOLOR="#000000">v1.2.0 + <text x="10" y="30" size="20" transp="1" FGCOLOR="#000000">v1.2.1 an arbitrary point and click engine. (c) 2015-2017 Thomas Leathers diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..43f585c8e012e87fa87d92d21fb0d2362fffe670 GIT binary patch literal 2100 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 literal 0 HcmV?d00001 diff --git a/test0.xml b/test0.xml index 693b9f4..c48e769 100644 --- a/test0.xml +++ b/test0.xml @@ -22,6 +22,19 @@ <k if="1" keyid="switch1"/> <k if="1" keyid="switch2"/> </ortrig> + <!--These generate normal and yes/no dialogs respectively. both modes have appropiate selection + keyid attributes. to use yes/no mode, set ynflag="1", and use yesflag and noflag for respective + "post" keyids, in normal mode, use the "okkey" attribute. these use the internal engine ui + parameters, you can specifiy ui parameters like colors and text size in the "ui" section of ENGSYSTEM.xml + + Special note: only one uipop dialog can be active at any one time!--> + <uipop keyid="uidialog1" msg="Hello, this is a normal dialog." okkey="normaldialogok"/> + <!--now lets use some custom visual parameters! :D--> + <uipop keyid="uidialog3" msg="This Dialog is red." BGCOLOR="#AA0000" FGCOLOR="#FFFFFF" /> + <!--HUGE text :) --> + <uipop keyid="uidialog4" msg="This Dialog is BIG." BGCOLOR="#00AA00" FGCOLOR="#FFFFFF" textsize="70" /> + <!--yes/no dialog--> + <uipop keyid="uidialog2" msg="Hello, this is a yes or no dialog." ynflag="1" nokey="nokeyyndiag" yeskey="yeskeyyndiag" /> <!--notice how this trigger lock triggers a sound event. note how the lock keyid prevents the trigger keyid from re-triggering, thus the sound triggered by the two toggle switches being on plays only once, and only the @@ -88,6 +101,25 @@ The timeout instance is also removed after the specified time lapses. also if th <con>timer (click me!)</con> <act type="key" ref="test1.xml"/> </label> + + <label x="0" y="400" size="24" BGCOLOR="#000088" FGCOLOR="#FFFFFF" keyid="uidialog1"> + <con>test normal dialog</con> + <act type="key" ref="test1.xml"/> + </label> + <label x="0" y="455" size="24" BGCOLOR="#000088" FGCOLOR="#FFFFFF" keyid="uidialog3"> + <con>test colorized dialog</con> + <act type="key" ref="test1.xml"/> + </label> + <label x="0" y="475" size="24" BGCOLOR="#000088" FGCOLOR="#FFFFFF" keyid="uidialog4"> + <con>test custom text size dialog</con> + <act type="key" ref="test1.xml"/> + </label> + + <label x="0" y="430" size="24" BGCOLOR="#000088" FGCOLOR="#FFFFFF" keyid="uidialog2"> + <con>test yes/no dialog</con> + <act type="key" ref="test1.xml"/> + </label> + <!--take note how these toggle switches work. see how, in each toggle switch, the "keyid" and "offkey" atributes in the "(off)" labels and the "takekey" and "onkey" in the "(on)" labels all have the same keyid. diff --git a/test1.xml b/test1.xml index ff6bb74..c9ee6cc 100644 --- a/test1.xml +++ b/test1.xml @@ -11,6 +11,8 @@ such as in a page that acts as a story sequence for example, you would have the last timeout in the sequence trigger one of these.--> <pagejump keyid="pagejumptest" page="test0.xml"/> + <pagejump keyid="pagejumptestB" useprev="1" page="test0.xml"/> + </forks> <core> <label x="0" y="400" size="40"> @@ -25,6 +27,10 @@ last timeout in the sequence trigger one of these.--> <con>test pagejump.</con> <act type="key"/> </label> + <label x="0" y="340" size="24" keyid="pagejumptestB"> + <con>test pagejump prevpage feature</con> + <act type="key"/> + </label> <label x="0" y="300" size="24" onkey="pagejumpdelay"> <con>starting booster rockets...</con> <act type="none"/>