Implement dialogs

This commit is contained in:
Jeremy Penner 2020-08-02 16:00:16 -04:00
parent 33663ba093
commit d8baf72cf6
2 changed files with 66 additions and 5 deletions

View file

@ -489,6 +489,49 @@ class SyntPrint(SyntDesc):
def Eval(self, env):
env.GlobalMsg(self.expr.Eval(env))
class SyntDialogBlock(SyntBlock):
def StypeForChild(self, syntChild):
return StypeDialogElement()
def Eval(self, env):
rgmi = []
for synt in self.rgsynt:
rgmiChild = synt.Eval(env)
if rgmiChild != None:
rgmi += rgmiChild
else:
rgmi.append(None)
return rgmi
class SyntDialogIf(SyntIf):
desc = [["If"], " ", RtypeFlag(), " is ", (StypeFlagTest(), SyntIsFlagSet), ", then:", SyntDialogBlock, "or else:", SyntDialogBlock]
class SyntDialogText(SyntDesc):
desc = [["Text"], ": \"", SyntText, "\""]
text = SyntDesc.DefProp(0)
def StButtonText(self, env):
return self.text.Eval(env)
def Eval(self, env):
return [MiDgText(Partial(self.StButtonText, env))]
class SyntDialogOption(SyntDesc):
desc = [["Option"], " \"", SyntText, "\" is selected:", SyntBlock]
text = SyntDesc.DefProp(0)
exprOnSelect = SyntDesc.DefProp(1)
def Eval(self, env):
return [MiButton(self.text.Eval(env), Partial(env.OnDialogOptionSelected, self.exprOnSelect))]
class StypeDialogElement(StypeEnum):
rgclsSynt = [SyntDialogText, SyntDialogOption, SyntDialogIf]
@RegStmt
class SyntDialog(SyntDesc):
desc = [["Show dialog"], ":", SyntDialogBlock]
dialog = SyntDesc.DefProp(0)
def Eval(self, env):
rgmi = self.dialog.Eval(env)
env.ShowDialog(MiMenu([None] + rgmi + [None]))
class Fail(TPrs):
"""
Failure object. Our scripting language has no exceptions; instead, if a failure object is involved in a calculation,

View file

@ -17,7 +17,7 @@ import ansi_cython as ansi
from tpers import TPrs, Partial
from scripting import Vm
from basetoken import AutoJoiner, AutoKiller, MsgScroller, Mi, MiButton, MiTypein, MiMenu, OvPopup
from basetoken import LeaveJoinToken, Selor
from basetoken import LeaveJoinToken, Selor, OvMenu
from util import RgstWrapped
from engine import Game, Token, TokenClient, Event
from datetime import datetime
@ -212,9 +212,6 @@ class Joiner(LeaveJoinToken):
self.msgScroller.evPost.fire(client.cld.user + " has left! :(")
self.game.Chat().Add(ChlSys(client, "has left"))
## TODO:
## - fix lobby numbering (clients either editing or playing a game)
class Player(TokenClient):
def InitPersistent(self, owner, client):
TokenClient.InitPersistent(self, owner, client, "drawable", "player")
@ -224,6 +221,8 @@ class Player(TokenClient):
miQuit = MiButton("Leave Game", self.client.leaveGame)
self.mi = MiMenu([None, MiChat(self.client, 13, chat), MiTypein(Partial(chat.SendMsg, self.client)), None, miQuit, None])
self.ovPopup = OvPopup(self, self.client, self.mi)
self.ovDialog = None
self.evDialogDismiss = Event(self.game)
def die(self):
self.vm.RemovePlayer(self.rbot)
@ -264,7 +263,26 @@ class Player(TokenClient):
def GlobalMsg(self, stMsg):
self.game.rgtoken("msgscroller")[0].evPost.fire(stMsg)
# idea: synchronous event pair to implement "show message" w/ blocking
def OnDialogOptionSelected(self, synt):
self.evDialogDismiss.fire(synt)
return True
def DismissDialog(self):
if self.ovDialog:
self.ovDialog.die()
self.ovDialog = None
def ShowDialog(self, mi):
self.DismissDialog()
self.ovDialog = OvMenu(self, self.client, mi, OvMenu.MIDDLE)
while self.ovDialog:
ev, val = Event.select(self, self.evDialogDismiss, self.EvKey())
if ev == self.evDialogDismiss:
self.DismissDialog()
val.Eval(self)
break
elif val == ansi.K_TAB:
self.DismissDialog()
class GameWorld(Game):
def InitPersistent(self, board):