2020-06-28 18:20:31 +00:00
|
|
|
#!/usr/bin/env python2
|
|
|
|
|
2020-06-28 15:27:56 +00:00
|
|
|
# This file is part of MarMOTS.
|
|
|
|
#
|
|
|
|
# MarMOTS is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
|
|
|
|
# General Public License as published by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# MarMOTS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
|
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
|
|
|
|
# Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License along with MarMOTS. If not,
|
|
|
|
# see <https://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
# Copyright 2009, 2010, 2011, 2020 Jeremy Penner
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
from engine import *
|
|
|
|
from basetoken import *
|
|
|
|
from tpers import *
|
|
|
|
from datetime import *
|
|
|
|
from util import *
|
|
|
|
import telnet
|
|
|
|
import time
|
|
|
|
import login
|
|
|
|
import weakref
|
2020-06-28 14:32:13 +00:00
|
|
|
import sys
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
class Layer(TPrs):
|
|
|
|
def InitPersistent(self, ascr, stName):
|
|
|
|
self.ascr = ascr
|
|
|
|
self.stName = stName
|
|
|
|
|
|
|
|
def StName(self):
|
|
|
|
return self.stName
|
|
|
|
|
|
|
|
def SetName(self, st):
|
|
|
|
self.stName = st
|
|
|
|
|
|
|
|
def FSelectable(self):
|
|
|
|
return True
|
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
class Project(Ownable):
|
|
|
|
def InitPersistent(self, owner, stName, user):
|
|
|
|
Ownable.InitPersistent(self, owner)
|
|
|
|
self.stName = stName
|
|
|
|
self.user = user
|
2011-10-05 21:50:18 +00:00
|
|
|
self.rgdrawing = []
|
2011-09-14 22:30:44 +00:00
|
|
|
self.rgscript = []
|
2011-10-05 21:50:18 +00:00
|
|
|
|
2011-09-16 12:57:31 +00:00
|
|
|
def NewBoard(self, stName, user):
|
|
|
|
board = Board(self, stName, user)
|
2011-10-05 21:50:18 +00:00
|
|
|
self.rgdrawing.insert(0, board)
|
2011-09-16 12:57:31 +00:00
|
|
|
return board
|
2011-10-05 21:50:18 +00:00
|
|
|
|
|
|
|
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)
|
2011-09-14 22:30:44 +00:00
|
|
|
def StName(self):
|
|
|
|
return self.owner.StNameProject(self)
|
|
|
|
def StLastModified(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
drawingLast = None
|
|
|
|
for drawing in self.rgdrawing:
|
|
|
|
if drawingLast == None or drawing.dtLastModified > drawingLast.dtLastModified:
|
|
|
|
drawingLast = drawing
|
|
|
|
if drawingLast != None:
|
|
|
|
return drawingLast.StLastModified()
|
2011-09-14 22:30:44 +00:00
|
|
|
return "never"
|
2011-10-05 21:50:18 +00:00
|
|
|
def RgstMetadata(self):
|
|
|
|
return ["by " + self.user, "", "Last modified:", self.StLastModified()]
|
|
|
|
|
|
|
|
class Drawing(Ownable):
|
2011-03-19 00:10:02 +00:00
|
|
|
def InitPersistent(self, owner, stName, user, rglayer=None, dtLastModified=None):
|
|
|
|
Ownable.InitPersistent(self, owner)
|
|
|
|
if rglayer == None:
|
|
|
|
rglayer = [Layer(ansi.Ascr(self.W(), self.H()), "Layer 1")]
|
|
|
|
self.rglayer = rglayer
|
|
|
|
self.stName = stName
|
|
|
|
self.user = user
|
|
|
|
self.chat = Chat()
|
|
|
|
if dtLastModified == None:
|
|
|
|
self.SetTimestamp()
|
|
|
|
else:
|
|
|
|
self.dtLastModified = dtLastModified
|
2011-10-05 21:50:18 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def StName(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
return self.owner.owner.StNameDrawing(self)
|
|
|
|
|
|
|
|
def RgstMetadata(self):
|
|
|
|
return [self.StType(), "by " + self.user, "", "Last modified", self.StLastModified()]
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def StLastModified(self):
|
|
|
|
return self.dtLastModified.strftime("%b %d, %Y at %I:%M%p")
|
|
|
|
|
|
|
|
def LayerByName(self, stName):
|
|
|
|
for layer in self.rglayer:
|
|
|
|
if layer.StName().lower() == stName.lower():
|
|
|
|
return layer
|
|
|
|
return None
|
|
|
|
|
2011-10-06 12:41:21 +00:00
|
|
|
def NewLayer(self, stName, ascr = None):
|
2011-03-19 00:10:02 +00:00
|
|
|
if len(self.rglayer) < 8:
|
2011-10-06 12:41:21 +00:00
|
|
|
if ascr == None:
|
|
|
|
ascr = ansi.Ascr(self.W(), self.H())
|
|
|
|
layerNew = Layer(ascr, stName)
|
2011-03-19 00:10:02 +00:00
|
|
|
self.rglayer.append(layerNew)
|
|
|
|
return layerNew
|
|
|
|
|
|
|
|
def MoveLayer(self, layer, fUp):
|
|
|
|
ilayer = self.rglayer.index(layer)
|
|
|
|
if fUp and ilayer > 0:
|
|
|
|
ilayer = ilayer - 1
|
|
|
|
elif not fUp and ilayer < len(self.rglayer) - 1:
|
|
|
|
ilayer = ilayer + 1
|
|
|
|
self.rglayer.remove(layer)
|
|
|
|
self.rglayer.insert(ilayer, layer)
|
|
|
|
|
|
|
|
def Touch(self):
|
|
|
|
self.SetTimestamp()
|
2011-10-05 21:50:18 +00:00
|
|
|
self.owner.DrawingTouched(self)
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def SetTimestamp(self):
|
|
|
|
self.dtLastModified = datetime.now()
|
2011-10-05 21:50:18 +00:00
|
|
|
|
|
|
|
@Version(3)
|
|
|
|
class Board(Drawing):
|
|
|
|
def StType(self):
|
|
|
|
return "Board"
|
|
|
|
def W(self): return config.W
|
|
|
|
def H(self): return config.H
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def draw(self, ascr):
|
|
|
|
for layer in reversed(self.rglayer):
|
2011-10-05 21:50:18 +00:00
|
|
|
ascr.PutAscr(layer.ascr)
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def Save(self):
|
|
|
|
fn = config.DIR_ANSI + "/" + "_".join([str(x) for x in time.localtime()])
|
|
|
|
ascr = ansi.Ascr(self.W(), self.H())
|
|
|
|
self.draw(ascr)
|
|
|
|
with open(fn + ".html", "w") as fl:
|
|
|
|
fl.write("<html><body bgcolor='#000000'><center>")
|
|
|
|
fl.write(ascr.Hst())
|
|
|
|
fl.write("</center></body></html>")
|
|
|
|
with open(fn + ".ans", "w") as fl:
|
|
|
|
fl.write(ascr.Ast())
|
2011-10-05 21:50:18 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def UpgradeFrom(self, versionOld):
|
|
|
|
if versionOld < 2:
|
|
|
|
gameWB = [gameWB for gameWB in self.owner.rggameWB if gameWB.rgtoken("whiteboard")[0].board == self][0]
|
|
|
|
self.stName = gameWB.stName
|
|
|
|
self.user = gameWB.user
|
|
|
|
if versionOld < 3:
|
|
|
|
self.chat = Chat()
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
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()]
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
@Version(5)
|
|
|
|
class Whiteboard(Token):
|
|
|
|
def InitPersistent(self, game, board):
|
|
|
|
Token.InitPersistent(self, game, "whiteboard")
|
|
|
|
self.board = board
|
|
|
|
|
|
|
|
def UpgradeFrom(self, versionOld):
|
|
|
|
if versionOld < 3:
|
|
|
|
dt = None
|
|
|
|
else:
|
|
|
|
dt = self.dtLastModified
|
|
|
|
del self.dtLastModified
|
|
|
|
if versionOld < 4:
|
|
|
|
rglayer = [Layer(self.ascr, "Layer 1")]
|
|
|
|
del self.ascr
|
|
|
|
self.untag("drawable")
|
|
|
|
self.untag("solid")
|
|
|
|
else:
|
|
|
|
rglayer = self.rglayer
|
|
|
|
del self.rglayer
|
|
|
|
if versionOld < 5:
|
|
|
|
self.board = Board(self.game.gameLobby, self.game.stName, self.game.user, rglayer, dt)
|
2011-09-14 22:30:44 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class Chl(object):
|
|
|
|
def __init__(self, client, st):
|
|
|
|
self.user = client.cld.user
|
|
|
|
self.st = st.rstrip()
|
|
|
|
|
|
|
|
class ChlMsg(Chl):
|
|
|
|
def StUser(self):
|
|
|
|
return "<" + self.user + ">"
|
|
|
|
def Col(self):
|
|
|
|
return ansi.WHITE
|
|
|
|
|
|
|
|
class ChlAct(Chl):
|
|
|
|
def StUser(self):
|
|
|
|
return "* " + self.user
|
|
|
|
def Col(self):
|
|
|
|
return ansi.MAGENTA
|
|
|
|
|
|
|
|
class ChlSys(Chl):
|
|
|
|
def StUser(self):
|
|
|
|
return self.user
|
|
|
|
def Col(self):
|
|
|
|
return ansi.BLUE
|
|
|
|
|
|
|
|
class Chat(TPrs):
|
|
|
|
def InitTransient(self):
|
|
|
|
TPrs.InitTransient(self)
|
|
|
|
self.cchl = 100
|
|
|
|
self.DetachFromGame()
|
|
|
|
|
|
|
|
def InitPersistent(self):
|
|
|
|
TPrs.InitPersistent(self)
|
|
|
|
self.rgchl = []
|
|
|
|
|
|
|
|
def AttachToGame(self, game):
|
|
|
|
self.game = game
|
|
|
|
self.evChat = Event(game)
|
|
|
|
|
|
|
|
def DetachFromGame(self):
|
|
|
|
self.game = None
|
|
|
|
self.evChat = None
|
|
|
|
|
|
|
|
def Add(self, chl):
|
|
|
|
if len(chl.st) > 0:
|
|
|
|
self.rgchl.insert(0, chl)
|
|
|
|
if len(self.rgchl) > self.cchl:
|
|
|
|
self.rgchl = self.rgchl[:self.cchl]
|
|
|
|
self.evChat.fire(chl)
|
|
|
|
|
|
|
|
def CChl(self):
|
|
|
|
return len(self.rgchl)
|
|
|
|
def CUsers(self):
|
|
|
|
return len(self.game.rgclient)
|
|
|
|
def DrawMsg(self, ascr, x, y, w, h, colBg=ansi.BLACK, ichl=0):
|
|
|
|
yDraw = y + h - 1
|
|
|
|
for chl in self.rgchl[ichl:]:
|
|
|
|
stUser = chl.StUser()
|
|
|
|
colFg = chl.Col()
|
|
|
|
wMsg = w - len(stUser) - 1
|
|
|
|
rgstMsg = RgstWrapped(chl.st, wMsg)
|
|
|
|
|
|
|
|
rgstMsg.reverse()
|
|
|
|
for istMsg, stMsg in enumerate(rgstMsg):
|
|
|
|
if istMsg == len(rgstMsg) - 1:
|
|
|
|
st = "{0} {1:{2}}".format(stUser, stMsg, wMsg)
|
|
|
|
else:
|
|
|
|
st = "{0:{1}} {2:{3}}".format("", len(stUser), stMsg, wMsg)
|
|
|
|
ascr.PutSt(st, x, yDraw, colFg, colBg)
|
|
|
|
yDraw = yDraw - 1
|
|
|
|
if yDraw == y - 1:
|
|
|
|
return
|
|
|
|
while yDraw >= y:
|
|
|
|
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
|
|
|
yDraw = yDraw - 1
|
|
|
|
|
|
|
|
def DrawUsers(self, ascr, x, y, w, h, colBg=ansi.BLACK, iuser=0):
|
|
|
|
yDraw = y
|
|
|
|
for client in sorted(self.game.rgclient, lambda c1, c2: cmp(c1.Cldg().iclient, c2.Cldg().iclient))[iuser:]:
|
|
|
|
ascr.PutSt("{0:{1}}".format(str(client.Cldg().iclient) + ") " + client.cld.user, w), x, yDraw, ansi.WHITE, colBg)
|
|
|
|
yDraw = yDraw + 1
|
|
|
|
if yDraw == y + h:
|
|
|
|
break
|
|
|
|
while yDraw < y + h:
|
|
|
|
ascr.PutSt("{0:{1}}".format("", w), x, yDraw, ansi.WHITE, colBg)
|
|
|
|
yDraw = yDraw + 1
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class Cursor(TokenClient):
|
|
|
|
def InitPersistent(self, game, client):
|
|
|
|
TokenClient.InitPersistent(self, game, client, "drawable", "cursor")
|
|
|
|
self.fBlink = False
|
|
|
|
self.cDontBlink = 0
|
2011-10-05 21:50:18 +00:00
|
|
|
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):
|
2011-03-19 00:10:02 +00:00
|
|
|
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
|
|
|
|
[176, 177, 178, 219, 223, 220, 221, 222, 254, 249], #blocks
|
|
|
|
[218, 191, 192, 217, 196, 179, 195, 180, 193, 194], #single lines
|
|
|
|
[201, 187, 200, 188, 205, 186, 204, 185, 202, 203], #double lines
|
|
|
|
[213, 184, 212, 190, 205, 179, 198, 181, 207, 209], #sing vert, doub horiz
|
|
|
|
[214, 183, 211, 189, 196, 186, 199, 182, 208, 210], #doub vert, sing horiz
|
|
|
|
[197, 206, 216, 215, 173, 168, 169, 170, 174, 175], #crosses
|
2011-09-30 12:47:41 +00:00
|
|
|
[ 1, 2, 3, 4, 5, 6, 14, 15, 19, 20], #smiles
|
2011-03-19 00:10:02 +00:00
|
|
|
[224, 225, 226, 227, 228, 229, 230, 231, 232, 233], #greek
|
|
|
|
[234, 235, 236, 237, 238, 239, 240, 241, 242, 243], #crap
|
|
|
|
[244, 245, 246, 247, 248, 249, 251, 252, 253, 167], #more crap
|
|
|
|
[155, 156, 157, 158, 159, 171, 172, 166, 32, 32], #$
|
|
|
|
[142, 132, 131, 143, 134, 133, 160, 145, 146, 32], #a
|
|
|
|
[128, 135, 137, 136, 138, 144, 130, 164, 165, 32], #c, e, n
|
|
|
|
[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)
|
2011-10-05 21:50:18 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
miQuit = MiButton("Back to Menu", self.client.leaveGame)
|
2011-10-05 21:50:18 +00:00
|
|
|
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]))
|
2011-03-19 00:10:02 +00:00
|
|
|
miStatus = MiMenuHoriz([MiStatic("Hit <Tab> for menu"), MiValue(miChars)])
|
|
|
|
miStatus.ListenForNotice(self.miChat)
|
|
|
|
self.ovStatus = OvStatic(self, self.client, miStatus, OvStatic.BOTTOM)
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
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"
|
2011-03-19 00:10:02 +00:00
|
|
|
def Save(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.Save()
|
2011-03-19 00:10:02 +00:00
|
|
|
msgscroller = self.game.rgtoken("msgscroller")[0]
|
|
|
|
msgscroller.evPost.fire("Saved picture")
|
|
|
|
|
|
|
|
def SelectLayer(self, layer):
|
|
|
|
self.ovPopup.SetSelection("layer", self.rgmiLayer.MiFromValue(layer))
|
|
|
|
miRename = self.miLayers.MiByName("LayerName").SetValue(layer.StName())
|
|
|
|
return True
|
|
|
|
|
|
|
|
def GetLayer(self):
|
|
|
|
return self.ovPopup.GetSelection("layer").Value()
|
|
|
|
|
|
|
|
def NewLayer(self):
|
|
|
|
ilayer = 1
|
|
|
|
stLayer = None
|
|
|
|
while stLayer == None:
|
|
|
|
stLayer = "Layer " + str(ilayer)
|
2011-10-05 21:50:18 +00:00
|
|
|
if self.game.drawing.LayerByName(stLayer) != None:
|
2011-03-19 00:10:02 +00:00
|
|
|
stLayer = None
|
|
|
|
ilayer = ilayer + 1
|
2011-10-05 21:50:18 +00:00
|
|
|
layerNew = self.game.drawing.NewLayer(stLayer)
|
2011-03-19 00:10:02 +00:00
|
|
|
if layerNew != None:
|
|
|
|
self.SelectLayer(layerNew)
|
|
|
|
return True
|
|
|
|
|
|
|
|
def LayerUp(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.MoveLayer(self.GetLayer(), True)
|
2011-03-19 00:10:02 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
def LayerDown(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.MoveLayer(self.GetLayer(), False)
|
2011-03-19 00:10:02 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
def RenameLayer(self, st):
|
|
|
|
if st != "":
|
|
|
|
self.GetLayer().SetName(st)
|
|
|
|
return True
|
|
|
|
|
|
|
|
def blinkCursor(self, fBlink):
|
|
|
|
self.fBlink = fBlink
|
|
|
|
if not fBlink and self.cDontBlink > 0:
|
|
|
|
self.cDontBlink = self.cDontBlink - 1
|
|
|
|
|
|
|
|
def SendMsg(self, st):
|
|
|
|
if st.lower().startswith("/me ") and len(st.rstrip()) > 3:
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.chat.Add(ChlAct(self.client, st[4:]))
|
2011-03-19 00:10:02 +00:00
|
|
|
else:
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.chat.Add(ChlMsg(self.client, st))
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def OnChat(self, chl):
|
|
|
|
if type(chl) != ChlSys:
|
|
|
|
self.miChat.FlagNotice()
|
|
|
|
|
|
|
|
def run(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
with self.game.drawing.chat.evChat.oob(self, self.OnChat):
|
2011-03-19 00:10:02 +00:00
|
|
|
while True:
|
|
|
|
key = self.client.evKey.receive(self)
|
|
|
|
fDontBlink = True
|
|
|
|
if key == ansi.K_LEFT:
|
|
|
|
self.pos.Left()
|
|
|
|
elif key == ansi.K_RIGHT:
|
|
|
|
self.pos.Right()
|
|
|
|
elif key == ansi.K_UP:
|
|
|
|
self.pos.Up()
|
|
|
|
elif key == ansi.K_DOWN:
|
|
|
|
self.pos.Down()
|
|
|
|
elif key == ansi.K_BACKSPACE:
|
|
|
|
self.pos.Left()
|
|
|
|
self.PutWb(ansi.achBlank)
|
|
|
|
elif key == ansi.K_DEL:
|
|
|
|
self.PutWb(ansi.achBlank)
|
|
|
|
self.pos.Right()
|
|
|
|
elif key == ansi.K_TAB:
|
|
|
|
fDontBlink = False
|
|
|
|
self.ovPopup.evShow.fire()
|
|
|
|
self.ovPopup.evDone.receive(self)
|
|
|
|
elif key == ansi.K_HOME:
|
|
|
|
self.Skip(self.pos.Left)
|
|
|
|
elif key == ansi.K_END:
|
|
|
|
self.Skip(self.pos.Right)
|
|
|
|
elif key == ansi.K_PGUP:
|
|
|
|
self.Skip(self.pos.Up)
|
|
|
|
elif key == ansi.K_PGDN:
|
|
|
|
self.Skip(self.pos.Down)
|
|
|
|
elif ansi.FKeyPrintable(key):
|
|
|
|
if key.isdigit():
|
|
|
|
self.PutWb(chr(self.cf.Value("Characters")[IchFromCh(key)]))
|
|
|
|
else:
|
|
|
|
self.PutWb(key)
|
|
|
|
self.pos.Right()
|
|
|
|
else:
|
|
|
|
print "weird key:", ansi.StrKey(key)
|
|
|
|
fDontBlink = False
|
|
|
|
|
|
|
|
if fDontBlink:
|
|
|
|
self.cDontBlink = 2 if self.fBlink else 1
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
if (self.game.drawing.H() < config.H) or (self.pos.Y() < self.game.drawing.H() / 2):
|
2011-03-19 00:10:02 +00:00
|
|
|
self.ovStatus.kplace = OvStatic.BOTTOM
|
|
|
|
else:
|
|
|
|
self.ovStatus.kplace = OvStatic.TOP
|
|
|
|
|
|
|
|
def PutWb(self, ch):
|
|
|
|
self.Put(ch, self.GetLayer().ascr)
|
2011-10-05 21:50:18 +00:00
|
|
|
self.game.drawing.Touch()
|
2011-03-19 00:10:02 +00:00
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def Put(self, ch, ascr, xzOffset = 0, yzOffset = 0):
|
2011-03-19 00:10:02 +00:00
|
|
|
if type(ch) == str:
|
|
|
|
ach = ansi.MkAch(ch, self.cf.Value("Foreground"), self.cf.Value("Background"))
|
|
|
|
else:
|
|
|
|
ach = ch
|
2011-10-05 21:50:18 +00:00
|
|
|
ascr.PutAch(ach, self.pos.X() + xzOffset, self.pos.Y() + yzOffset)
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def GetAch(self):
|
|
|
|
return self.GetLayer().ascr.GetAch(self.pos.X(), self.pos.Y())
|
|
|
|
|
|
|
|
def Skip(self, dgMove):
|
|
|
|
self.SkipI(dgMove, self.GetAch())
|
|
|
|
|
|
|
|
def SkipI(self, dgMove, ach):
|
|
|
|
fStop = False
|
|
|
|
while not fStop:
|
|
|
|
fStop = not dgMove() or self.GetAch() != ach
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
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
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
def draw(self, ascr, client):
|
2011-10-05 21:50:18 +00:00
|
|
|
if self.FDrawCursor():
|
2011-03-19 00:10:02 +00:00
|
|
|
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)
|
2011-10-05 21:50:18 +00:00
|
|
|
self.Put(chCursor, ascr, *self.XzYzScreenPic())
|
2011-03-19 00:10:02 +00:00
|
|
|
elif self.fBlink:
|
2011-10-05 21:50:18 +00:00
|
|
|
self.Put(str(self.client.Cldg().iclient)[0], ascr, *self.XzYzScreenPic())
|
2011-03-19 00:10:02 +00:00
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
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)
|
2011-10-06 12:41:21 +00:00
|
|
|
layer = self.GetLayer()
|
|
|
|
ascr = ansi.Ascr(self.game.drawing.W(), self.game.drawing.H())
|
|
|
|
ascr.PutAscr(layer.ascr)
|
|
|
|
layerNew = self.game.drawing.NewLayer(stLayer, ascr)
|
2011-10-05 21:50:18 +00:00
|
|
|
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)
|
2011-03-19 00:10:02 +00:00
|
|
|
class WhiteboardDraw(TokenClient):
|
|
|
|
def InitPersistent(self, owner, client):
|
|
|
|
TokenClient.InitPersistent(self, owner, client, "drawable", "solid")
|
|
|
|
|
|
|
|
def draw(self, ascr, client):
|
|
|
|
if client == self.client:
|
|
|
|
if self.owner.miLayers.Value("Show One"):
|
2011-10-05 21:50:18 +00:00
|
|
|
ascr.PutAscr(self.owner.GetLayer().ascr)
|
2011-03-19 00:10:02 +00:00
|
|
|
else:
|
2011-10-05 21:50:18 +00:00
|
|
|
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) # |
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
class CursorBlinker(Token):
|
|
|
|
def InitPersistent(self, owner):
|
|
|
|
Token.InitPersistent(self, owner)
|
|
|
|
Blinker(self, self.BlinkAllCursors)
|
|
|
|
|
|
|
|
def BlinkAllCursors(self, fBlink):
|
|
|
|
for tok in self.game.rgtoken("cursor"):
|
|
|
|
tok.blinkCursor(fBlink)
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class MiColour(MiList):
|
|
|
|
def InitPersistent(self, stName, rgcolor, col):
|
|
|
|
self.rgcolor = rgcolor
|
|
|
|
MiList.InitPersistent(self, rgcolor, rgcolor.index(col))
|
|
|
|
self.stName = stName
|
|
|
|
|
|
|
|
def StName(self):
|
|
|
|
return self.stName
|
|
|
|
|
|
|
|
def DrawValue(self, ascr, x, y, selor):
|
|
|
|
for icol in range(len(self.rgcolor)):
|
|
|
|
col = self.rgcolor[icol]
|
|
|
|
ascr.PutAch(ansi.MkAch(chr(219) if icol != self.ival else chr(254), col, ansi.BLACK if col != ansi.BLACK else ansi.WHITE), x + icol, y)
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class MiChars(MiList):
|
|
|
|
def InitPersistent(self, rgchar, miFg, miBg):
|
|
|
|
MiList.InitPersistent(self, rgchar)
|
|
|
|
self.miFg = miFg
|
|
|
|
self.miBg = miBg
|
|
|
|
def StName(self):
|
|
|
|
return "Characters"
|
|
|
|
def DrawValue(self, ascr, x, y, selor):
|
|
|
|
for ich, ch in enumerate(self.Value()):
|
|
|
|
ascr.PutSt(ChFromIch(ich) + ":", x, y, self.ColFg(), self.ColBg(selor))
|
|
|
|
ascr.PutAch(ansi.MkAch(chr(ch), self.miFg.Value(), self.miBg.Value()), x + 2, y)
|
|
|
|
x = x + 4
|
|
|
|
|
|
|
|
def ChFromIch(ich):
|
|
|
|
if ich == 9:
|
|
|
|
return '0'
|
|
|
|
return str(ich + 1)
|
|
|
|
|
|
|
|
def IchFromCh(ch):
|
|
|
|
if ch == '0':
|
|
|
|
return 9
|
|
|
|
return int(ch) - 1
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class MiChat(Mi):
|
|
|
|
KWNDMSG = 0
|
|
|
|
KWNDUSERS = 1
|
|
|
|
def InitPersistent(self, client, height, chat):
|
|
|
|
Mi.InitPersistent(self)
|
|
|
|
self.client = client
|
|
|
|
self.chat = chat
|
|
|
|
self.height = height
|
|
|
|
assert height > 2
|
|
|
|
self.kwnd = self.KWNDMSG
|
|
|
|
self.imsg = 0
|
|
|
|
self.iuser = 0
|
|
|
|
|
|
|
|
def StName(self):
|
|
|
|
return "Chat"
|
|
|
|
|
|
|
|
def HandleKey(self, key):
|
|
|
|
if self.kwnd == self.KWNDUSERS:
|
|
|
|
if key == ansi.K_LEFT:
|
|
|
|
self.kwnd = self.KWNDMSG
|
|
|
|
elif (key == 'a' or key == 'A') and self.iuser > 0:
|
|
|
|
self.iuser = self.iuser - 1
|
|
|
|
elif (key == 'z' or key == 'Z') and self.iuser < self.chat.CUsers() - 1:
|
|
|
|
self.iuser = self.iuser + 1
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
else: #KWNDMSG
|
|
|
|
if key == ansi.K_RIGHT:
|
|
|
|
self.kwnd = self.KWNDUSERS
|
|
|
|
elif (key == 'a' or key == 'A') and self.imsg < self.chat.CChl() - 1:
|
|
|
|
self.imsg = self.imsg + 1
|
|
|
|
elif (key == 'z' or key == 'Z') and self.imsg > 0:
|
|
|
|
self.imsg = self.imsg - 1
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def Height(self, w):
|
|
|
|
return self.height
|
|
|
|
|
|
|
|
def ColBgDefault(self):
|
|
|
|
return ansi.BLACK
|
|
|
|
def ColBgSelected(self, fPri):
|
|
|
|
return ansi.BLACK
|
|
|
|
def ColFg(self):
|
|
|
|
return ansi.WHITE
|
|
|
|
|
|
|
|
def FIgnoreParent(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def Draw(self, ascr, x, y, w, selor):
|
|
|
|
wChat = (w / 4) * 3
|
|
|
|
wUser = (w / 4) - 1
|
|
|
|
self.chat.DrawMsg(ascr, x, y, wChat, self.height - 1, self.ColBg(selor), self.imsg)
|
|
|
|
for yT in range(y, y + self.height - 1):
|
|
|
|
ascr.PutAch(ansi.MkAch(chr(179)), x + wChat, yT)
|
|
|
|
ascr.PutSt("{0:{1}<{2}}{3}{0:{1}<{4}}".format("", chr(196), wChat, chr(193), wUser), x, y + self.height - 1)
|
|
|
|
self.chat.DrawUsers(ascr, x + wChat + 1, y, wUser, self.height - 1, self.ColBg(selor), self.iuser)
|
|
|
|
if selor.KSel() == Selor.PRI:
|
|
|
|
if self.kwnd == self.KWNDMSG:
|
|
|
|
xBar = x + wChat - 1
|
|
|
|
pct = 1 - (self.imsg / float(self.chat.CChl()))
|
|
|
|
else: # KWNDUSERS
|
|
|
|
xBar = x + w - 1
|
|
|
|
pct = self.iuser / float(self.chat.CUsers())
|
|
|
|
yBar = int(y + (pct * (self.height - 4)))
|
|
|
|
ascr.PutAch(ansi.MkAch("A", ansi.RED, ansi.WHITE), xBar, yBar)
|
|
|
|
ascr.PutAch(ansi.MkAch(chr(186), ansi.RED, ansi.WHITE), xBar, yBar + 1)
|
|
|
|
ascr.PutAch(ansi.MkAch("Z", ansi.RED, ansi.WHITE), xBar, yBar + 2)
|
2011-04-12 15:37:52 +00:00
|
|
|
|
2011-09-21 21:41:57 +00:00
|
|
|
class Joiner(LeaveJoinToken):
|
2011-03-19 00:10:02 +00:00
|
|
|
def InitPersistent(self, owner):
|
|
|
|
Token.InitPersistent(self, owner)
|
|
|
|
self.msgScroller = self.game.rgtoken("msgscroller")[0]
|
2011-10-05 21:50:18 +00:00
|
|
|
self.board = self.game.drawing
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def OnJoin(self, client):
|
|
|
|
with client.Cldg().SetTransiently() as cldg:
|
|
|
|
cldg.iclient = -1
|
|
|
|
iclient = 1
|
|
|
|
rgiclient = [clientT.Cldg().iclient for clientT in self.game.rgclient]
|
|
|
|
while iclient in rgiclient:
|
|
|
|
iclient = iclient + 1
|
|
|
|
cldg.iclient = iclient
|
|
|
|
self.msgScroller.evPost.fire(client.cld.user + "(#" + str(cldg.iclient) + ") has joined! :)")
|
|
|
|
self.board.chat.Add(ChlSys(client, "has joined"))
|
|
|
|
|
|
|
|
def OnLeave(self, client):
|
|
|
|
self.msgScroller.evPost.fire(client.cld.user + " has left! :(")
|
|
|
|
self.board.chat.Add(ChlSys(client, "has left"))
|
|
|
|
|
|
|
|
class Lobby(TokenClient):
|
|
|
|
def InitPersistent(self, owner, client):
|
|
|
|
TokenClient.InitPersistent(self, owner, client)
|
2011-10-05 21:50:18 +00:00
|
|
|
drawing = client.Cldg(self.game).drawingSelected
|
|
|
|
if drawing == None:
|
|
|
|
self.lobbyCurrent = LobbyProject(self, client)
|
|
|
|
else:
|
|
|
|
self.lobbyCurrent = LobbyBoard(self, client, drawing.owner, drawing)
|
2011-09-14 22:30:44 +00:00
|
|
|
|
|
|
|
def SwitchToLobby(self, lobbyNew):
|
2011-09-16 12:57:31 +00:00
|
|
|
lobbyOld = self.lobbyCurrent
|
2011-09-14 22:30:44 +00:00
|
|
|
self.lobbyCurrent = lobbyNew
|
2011-09-16 12:57:31 +00:00
|
|
|
lobbyOld.die()
|
2011-09-14 22:30:44 +00:00
|
|
|
|
|
|
|
class LobbyI(TokenClient):
|
2011-10-05 21:50:18 +00:00
|
|
|
def InitPersistent(self, owner, client, objSelected = None, *rgmiListTop):
|
2011-09-14 22:30:44 +00:00
|
|
|
TokenClient.InitPersistent(self, owner, client)
|
2011-09-16 12:57:31 +00:00
|
|
|
|
|
|
|
rgmiList = RgmiProjected(self.RgObj(), DgProjectMiButton(self.OnObjSelected))
|
|
|
|
if rgmiListTop != None:
|
|
|
|
rgmiList = Rgseq(rgmiListTop, rgmiList)
|
|
|
|
self.miDrawings = MiMenu(rgmiList)
|
2011-10-05 21:50:18 +00:00
|
|
|
if objSelected:
|
|
|
|
mi = self.miDrawings.MiByName(objSelected.StName())
|
|
|
|
self.miDrawings.selMi.SetSelected(mi)
|
|
|
|
self.miCmds = self.CreateMiCmds()
|
2011-03-19 00:10:02 +00:00
|
|
|
OvMenu(self, client, MiMenuHoriz([self.miDrawings, self.miCmds], [65, 35]), OvMenu.FILL)
|
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
def RgObj(self):
|
|
|
|
"Return the list of objects we are selecting from"
|
|
|
|
raise "not implemented"
|
2011-10-05 21:50:18 +00:00
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
def OnObjSelected(self, obj):
|
|
|
|
"Called when an object is selected by the user"
|
|
|
|
raise "not implemented"
|
2011-10-05 21:50:18 +00:00
|
|
|
|
|
|
|
def RgstMetadata(self, obj):
|
|
|
|
"Return a list of strings containing user-readable metadata about the object"
|
2011-09-14 22:30:44 +00:00
|
|
|
raise "not implemented"
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def StMetadata(self):
|
|
|
|
try:
|
|
|
|
return "\n".join(self.RgstMetadata(self.miDrawings.Value()))
|
|
|
|
except:
|
|
|
|
return ""
|
|
|
|
|
2011-10-08 18:57:33 +00:00
|
|
|
def MiTypein_MiButton_DgNew(self, stBtnLabel, stMiTypein, dgOnSelect):
|
2011-10-09 23:28:10 +00:00
|
|
|
def NewI(*rgarg):
|
2011-10-08 18:57:33 +00:00
|
|
|
stName = self.miCmds.Value(stMiTypein)
|
2011-10-05 21:50:18 +00:00
|
|
|
if stName != "":
|
|
|
|
dgOnSelect(stName)
|
2011-10-08 18:57:33 +00:00
|
|
|
return (MiTypein(NewI, stMiTypein), MiButton(stBtnLabel, NewI), NewI)
|
|
|
|
|
|
|
|
def MiTypein_MiButton(self, stBtnLabel, stMiTypein, dgOnSelect):
|
|
|
|
return self.MiTypein_MiButton_DgNew(stBtnLabel, stMiTypein, dgOnSelect)[:2]
|
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
class LobbyBoard(LobbyI):
|
2011-10-05 21:50:18 +00:00
|
|
|
def InitPersistent(self, owner, client, project, drawing = None):
|
2011-09-14 22:30:44 +00:00
|
|
|
self.project = project
|
2011-10-05 21:50:18 +00:00
|
|
|
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)
|
2011-10-08 18:57:33 +00:00
|
|
|
miTypeinSpr, miBtnNewSpr, dgNewSprite = self.MiTypein_MiButton_DgNew("New Sprite", "SpriteName", self.NewSprite)
|
|
|
|
miTypeinW = MiTypein(dgNewSprite, "w")
|
2011-10-05 21:50:18 +00:00
|
|
|
miTypeinW.SetValue("1")
|
2011-10-08 18:57:33 +00:00
|
|
|
miTypeinH = MiTypein(dgNewSprite, "h")
|
2011-10-05 21:50:18 +00:00
|
|
|
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)])
|
2011-09-14 22:30:44 +00:00
|
|
|
|
|
|
|
def RgObj(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
return self.project.rgdrawing
|
2011-09-14 22:30:44 +00:00
|
|
|
def OnObjSelected(self, board):
|
2011-03-19 00:10:02 +00:00
|
|
|
self.client.leaveGame(board)
|
2011-10-05 21:50:18 +00:00
|
|
|
def NewBoard(self, stName):
|
2011-09-16 12:57:31 +00:00
|
|
|
self.OnObjSelected(self.project.NewBoard(stName, self.client.cld.user))
|
2011-10-05 21:50:18 +00:00
|
|
|
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):
|
2011-09-16 12:57:31 +00:00
|
|
|
if board != None:
|
2011-10-05 21:50:18 +00:00
|
|
|
return board.RgstMetadata()
|
|
|
|
return self.project.RgstMetadata()
|
|
|
|
|
2011-09-16 12:57:31 +00:00
|
|
|
def Back(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
self.owner.SwitchToLobby(LobbyProject(self.owner, self.client, self.project))
|
2011-09-16 12:57:31 +00:00
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
class LobbyProject(LobbyI):
|
2011-10-05 21:50:18 +00:00
|
|
|
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)])
|
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
def StNewObj(self):
|
|
|
|
return "New Project"
|
|
|
|
def RgObj(self):
|
|
|
|
return self.game.rgproject
|
|
|
|
def OnObjSelected(self, project):
|
|
|
|
self.owner.SwitchToLobby(LobbyBoard(self.owner, self.client, project))
|
|
|
|
def New(self, stName):
|
|
|
|
project = self.game.NewProject(stName, self.client.cld.user)
|
|
|
|
self.OnObjSelected(project)
|
2011-10-05 21:50:18 +00:00
|
|
|
def RgstMetadata(self, project):
|
|
|
|
return project.RgstMetadata()
|
2011-09-14 22:30:44 +00:00
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
class RunnerWB(Runner):
|
|
|
|
def InitPersistent(self):
|
|
|
|
self.gameLobby = GameLobby()
|
|
|
|
Runner.InitPersistent(self)
|
|
|
|
|
|
|
|
def RunGame(self, client):
|
|
|
|
if (client.joinGame(GameLogin())):
|
2011-10-05 21:50:18 +00:00
|
|
|
client.Cldg(self.gameLobby).drawingSelected = None
|
2011-03-19 00:10:02 +00:00
|
|
|
while True:
|
2011-10-05 21:50:18 +00:00
|
|
|
drawing = client.joinGame(self.gameLobby)
|
|
|
|
client.Cldg(self.gameLobby).drawingSelected = drawing
|
|
|
|
client.joinGame(self.gameLobby.GameFromDrawing(drawing))
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
class GameLogin(Game):
|
|
|
|
def GetRgclsTokTrans(self):
|
|
|
|
return [[AutoJoiner, login.LoginTerm]]
|
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
@Version(6)
|
2011-03-19 00:10:02 +00:00
|
|
|
class GameLobby(Game):
|
|
|
|
def InitPersistent(self):
|
2011-09-14 22:30:44 +00:00
|
|
|
self.rgproject = []
|
2011-03-19 00:10:02 +00:00
|
|
|
Game.InitPersistent(self)
|
|
|
|
|
|
|
|
def InitTransient(self):
|
|
|
|
Game.InitTransient(self)
|
2011-10-05 21:50:18 +00:00
|
|
|
self.mpdrawing_game = {}
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def GetRgclsTokTrans(self):
|
|
|
|
return [[AutoJoiner, Lobby]]
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
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()
|
2020-06-28 14:32:13 +00:00
|
|
|
game.rgdgdie.append(Partial(self.KillBoard, drawing))
|
2011-10-05 21:50:18 +00:00
|
|
|
self.mpdrawing_game[drawing] = game
|
|
|
|
return game
|
|
|
|
return self.mpdrawing_game[drawing]
|
|
|
|
|
2020-06-28 14:32:13 +00:00
|
|
|
def KillBoard(self, drawing):
|
|
|
|
del self.mpdrawing_game[drawing]
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def CclientDrawing(self, drawing):
|
|
|
|
if drawing in self.mpdrawing_game:
|
|
|
|
return len(self.mpdrawing_game[drawing].rgclient)
|
2011-09-14 22:30:44 +00:00
|
|
|
return 0
|
2011-03-19 00:10:02 +00:00
|
|
|
|
2011-09-14 22:30:44 +00:00
|
|
|
def StNameProject(self, project):
|
2011-10-05 21:50:18 +00:00
|
|
|
return project.stName + " [" + str(sum([self.CclientDrawing(drawing) for drawing in project.rgdrawing])) + "]"
|
2011-03-19 00:10:02 +00:00
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def StNameDrawing(self, drawing):
|
|
|
|
return drawing.stName + " [" + str(self.CclientDrawing(drawing)) + "]"
|
2011-09-16 12:57:31 +00:00
|
|
|
|
|
|
|
def NewProject(self, stName, user):
|
|
|
|
proj = Project(self, stName, user)
|
|
|
|
self.rgproject.insert(0, proj)
|
|
|
|
return proj
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def DrawingTouched(self, drawing):
|
|
|
|
project = drawing.owner
|
2011-09-16 12:57:31 +00:00
|
|
|
if project != self.rgproject[0]:
|
|
|
|
self.rgproject.remove(project)
|
|
|
|
self.rgproject.insert(0, project)
|
2011-03-19 00:10:02 +00:00
|
|
|
#haaaack
|
|
|
|
self.ensureRun() # redraw
|
|
|
|
|
|
|
|
def UpgradeFrom(self, versionOld):
|
|
|
|
if versionOld < 3:
|
|
|
|
for gameWB in self.rggameWB:
|
|
|
|
gameWB.gameLobby = self
|
|
|
|
if versionOld < 4:
|
|
|
|
self.rgboard = [game.rgtoken("whiteboard")[0].board for game in self.rggameWB]
|
|
|
|
for gameWB in self.rggameWB:
|
|
|
|
gameWB.finish()
|
|
|
|
if versionOld < 5:
|
|
|
|
del self.rggameWB
|
2011-09-14 22:30:44 +00:00
|
|
|
if versionOld < 6:
|
|
|
|
project = Project(self, "Drawings", "Willy Marmot")
|
|
|
|
for board in self.rgboard:
|
|
|
|
board.TransferToOwner(project)
|
2011-10-05 21:50:18 +00:00
|
|
|
project.rgdrawing.append(board)
|
2011-09-14 22:30:44 +00:00
|
|
|
del self.rgboard
|
|
|
|
self.rgproject = [project]
|
2011-10-05 21:50:18 +00:00
|
|
|
self.mpuser_cldg = {} # ugh, upgrading parent classes is broken in our model :(
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
class GameWB(Game):
|
|
|
|
def InitPersistent(self, gameLobby, board):
|
|
|
|
self.gameLobby = gameLobby
|
2011-10-05 21:50:18 +00:00
|
|
|
self.drawing = board
|
2011-03-19 00:10:02 +00:00
|
|
|
Game.InitPersistent(self)
|
|
|
|
|
|
|
|
def InitTransient(self):
|
|
|
|
Game.InitTransient(self)
|
|
|
|
if not self.FDead():
|
2011-10-05 21:50:18 +00:00
|
|
|
self.drawing.chat.AttachToGame(self)
|
|
|
|
self.rgdgdie.append(self.drawing.chat.DetachFromGame)
|
2011-03-19 00:10:02 +00:00
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
def ClsCursor(self):
|
|
|
|
return Cursor
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def GetRgclsTokTrans(self):
|
2011-10-05 21:50:18 +00:00
|
|
|
return [MsgScroller, Joiner, [AutoJoiner, self.ClsCursor()], [AliveWithPlayers, CursorBlinker], AutoKiller]
|
2011-03-19 00:10:02 +00:00
|
|
|
|
|
|
|
def GetRgtagDraw(self):
|
|
|
|
return ["background", "solid", "cursor", "menu", "msgscroller"]
|
|
|
|
|
2011-10-05 21:50:18 +00:00
|
|
|
class GameSprEdit(GameWB):
|
|
|
|
def ClsCursor(self):
|
|
|
|
return CursorSprite
|
|
|
|
|
2011-03-19 00:10:02 +00:00
|
|
|
if __name__ == "__main__":
|
2020-06-28 14:32:13 +00:00
|
|
|
if len(sys.argv) > 1:
|
|
|
|
config.override(sys.argv[1])
|
|
|
|
Run(RunnerWB, config.ODBPATH)
|