add sprite / animation support
add support for returning to the spot where you left off in the lobby move meta information out of drawing name and off to the side
This commit is contained in:
parent
70529b610f
commit
19fe12a12a
372
whiteboard.py
372
whiteboard.py
|
@ -19,8 +19,6 @@ class Layer(TPrs):
|
|||
def SetName(self, st):
|
||||
self.stName = st
|
||||
|
||||
def Draw(self, ascr):
|
||||
ascr.PutAscr(self.ascr)
|
||||
def FSelectable(self):
|
||||
return True
|
||||
|
||||
|
@ -29,30 +27,38 @@ class Project(Ownable):
|
|||
Ownable.InitPersistent(self, owner)
|
||||
self.stName = stName
|
||||
self.user = user
|
||||
self.rgboard = []
|
||||
self.rgdrawing = []
|
||||
self.rgscript = []
|
||||
|
||||
def NewBoard(self, stName, user):
|
||||
board = Board(self, stName, user)
|
||||
self.rgboard.insert(0, board)
|
||||
self.rgdrawing.insert(0, board)
|
||||
return board
|
||||
def BoardTouched(self, board):
|
||||
if board != self.rgboard[0]:
|
||||
self.rgboard.remove(board)
|
||||
self.rgboard.insert(0, board)
|
||||
self.owner.BoardTouched(board)
|
||||
|
||||
def NewSprite(self, stName, user, w, h):
|
||||
sprite = Sprite(self, stName, user, w, h)
|
||||
self.rgdrawing.insert(0, sprite)
|
||||
return sprite
|
||||
|
||||
def DrawingTouched(self, drawing):
|
||||
if drawing != self.rgdrawing[0]:
|
||||
self.rgdrawing.remove(drawing)
|
||||
self.rgdrawing.insert(0, drawing)
|
||||
self.owner.DrawingTouched(drawing)
|
||||
def StName(self):
|
||||
return self.owner.StNameProject(self)
|
||||
def StLastModified(self):
|
||||
boardLast = None
|
||||
for board in self.rgboard:
|
||||
if boardLast == None or board.dtLastModified > boardLast.dtLastModified:
|
||||
boardLast = board
|
||||
if boardLast != None:
|
||||
return boardLast.StLastModified()
|
||||
drawingLast = None
|
||||
for drawing in self.rgdrawing:
|
||||
if drawingLast == None or drawing.dtLastModified > drawingLast.dtLastModified:
|
||||
drawingLast = drawing
|
||||
if drawingLast != None:
|
||||
return drawingLast.StLastModified()
|
||||
return "never"
|
||||
|
||||
@Version(3)
|
||||
class Board(Ownable):
|
||||
def RgstMetadata(self):
|
||||
return ["by " + self.user, "", "Last modified:", self.StLastModified()]
|
||||
|
||||
class Drawing(Ownable):
|
||||
def InitPersistent(self, owner, stName, user, rglayer=None, dtLastModified=None):
|
||||
Ownable.InitPersistent(self, owner)
|
||||
if rglayer == None:
|
||||
|
@ -65,9 +71,13 @@ class Board(Ownable):
|
|||
self.SetTimestamp()
|
||||
else:
|
||||
self.dtLastModified = dtLastModified
|
||||
|
||||
|
||||
def StName(self):
|
||||
return self.owner.owner.StNameBoard(self)
|
||||
return self.owner.owner.StNameDrawing(self)
|
||||
|
||||
def RgstMetadata(self):
|
||||
return [self.StType(), "by " + self.user, "", "Last modified", self.StLastModified()]
|
||||
|
||||
def StLastModified(self):
|
||||
return self.dtLastModified.strftime("%b %d, %Y at %I:%M%p")
|
||||
|
||||
|
@ -92,19 +102,23 @@ class Board(Ownable):
|
|||
self.rglayer.remove(layer)
|
||||
self.rglayer.insert(ilayer, layer)
|
||||
|
||||
def W(self): return config.W
|
||||
def H(self): return config.H
|
||||
|
||||
def Touch(self):
|
||||
self.SetTimestamp()
|
||||
self.owner.BoardTouched(self)
|
||||
self.owner.DrawingTouched(self)
|
||||
|
||||
def SetTimestamp(self):
|
||||
self.dtLastModified = datetime.now()
|
||||
|
||||
|
||||
@Version(3)
|
||||
class Board(Drawing):
|
||||
def StType(self):
|
||||
return "Board"
|
||||
def W(self): return config.W
|
||||
def H(self): return config.H
|
||||
|
||||
def draw(self, ascr):
|
||||
for layer in reversed(self.rglayer):
|
||||
layer.Draw(ascr)
|
||||
ascr.PutAscr(layer.ascr)
|
||||
|
||||
def Save(self):
|
||||
fn = config.DIR_ANSI + "/" + "_".join([str(x) for x in time.localtime()])
|
||||
|
@ -116,7 +130,7 @@ class Board(Ownable):
|
|||
fl.write("</center></body></html>")
|
||||
with open(fn + ".ans", "w") as fl:
|
||||
fl.write(ascr.Ast())
|
||||
|
||||
|
||||
def UpgradeFrom(self, versionOld):
|
||||
if versionOld < 2:
|
||||
gameWB = [gameWB for gameWB in self.owner.rggameWB if gameWB.rgtoken("whiteboard")[0].board == self][0]
|
||||
|
@ -125,6 +139,22 @@ class Board(Ownable):
|
|||
if versionOld < 3:
|
||||
self.chat = Chat()
|
||||
|
||||
class Sprite(Drawing):
|
||||
def InitPersistent(self, owner, stName, user, w, h):
|
||||
self.w = w
|
||||
self.h = h
|
||||
Drawing.InitPersistent(self, owner, stName, user, [Layer(ansi.Ascr(w, h), "Frame 1")])
|
||||
|
||||
def StType(self): return "Sprite"
|
||||
def W(self): return self.w
|
||||
def H(self): return self.h
|
||||
|
||||
def draw(self, ascr, x, y, iframe):
|
||||
ascr.PutAscr(self.rglayer[iframe].ascr, x, y)
|
||||
|
||||
def RgstMetadata(self):
|
||||
return [self.StType(), "by " + self.user, "", str(self.w) + "x" + str(self.h), str(len(self.rglayer)) + " frames", "", "Last modified", self.StLastModified()]
|
||||
|
||||
@Version(5)
|
||||
class Whiteboard(Token):
|
||||
def InitPersistent(self, game, board):
|
||||
|
@ -238,8 +268,15 @@ class Cursor(TokenClient):
|
|||
TokenClient.InitPersistent(self, game, client, "drawable", "cursor")
|
||||
self.fBlink = False
|
||||
self.cDontBlink = 0
|
||||
self.whiteboard = self.game.rgtoken("whiteboard")[0].board
|
||||
self.pos = ansi.Pos(self.whiteboard.W(), self.whiteboard.H())
|
||||
self.pos = ansi.Pos(self.game.drawing.W(), self.game.drawing.H())
|
||||
self.SetupMenus()
|
||||
self.SelectLayer(self.game.drawing.rglayer[0])
|
||||
self.CreateDrawingToken()
|
||||
|
||||
def CreateDrawingToken(self):
|
||||
WhiteboardDraw(self, self.client)
|
||||
|
||||
def SetupMenus(self):
|
||||
miFg = MiColour("Foreground", ansi.rgcolorFg, ansi.WHITE)
|
||||
miBg = MiColour("Background", ansi.rgcolorBg, ansi.BLACK)
|
||||
miChars = MiChars([[49, 50, 51, 52, 53, 54, 55, 56, 57, 48], #digits
|
||||
|
@ -259,21 +296,26 @@ class Cursor(TokenClient):
|
|||
[139, 140, 141, 161, 153, 148, 147, 149, 162, 32], #i, o
|
||||
[154, 129, 150, 151, 163, 32, 32, 32, 32, 32], #u
|
||||
], miFg, miBg)
|
||||
|
||||
miQuit = MiButton("Back to Menu", self.client.leaveGame)
|
||||
self.cf = MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save", self.Save), None, miQuit, None])
|
||||
self.miChat = MiMenu([None, MiChat(client, 13, self.whiteboard.chat), MiTypein(self.SendMsg), None, miQuit, None])
|
||||
self.rgmiLayer = RgmiProjected(self.whiteboard.rglayer, DgProjectMiButton(self.SelectLayer))
|
||||
self.miLayers = MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Layer", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown),
|
||||
None, MiToggle("Show One"), None, MiStatic("Rename selected layer:"), MiTypein(self.RenameLayer, "LayerName", 80), None, miQuit, None]))
|
||||
self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], ["Layers", self.miLayers], ["Chat", self.miChat]))
|
||||
self.cf = self.MenuDrawing(miFg, miBg, miChars, miQuit)
|
||||
self.miChat = MiMenu([None, MiChat(self.client, 13, self.game.drawing.chat), MiTypein(self.SendMsg), None, miQuit, None])
|
||||
self.rgmiLayer = RgmiProjected(self.game.drawing.rglayer, DgProjectMiButton(self.SelectLayer))
|
||||
self.miLayers = self.MenuLayers(miQuit)
|
||||
self.ovPopup = OvPopup(self, self.client, MiTab.MiTabbed(["Drawing", self.cf], [self.StLayerTab(), self.miLayers], ["Chat", self.miChat]))
|
||||
miStatus = MiMenuHoriz([MiStatic("Hit <Tab> for menu"), MiValue(miChars)])
|
||||
miStatus.ListenForNotice(self.miChat)
|
||||
self.ovStatus = OvStatic(self, self.client, miStatus, OvStatic.BOTTOM)
|
||||
|
||||
self.SelectLayer(self.whiteboard.rglayer[0])
|
||||
WhiteboardDraw(self, client)
|
||||
def MenuDrawing(self, miFg, miBg, miChars, miQuit):
|
||||
return MiMenu([None, miFg, miBg, None, miChars, None, MiButton("Save", self.Save), None, miQuit, None])
|
||||
|
||||
def MenuLayers(self, miQuit):
|
||||
return MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Layer", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown),
|
||||
None, MiToggle("Show One"), None, MiStatic("Rename selected layer:"), MiTypein(self.RenameLayer, "LayerName", 80), None, miQuit, None]))
|
||||
def StLayerTab(self): return "Layers"
|
||||
def Save(self):
|
||||
self.whiteboard.Save()
|
||||
self.game.drawing.Save()
|
||||
msgscroller = self.game.rgtoken("msgscroller")[0]
|
||||
msgscroller.evPost.fire("Saved picture")
|
||||
|
||||
|
@ -290,20 +332,20 @@ class Cursor(TokenClient):
|
|||
stLayer = None
|
||||
while stLayer == None:
|
||||
stLayer = "Layer " + str(ilayer)
|
||||
if self.whiteboard.LayerByName(stLayer) != None:
|
||||
if self.game.drawing.LayerByName(stLayer) != None:
|
||||
stLayer = None
|
||||
ilayer = ilayer + 1
|
||||
layerNew = self.whiteboard.NewLayer(stLayer)
|
||||
layerNew = self.game.drawing.NewLayer(stLayer)
|
||||
if layerNew != None:
|
||||
self.SelectLayer(layerNew)
|
||||
return True
|
||||
|
||||
def LayerUp(self):
|
||||
self.whiteboard.MoveLayer(self.GetLayer(), True)
|
||||
self.game.drawing.MoveLayer(self.GetLayer(), True)
|
||||
return True
|
||||
|
||||
def LayerDown(self):
|
||||
self.whiteboard.MoveLayer(self.GetLayer(), False)
|
||||
self.game.drawing.MoveLayer(self.GetLayer(), False)
|
||||
return True
|
||||
|
||||
def RenameLayer(self, st):
|
||||
|
@ -318,16 +360,16 @@ class Cursor(TokenClient):
|
|||
|
||||
def SendMsg(self, st):
|
||||
if st.lower().startswith("/me ") and len(st.rstrip()) > 3:
|
||||
self.whiteboard.chat.Add(ChlAct(self.client, st[4:]))
|
||||
self.game.drawing.chat.Add(ChlAct(self.client, st[4:]))
|
||||
else:
|
||||
self.whiteboard.chat.Add(ChlMsg(self.client, st))
|
||||
self.game.drawing.chat.Add(ChlMsg(self.client, st))
|
||||
|
||||
def OnChat(self, chl):
|
||||
if type(chl) != ChlSys:
|
||||
self.miChat.FlagNotice()
|
||||
|
||||
def run(self):
|
||||
with self.whiteboard.chat.evChat.oob(self, self.OnChat):
|
||||
with self.game.drawing.chat.evChat.oob(self, self.OnChat):
|
||||
while True:
|
||||
key = self.client.evKey.receive(self)
|
||||
fDontBlink = True
|
||||
|
@ -370,21 +412,21 @@ class Cursor(TokenClient):
|
|||
if fDontBlink:
|
||||
self.cDontBlink = 2 if self.fBlink else 1
|
||||
|
||||
if self.pos.Y() < self.whiteboard.H() / 2:
|
||||
if (self.game.drawing.H() < config.H) or (self.pos.Y() < self.game.drawing.H() / 2):
|
||||
self.ovStatus.kplace = OvStatic.BOTTOM
|
||||
else:
|
||||
self.ovStatus.kplace = OvStatic.TOP
|
||||
|
||||
def PutWb(self, ch):
|
||||
self.Put(ch, self.GetLayer().ascr)
|
||||
self.whiteboard.Touch()
|
||||
self.game.drawing.Touch()
|
||||
|
||||
def Put(self, ch, ascr):
|
||||
def Put(self, ch, ascr, xzOffset = 0, yzOffset = 0):
|
||||
if type(ch) == str:
|
||||
ach = ansi.MkAch(ch, self.cf.Value("Foreground"), self.cf.Value("Background"))
|
||||
else:
|
||||
ach = ch
|
||||
ascr.PutAch(ach, self.pos.X(), self.pos.Y())
|
||||
ascr.PutAch(ach, self.pos.X() + xzOffset, self.pos.Y() + yzOffset)
|
||||
|
||||
def GetAch(self):
|
||||
return self.GetLayer().ascr.GetAch(self.pos.X(), self.pos.Y())
|
||||
|
@ -397,17 +439,59 @@ class Cursor(TokenClient):
|
|||
while not fStop:
|
||||
fStop = not dgMove() or self.GetAch() != ach
|
||||
|
||||
def XzYzScreenPic(self):
|
||||
layer = self.GetLayer()
|
||||
return ((config.W - layer.ascr.W()) / 2, (config.H - layer.ascr.H()) / 2)
|
||||
|
||||
def FDrawCursor(self):
|
||||
return self.fBlink or self.cDontBlink > 0
|
||||
|
||||
def draw(self, ascr, client):
|
||||
if self.fBlink or self.cDontBlink > 0:
|
||||
if self.FDrawCursor():
|
||||
if client == self.client:
|
||||
chCursor = chr(176)
|
||||
ach = ascr.GetAch(self.pos.X(), self.pos.Y())
|
||||
if ach != None and ansi.ChFromAch(ach) == chCursor:
|
||||
chCursor = chr(177)
|
||||
self.Put(chCursor, ascr)
|
||||
self.Put(chCursor, ascr, *self.XzYzScreenPic())
|
||||
elif self.fBlink:
|
||||
self.Put(str(self.client.Cldg().iclient)[0], ascr)
|
||||
self.Put(str(self.client.Cldg().iclient)[0], ascr, *self.XzYzScreenPic())
|
||||
|
||||
class CursorSprite(Cursor):
|
||||
def InitPersistent(self, game, client):
|
||||
Cursor.InitPersistent(self, game, client)
|
||||
self.blinkerAnimate = None
|
||||
|
||||
def CreateDrawingToken(self):
|
||||
SpriteDraw(self, self.client)
|
||||
|
||||
def MenuDrawing(self, miFg, miBg, miChars, miQuit):
|
||||
return MiMenu([None, miFg, miBg, None, miChars, None, miQuit, None])
|
||||
|
||||
def MenuLayers(self, miQuit):
|
||||
return MiMenu(Rgseq([None], self.rgmiLayer, [None, MiButton("New Frame", self.NewLayer), MiButton("Move up", self.LayerUp), MiButton("Move down", self.LayerDown),
|
||||
None, MiStatic("Rename selected frame:"), MiTypein(self.RenameLayer, "LayerName", 80), None, MiButton("Animate", self.Animate), None, miQuit, None]))
|
||||
|
||||
def StLayerTab(self): return "Frames"
|
||||
def NewLayer(self):
|
||||
stLayer = "Frame " + str(len(self.game.drawing.rglayer) + 1)
|
||||
layerNew = self.game.drawing.NewLayer(stLayer)
|
||||
if layerNew != None:
|
||||
self.SelectLayer(layerNew)
|
||||
return True
|
||||
|
||||
def Animate(self):
|
||||
if (self.blinkerAnimate == None):
|
||||
self.blinkerAnimate = Blinker(self, self.SelectLayer, self.game.drawing.rglayer, interval = 300)
|
||||
self.ovPopup.SetSelection("animate", self.miLayers.MiByName("Animate"))
|
||||
else:
|
||||
self.blinkerAnimate.die()
|
||||
self.blinkerAnimate = None
|
||||
self.ovPopup.SetSelection("animate", None)
|
||||
def FDrawCursor(self):
|
||||
if self.blinkerAnimate:
|
||||
return False
|
||||
return Cursor.FDrawCursor(self)
|
||||
class WhiteboardDraw(TokenClient):
|
||||
def InitPersistent(self, owner, client):
|
||||
TokenClient.InitPersistent(self, owner, client, "drawable", "solid")
|
||||
|
@ -415,9 +499,31 @@ class WhiteboardDraw(TokenClient):
|
|||
def draw(self, ascr, client):
|
||||
if client == self.client:
|
||||
if self.owner.miLayers.Value("Show One"):
|
||||
self.owner.GetLayer().Draw(ascr)
|
||||
ascr.PutAscr(self.owner.GetLayer().ascr)
|
||||
else:
|
||||
self.owner.whiteboard.draw(ascr)
|
||||
self.game.drawing.draw(ascr)
|
||||
|
||||
class SpriteDraw(TokenClient):
|
||||
def InitPersistent(self, owner, client):
|
||||
TokenClient.InitPersistent(self, owner, client, "drawable", "solid")
|
||||
|
||||
def draw(self, ascr, client):
|
||||
if client == self.client:
|
||||
(xz, yz) = self.owner.XzYzScreenPic()
|
||||
x = xz + 1
|
||||
y = yz + 1
|
||||
layer = self.owner.GetLayer()
|
||||
ascr.PutAscr(layer.ascr, x, y)
|
||||
# draw border
|
||||
ascr.PutAch(ansi.MkAch(chr(218), ansi.WHITE | ansi.FBRIGHT), x - 1, y - 1) # top-left
|
||||
ascr.PutAch(ansi.MkAch(chr(191), ansi.WHITE | ansi.FBRIGHT), x + layer.ascr.W(), y - 1) # top-right
|
||||
ascr.PutAch(ansi.MkAch(chr(192), ansi.WHITE | ansi.FBRIGHT), x - 1, y + layer.ascr.H()) # bottom-left
|
||||
ascr.PutAch(ansi.MkAch(chr(217), ansi.WHITE | ansi.FBRIGHT), x + layer.ascr.W(), y + layer.ascr.H()) # bottom-right
|
||||
for yT in (y - 1, y + layer.ascr.H()):
|
||||
ascr.PutSt(chr(196) * layer.ascr.W(), x, yT, ansi.WHITE | ansi.FBRIGHT) # -
|
||||
for xT in (x - 1, x + layer.ascr.W()):
|
||||
for yT in xrange(y, y + layer.ascr.H()):
|
||||
ascr.PutAch(ansi.MkAch(chr(179), ansi.WHITE | ansi.FBRIGHT), xT, yT) # |
|
||||
|
||||
class CursorBlinker(Token):
|
||||
def InitPersistent(self, owner):
|
||||
|
@ -539,7 +645,7 @@ class Joiner(LeaveJoinToken):
|
|||
def InitPersistent(self, owner):
|
||||
Token.InitPersistent(self, owner)
|
||||
self.msgScroller = self.game.rgtoken("msgscroller")[0]
|
||||
self.board = self.game.rgtoken("whiteboard")[0].board
|
||||
self.board = self.game.drawing
|
||||
|
||||
def OnJoin(self, client):
|
||||
with client.Cldg().SetTransiently() as cldg:
|
||||
|
@ -559,7 +665,11 @@ class Joiner(LeaveJoinToken):
|
|||
class Lobby(TokenClient):
|
||||
def InitPersistent(self, owner, client):
|
||||
TokenClient.InitPersistent(self, owner, client)
|
||||
self.lobbyCurrent = LobbyProject(self, client)
|
||||
drawing = client.Cldg(self.game).drawingSelected
|
||||
if drawing == None:
|
||||
self.lobbyCurrent = LobbyProject(self, client)
|
||||
else:
|
||||
self.lobbyCurrent = LobbyBoard(self, client, drawing.owner, drawing)
|
||||
|
||||
def SwitchToLobby(self, lobbyNew):
|
||||
lobbyOld = self.lobbyCurrent
|
||||
|
@ -567,62 +677,88 @@ class Lobby(TokenClient):
|
|||
lobbyOld.die()
|
||||
|
||||
class LobbyI(TokenClient):
|
||||
def InitPersistent(self, owner, client, *rgmiListTop):
|
||||
def InitPersistent(self, owner, client, objSelected = None, *rgmiListTop):
|
||||
TokenClient.InitPersistent(self, owner, client)
|
||||
|
||||
rgmiList = RgmiProjected(self.RgObj(), DgProjectMiButton(self.OnObjSelected))
|
||||
if rgmiListTop != None:
|
||||
rgmiList = Rgseq(rgmiListTop, rgmiList)
|
||||
self.miDrawings = MiMenu(rgmiList)
|
||||
self.miCmds = MiMenu([None, None, MiTypein(self.NewI, "ObjectName"), MiButton(self.StNewObj(), self.NewI),
|
||||
None, None, None, None, None, None, None, None, MiStatic("Last modified:"), MiDgText(self.StLastModifiedI)])
|
||||
if objSelected:
|
||||
mi = self.miDrawings.MiByName(objSelected.StName())
|
||||
self.miDrawings.selMi.SetSelected(mi)
|
||||
self.miCmds = self.CreateMiCmds()
|
||||
OvMenu(self, client, MiMenuHoriz([self.miDrawings, self.miCmds], [65, 35]), OvMenu.FILL)
|
||||
|
||||
def StNewObj(self):
|
||||
"Text for the 'New X' text field"
|
||||
raise "not implemented"
|
||||
def RgObj(self):
|
||||
"Return the list of objects we are selecting from"
|
||||
raise "not implemented"
|
||||
|
||||
def OnObjSelected(self, obj):
|
||||
"Called when an object is selected by the user"
|
||||
raise "not implemented"
|
||||
def New(self, stName):
|
||||
"Create a new object with the given name"
|
||||
raise "not implemented"
|
||||
def StLastModified(self, obj):
|
||||
"Return a string stating when the object was last modified"
|
||||
|
||||
def RgstMetadata(self, obj):
|
||||
"Return a list of strings containing user-readable metadata about the object"
|
||||
raise "not implemented"
|
||||
|
||||
def StLastModifiedI(self):
|
||||
return self.StLastModified(self.miDrawings.Value())
|
||||
def NewI(self, stName = None):
|
||||
if stName == None:
|
||||
stName = self.miCmds.Value("ObjectName")
|
||||
if stName != "":
|
||||
self.New(stName)
|
||||
def StMetadata(self):
|
||||
try:
|
||||
return "\n".join(self.RgstMetadata(self.miDrawings.Value()))
|
||||
except:
|
||||
return ""
|
||||
|
||||
def MiTypein_MiButton(self, stBtnLabel, stMiTypein, dgOnSelect):
|
||||
def NewI(stName = None):
|
||||
if stName == None:
|
||||
stName = self.miCmds.Value(stMiTypein)
|
||||
if stName != "":
|
||||
dgOnSelect(stName)
|
||||
return (MiTypein(NewI, stMiTypein), MiButton(stBtnLabel, NewI))
|
||||
|
||||
class LobbyBoard(LobbyI):
|
||||
def InitPersistent(self, owner, client, project):
|
||||
def InitPersistent(self, owner, client, project, drawing = None):
|
||||
self.project = project
|
||||
LobbyI.InitPersistent(self, owner, client, MiButton("<-- Back to projects", self.Back), None)
|
||||
LobbyI.InitPersistent(self, owner, client, drawing, MiButton("<-- Back to projects", self.Back), None)
|
||||
|
||||
def CreateMiCmds(self):
|
||||
miTypeinBoard, miBtnNewBoard = self.MiTypein_MiButton("New Board", "BoardName", self.NewBoard)
|
||||
miTypeinSpr, miBtnNewSpr = self.MiTypein_MiButton("New Sprite", "SpriteName", self.NewSprite)
|
||||
miTypeinW = MiTypein(None, "w")
|
||||
miTypeinW.SetValue("1")
|
||||
miTypeinH = MiTypein(None, "h")
|
||||
miTypeinH.SetValue("1")
|
||||
self.miDimensions = MiMenuHoriz([MiStatic("W:"), miTypeinW, MiStatic("H:"), miTypeinH])
|
||||
|
||||
return MiMenu([None, None, miTypeinBoard, miBtnNewBoard, None, None, miTypeinSpr, self.miDimensions, miBtnNewSpr, None, None, None, None, None, MiDgText(self.StMetadata)])
|
||||
|
||||
def StNewObj(self):
|
||||
return "New Board"
|
||||
def RgObj(self):
|
||||
return self.project.rgboard
|
||||
return self.project.rgdrawing
|
||||
def OnObjSelected(self, board):
|
||||
self.client.leaveGame(board)
|
||||
def New(self, stName):
|
||||
def NewBoard(self, stName):
|
||||
self.OnObjSelected(self.project.NewBoard(stName, self.client.cld.user))
|
||||
def StLastModified(self, board):
|
||||
def NewSprite(self, stName):
|
||||
try:
|
||||
w = int(self.miDimensions.Value("w"))
|
||||
h = int(self.miDimensions.Value("h"))
|
||||
if 0 < w < config.W and 0 < h < config.H:
|
||||
self.OnObjSelected(self.project.NewSprite(stName, self.client.cld.user, w, h))
|
||||
except:
|
||||
pass
|
||||
def RgstMetadata(self, board):
|
||||
if board != None:
|
||||
return board.StLastModified()
|
||||
return self.project.StLastModified()
|
||||
return board.RgstMetadata()
|
||||
return self.project.RgstMetadata()
|
||||
|
||||
def Back(self):
|
||||
self.owner.SwitchToLobby(LobbyProject(self.owner, self.client))
|
||||
self.owner.SwitchToLobby(LobbyProject(self.owner, self.client, self.project))
|
||||
|
||||
class LobbyProject(LobbyI):
|
||||
def CreateMiCmds(self):
|
||||
miTypein, miBtnNew = self.MiTypein_MiButton("New Project", "ProjName", self.New)
|
||||
return MiMenu([None, None, miTypein, miBtnNew, None, None, None, None, None, None, None, None, MiDgText(self.StMetadata)])
|
||||
|
||||
def StNewObj(self):
|
||||
return "New Project"
|
||||
def RgObj(self):
|
||||
|
@ -632,8 +768,8 @@ class LobbyProject(LobbyI):
|
|||
def New(self, stName):
|
||||
project = self.game.NewProject(stName, self.client.cld.user)
|
||||
self.OnObjSelected(project)
|
||||
def StLastModified(self, project):
|
||||
return project.StLastModified()
|
||||
def RgstMetadata(self, project):
|
||||
return project.RgstMetadata()
|
||||
|
||||
class RunnerWB(Runner):
|
||||
def InitPersistent(self):
|
||||
|
@ -642,9 +778,11 @@ class RunnerWB(Runner):
|
|||
|
||||
def RunGame(self, client):
|
||||
if (client.joinGame(GameLogin())):
|
||||
client.Cldg(self.gameLobby).drawingSelected = None
|
||||
while True:
|
||||
board = client.joinGame(self.gameLobby)
|
||||
client.joinGame(self.gameLobby.GameFromBoard(board))
|
||||
drawing = client.joinGame(self.gameLobby)
|
||||
client.Cldg(self.gameLobby).drawingSelected = drawing
|
||||
client.joinGame(self.gameLobby.GameFromDrawing(drawing))
|
||||
|
||||
class GameLogin(Game):
|
||||
def GetRgclsTokTrans(self):
|
||||
|
@ -658,39 +796,44 @@ class GameLobby(Game):
|
|||
|
||||
def InitTransient(self):
|
||||
Game.InitTransient(self)
|
||||
self.mpboard_gameWB = {}
|
||||
self.mpdrawing_game = {}
|
||||
|
||||
def GetRgclsTokTrans(self):
|
||||
return [[AutoJoiner, Lobby]]
|
||||
|
||||
def GameFromBoard(self, board):
|
||||
if not (board in self.mpboard_gameWB):
|
||||
gameWB = GameWB(self, board)
|
||||
def GameFromDrawing(self, drawing):
|
||||
if not (drawing in self.mpdrawing_game):
|
||||
if drawing.StType() == "Board":
|
||||
game = GameWB(self, drawing)
|
||||
elif drawing.StType() == "Sprite":
|
||||
game = GameSprEdit(self, drawing)
|
||||
else:
|
||||
assert False, "Lobby not prepared to deal with drawing of type " + drawing.StType()
|
||||
def KillBoard():
|
||||
del self.mpboard_gameWB[board]
|
||||
gameWB.rgdgdie.append(KillBoard)
|
||||
self.mpboard_gameWB[board] = gameWB
|
||||
return gameWB
|
||||
return self.mpboard_gameWB[board]
|
||||
del self.mpdrawing_game[drawing]
|
||||
game.rgdgdie.append(KillBoard)
|
||||
self.mpdrawing_game[drawing] = game
|
||||
return game
|
||||
return self.mpdrawing_game[drawing]
|
||||
|
||||
def CclientBoard(self, board):
|
||||
if board in self.mpboard_gameWB:
|
||||
return len(self.mpboard_gameWB[board].rgclient)
|
||||
def CclientDrawing(self, drawing):
|
||||
if drawing in self.mpdrawing_game:
|
||||
return len(self.mpdrawing_game[drawing].rgclient)
|
||||
return 0
|
||||
|
||||
def StNameProject(self, project):
|
||||
return project.stName + " (by " + project.user + ") [" + str(sum([self.CclientBoard(board) for board in project.rgboard])) + "]"
|
||||
return project.stName + " [" + str(sum([self.CclientDrawing(drawing) for drawing in project.rgdrawing])) + "]"
|
||||
|
||||
def StNameBoard(self, board):
|
||||
return board.stName + " (by " + board.user + ") [" + str(self.CclientBoard(board)) + "]"
|
||||
def StNameDrawing(self, drawing):
|
||||
return drawing.stName + " [" + str(self.CclientDrawing(drawing)) + "]"
|
||||
|
||||
def NewProject(self, stName, user):
|
||||
proj = Project(self, stName, user)
|
||||
self.rgproject.insert(0, proj)
|
||||
return proj
|
||||
|
||||
def BoardTouched(self, board):
|
||||
project = board.owner
|
||||
def DrawingTouched(self, drawing):
|
||||
project = drawing.owner
|
||||
if project != self.rgproject[0]:
|
||||
self.rgproject.remove(project)
|
||||
self.rgproject.insert(0, project)
|
||||
|
@ -711,30 +854,35 @@ class GameLobby(Game):
|
|||
project = Project(self, "Drawings", "Willy Marmot")
|
||||
for board in self.rgboard:
|
||||
board.TransferToOwner(project)
|
||||
project.rgboard.append(board)
|
||||
project.rgdrawing.append(board)
|
||||
del self.rgboard
|
||||
self.rgproject = [project]
|
||||
self.mpuser_cldg = {} # ugh, upgrading parent classes is broken in our model :(
|
||||
|
||||
class GameWB(Game):
|
||||
def InitPersistent(self, gameLobby, board):
|
||||
self.gameLobby = gameLobby
|
||||
self.board = board
|
||||
self.drawing = board
|
||||
Game.InitPersistent(self)
|
||||
|
||||
def InitTransient(self):
|
||||
Game.InitTransient(self)
|
||||
if not self.FDead():
|
||||
self.board.chat.AttachToGame(self)
|
||||
self.rgdgdie.append(self.board.chat.DetachFromGame)
|
||||
self.drawing.chat.AttachToGame(self)
|
||||
self.rgdgdie.append(self.drawing.chat.DetachFromGame)
|
||||
|
||||
def GetRgclsTokPers(self):
|
||||
return [[Whiteboard, self.board]]
|
||||
def ClsCursor(self):
|
||||
return Cursor
|
||||
|
||||
def GetRgclsTokTrans(self):
|
||||
return [MsgScroller, Joiner, [AutoJoiner, Cursor], [AliveWithPlayers, CursorBlinker], AutoKiller]
|
||||
return [MsgScroller, Joiner, [AutoJoiner, self.ClsCursor()], [AliveWithPlayers, CursorBlinker], AutoKiller]
|
||||
|
||||
def GetRgtagDraw(self):
|
||||
return ["background", "solid", "cursor", "menu", "msgscroller"]
|
||||
|
||||
class GameSprEdit(GameWB):
|
||||
def ClsCursor(self):
|
||||
return CursorSprite
|
||||
|
||||
if __name__ == "__main__":
|
||||
Run(RunnerWB, "whiteboard.marm")
|
||||
|
|
Loading…
Reference in a new issue