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): def Eval(self, env):
env.GlobalMsg(self.expr.Eval(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): class Fail(TPrs):
""" """
Failure object. Our scripting language has no exceptions; instead, if a failure object is involved in a calculation, 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 tpers import TPrs, Partial
from scripting import Vm from scripting import Vm
from basetoken import AutoJoiner, AutoKiller, MsgScroller, Mi, MiButton, MiTypein, MiMenu, OvPopup 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 util import RgstWrapped
from engine import Game, Token, TokenClient, Event from engine import Game, Token, TokenClient, Event
from datetime import datetime from datetime import datetime
@ -212,9 +212,6 @@ class Joiner(LeaveJoinToken):
self.msgScroller.evPost.fire(client.cld.user + " has left! :(") self.msgScroller.evPost.fire(client.cld.user + " has left! :(")
self.game.Chat().Add(ChlSys(client, "has left")) self.game.Chat().Add(ChlSys(client, "has left"))
## TODO:
## - fix lobby numbering (clients either editing or playing a game)
class Player(TokenClient): class Player(TokenClient):
def InitPersistent(self, owner, client): def InitPersistent(self, owner, client):
TokenClient.InitPersistent(self, owner, client, "drawable", "player") TokenClient.InitPersistent(self, owner, client, "drawable", "player")
@ -224,6 +221,8 @@ class Player(TokenClient):
miQuit = MiButton("Leave Game", self.client.leaveGame) 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.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.ovPopup = OvPopup(self, self.client, self.mi)
self.ovDialog = None
self.evDialogDismiss = Event(self.game)
def die(self): def die(self):
self.vm.RemovePlayer(self.rbot) self.vm.RemovePlayer(self.rbot)
@ -264,8 +263,27 @@ class Player(TokenClient):
def GlobalMsg(self, stMsg): def GlobalMsg(self, stMsg):
self.game.rgtoken("msgscroller")[0].evPost.fire(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): class GameWorld(Game):
def InitPersistent(self, board): def InitPersistent(self, board):
Game.InitPersistent(self) Game.InitPersistent(self)