cleanup!
This commit is contained in:
parent
60997eccad
commit
3b9ce53b4e
|
@ -0,0 +1,6 @@
|
|||
[*.{py,json,hy,yaml}]
|
||||
charset = utf-8
|
||||
indent_style = spaces
|
||||
insert_final_newline = true
|
||||
indent_size = 4
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
kate: indent-pasted-text false; indent-width 4; space-indent true;
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
import curses
|
||||
|
||||
class Colours:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.colours = min(curses.COLORS, 16)
|
||||
self.pairs = self.colours*self.colours
|
||||
|
||||
curses.use_default_colors()
|
||||
for i in range(0, self.pairs):
|
||||
curses.init_pair(i, i%self.colours, i//self.colours)
|
||||
|
||||
def get(self, fg=0, bg=0):
|
||||
if self.colours == 16:
|
||||
return curses.color_pair(fg + bg*self.colours)
|
||||
elif self.colours == 8:
|
||||
dfg = fg % 8
|
||||
dbg = bg % 8
|
||||
if bg == 8:
|
||||
dbg = 7
|
||||
if fg == 8:
|
||||
dfg = 7
|
||||
colour = curses.color_pair(dfg + dbg*self.colours)
|
||||
if fg >= 8 and bg < 8:
|
||||
colour |= curses.A_BOLD
|
||||
elif fg < 8 and bg >= 8:
|
||||
colour |= curses.A_DIM
|
||||
return colour
|
||||
else:
|
||||
return curses.color_pair(0)
|
|
@ -1,154 +0,0 @@
|
|||
|
||||
import curses
|
||||
|
||||
from .field import Field
|
||||
from .info import Info
|
||||
from .health import Health
|
||||
from .inventory import Inventory
|
||||
from .screen import Screen
|
||||
from .colours import Colours
|
||||
from .messages import Messages
|
||||
from .switcher import Switcher
|
||||
from .textinput import TextInput
|
||||
from .widget import Widget
|
||||
|
||||
from asciifarm.common.utils import get
|
||||
|
||||
|
||||
SIDEWIDTH = 20
|
||||
|
||||
ALPHABET = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
|
||||
|
||||
class Display:
|
||||
|
||||
def __init__(self, stdscr, charMap, colours=False):
|
||||
|
||||
if colours and curses.has_colors and curses.COLORS > 1:
|
||||
self.colours = Colours()
|
||||
else:
|
||||
self.colours = None
|
||||
self.characters = {}
|
||||
|
||||
def parseSprite(sprite):
|
||||
if isinstance(sprite, str):
|
||||
return (sprite, None, None)
|
||||
char = get(sprite, 0, " ")
|
||||
fg = get(sprite, 1)
|
||||
bg = get(sprite, 2)
|
||||
return (char, fg, bg)
|
||||
for name, sprite in charMap["mapping"].items():
|
||||
vals = parseSprite(sprite)
|
||||
if vals:
|
||||
self.characters[name] = vals
|
||||
|
||||
for name, colours in charMap.get("writable", {}).items():
|
||||
fg = get(colours, 0)
|
||||
bg = get(colours, 1)
|
||||
for i in range(min(len(ALPHABET), len(charMap.get("alphabet", [])))):
|
||||
self.characters[name + '-' + ALPHABET[i]] = (charMap["alphabet"][i], fg, bg)
|
||||
|
||||
self.defaultChar = parseSprite(charMap.get("default", "?"))
|
||||
screen = Screen(self, stdscr, self.colours)
|
||||
self.screen = screen
|
||||
|
||||
self.widgets = {}
|
||||
|
||||
self.addWidget(Field((1, 1), charMap.get("charwidth", 1), self.colours), "field")
|
||||
self.addWidget(Info(), "info")
|
||||
self.addWidget(Health(
|
||||
charMap.get("healthfull", ("@",7, 2)),
|
||||
charMap.get("healthempty", ("-",7, 1))
|
||||
),
|
||||
"health")
|
||||
self.addWidget(Inventory("Inventory"), "inventory")
|
||||
self.addWidget(Inventory("Ground"), "ground")
|
||||
self.addWidget(Inventory("Equipment"), "equipment")
|
||||
|
||||
|
||||
#switcher = Switcher([self.widgets["ground"], self.widgets["inventory"], self.widgets["equipment"]], 1)
|
||||
self.addWidget(Inventory(""), "switch")
|
||||
self.addWidget(Messages(charMap.get("msgcolours", {})), "msg")
|
||||
self.addWidget(TextInput(), "textinput")
|
||||
|
||||
self.forced = False
|
||||
|
||||
def addWidget(self, w, name, winname=None):
|
||||
if not winname:
|
||||
winname = name
|
||||
widget = Widget(w, name)
|
||||
self.widgets[name] = widget
|
||||
widget.setWin(winname, self.screen)
|
||||
|
||||
def getWidget(self, name):
|
||||
if name in self.widgets:
|
||||
return self.widgets[name].getImpl()
|
||||
else:
|
||||
return None
|
||||
|
||||
def resizeField(self, size):
|
||||
self.getWidget("field").resize(*size)
|
||||
self.forced = True
|
||||
|
||||
def drawFieldCells(self, cells):
|
||||
field = self.getWidget("field")
|
||||
for cell in cells:
|
||||
(x, y), spriteNames = cell
|
||||
sprites = [self.getChar(spriteName) for spriteName in spriteNames]
|
||||
if not len(sprites):
|
||||
sprites = [self.getChar(" ")]
|
||||
field.changeCell(x, y, sprites)
|
||||
|
||||
|
||||
def setFieldCenter(self, pos):
|
||||
self.getWidget("field").setCenter(pos)
|
||||
|
||||
def setHealth(self, health, maxHealth):
|
||||
self.getWidget("health").setHealth(health, maxHealth)
|
||||
|
||||
|
||||
def showInfo(self, infostring):
|
||||
self.getWidget("info").showString(infostring)
|
||||
|
||||
|
||||
#def setInventory(self, items):
|
||||
#self.getWidget("inventory").setInventory(items)
|
||||
|
||||
|
||||
#def setEquipment(self, slots):
|
||||
#self.getWidget("equipment").setInventory(
|
||||
#sorted([
|
||||
#slot + ": " + (item if item else "")
|
||||
#for slot, item in slots.items()
|
||||
#])
|
||||
#)
|
||||
|
||||
#def setGround(self, items):
|
||||
#self.getWidget("ground").setInventory(items)
|
||||
|
||||
|
||||
def addMessage(self, message, type):
|
||||
self.getWidget("msg").addMessage(message, type)
|
||||
|
||||
def scrollBack(self, amount, relative=True):
|
||||
self.getWidget("msg").scroll(amount, relative)
|
||||
|
||||
def getChar(self, sprite):
|
||||
"""This returns the character belonging to some spritename. This does not read a character"""
|
||||
return self.characters.get(sprite, self.defaultChar)
|
||||
|
||||
def setInputString(self, string, cursor):
|
||||
self.getWidget("textinput").setText(string, cursor)
|
||||
|
||||
def update(self):
|
||||
changed = False
|
||||
for widget in self.widgets.values():
|
||||
if self.forced or widget.isChanged():
|
||||
widget.update()
|
||||
changed = True
|
||||
if changed:
|
||||
self.screen.update()
|
||||
self.forced = False
|
||||
|
||||
def forceUpdate(self):
|
||||
self.forced = True
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
|
||||
import curses
|
||||
from .widimp import WidImp
|
||||
|
||||
class Field(WidImp):
|
||||
|
||||
|
||||
def __init__(self, size=(1,1), charSize=1, colours=False):
|
||||
self.pad = curses.newpad(size[1]+1, (size[0]+1)*charSize)
|
||||
self.size = size
|
||||
self.charSize = charSize
|
||||
self.center = (0, 0)
|
||||
self.colours = colours
|
||||
self.changed = False
|
||||
self.redraw = False
|
||||
|
||||
def resize(self, width, height):
|
||||
self.size = (width, height)
|
||||
self.pad.resize(height+1, width*self.charSize)
|
||||
self.redraw = True
|
||||
self.change()
|
||||
|
||||
def changeCell(self, x, y, sprites):
|
||||
""" sprites must always have at least one element """
|
||||
char, colour, bgcolour = sprites[0]
|
||||
if bgcolour is None:
|
||||
for (ch, co, bg) in sprites:
|
||||
if bg is not None:
|
||||
bgcolour = bg
|
||||
break
|
||||
else:
|
||||
bgcolour = 0
|
||||
if colour is not None and self.colours:
|
||||
self.pad.addstr(y, x*self.charSize, " "*self.charSize, self.colours.get(7, 0))
|
||||
self.pad.addstr(y, x*self.charSize, char, self.colours.get(colour, bgcolour))
|
||||
else:
|
||||
self.pad.addstr(y, x*self.charSize, char)
|
||||
self.change()
|
||||
|
||||
def setCenter(self, pos):
|
||||
self.center = pos
|
||||
self.change()
|
||||
|
||||
def getWidth(self):
|
||||
return self.size[0]*self.charSize
|
||||
|
||||
def getHeight(self):
|
||||
return self.size[1]
|
||||
|
||||
def _roundWidth(self, x):
|
||||
return x // self.charSize * self.charSize
|
||||
|
||||
def update(self, win):
|
||||
if self.redraw:
|
||||
win.erase()
|
||||
win.noutrefresh()
|
||||
self.redraw = False
|
||||
width, height = win.getSize()
|
||||
x, y = win.getPos()
|
||||
xmax = x + width
|
||||
ymax = y + height
|
||||
self.pad.noutrefresh(
|
||||
max(0, min(self.getHeight()-height, self.center[1] - int(height/2))),
|
||||
max(0, min(
|
||||
self._roundWidth(self.getWidth()-width),
|
||||
self._roundWidth(self.center[0]*self.charSize - int(width/2)))),
|
||||
y,
|
||||
x + max(0, (width - self.getWidth()) // 2),
|
||||
ymax,
|
||||
xmax)
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
|
||||
from .widimp import WidImp
|
||||
|
||||
class Health(WidImp):
|
||||
|
||||
def __init__(self, char=None, emptyChar=None):
|
||||
self.char = char or ('@',7,0)
|
||||
self.emptyChar = emptyChar or ('-',7,0)
|
||||
self.changed = False
|
||||
self.health = 0
|
||||
self.maxHealth = 0
|
||||
|
||||
def setHealth(self, health, maxHealth):
|
||||
self.health = health or 0
|
||||
self.maxHealth = maxHealth or 0
|
||||
self.change()
|
||||
|
||||
def update(self, win):
|
||||
width, height = win.getSize()
|
||||
width -= 1
|
||||
barEnd = round(self.health/self.maxHealth * width) if self.maxHealth > 0 else 0
|
||||
win.erase()
|
||||
win.addLine((0,0),"Health: {}/{}".format(self.health, self.maxHealth)[:width])
|
||||
win.addLine((0, 1), self.char[0]*barEnd, self.char[1:])
|
||||
win.addLine((barEnd, 1), self.emptyChar[0]*(width-barEnd), self.emptyChar[1:])
|
||||
win.noutrefresh()
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
from .widimp import WidImp
|
||||
|
||||
class Info(WidImp):
|
||||
|
||||
def __init__(self):
|
||||
self.changed = False
|
||||
self.lines = []
|
||||
self.lastString = None
|
||||
|
||||
def showString(self, string):
|
||||
if string == self.lastString:
|
||||
return
|
||||
self.lines = string.split('\n')
|
||||
self.change()
|
||||
self.lastString = string
|
||||
|
||||
def update(self, win):
|
||||
width, height = win.getSize()
|
||||
lines = [line[:width-1] for line in self.lines][:height]
|
||||
win.erase()
|
||||
for i, line in enumerate(lines):
|
||||
win.addLine((0, i), line)
|
||||
win.noutrefresh()
|
|
@ -1,73 +0,0 @@
|
|||
|
||||
from asciifarm.common import utils
|
||||
|
||||
from .widimp import WidImp
|
||||
|
||||
class Inventory(WidImp):
|
||||
|
||||
def __init__(self, title, titlebar="{}:", selectorChar="*"):
|
||||
self.title = title
|
||||
self.titlebar = titlebar
|
||||
self.selectorChar = selectorChar
|
||||
self.items = []
|
||||
self.selector = 0
|
||||
|
||||
def getSelected(self):
|
||||
return self.selector
|
||||
|
||||
def select(self, value, relative=False, modular=False):
|
||||
invLen = len(self.items)
|
||||
if relative:
|
||||
value += self.selector
|
||||
if modular and invLen:
|
||||
value %= invLen
|
||||
if value < 0:
|
||||
value = 0
|
||||
if value >= invLen:
|
||||
value = invLen-1
|
||||
if value in range(invLen):
|
||||
self.doSelect(value)
|
||||
|
||||
def doSelect(self, value):
|
||||
self.selector = value
|
||||
self.change()
|
||||
|
||||
def setInventory(self, items):
|
||||
self.items = items
|
||||
self.selector = utils.clamp(self.selector, 0, len(items)-1)
|
||||
self.change()
|
||||
|
||||
def getItem(self, num):
|
||||
return self.items[num]
|
||||
|
||||
def getSelectedItem(self):
|
||||
return self.getItem(self.getSelected())
|
||||
|
||||
def setTitle(self, title):
|
||||
self.title = title
|
||||
|
||||
def getNumItems(self):
|
||||
return len(self.items)
|
||||
|
||||
def itemName(self, item):
|
||||
return item
|
||||
|
||||
def update(self, win):
|
||||
|
||||
width, height = win.getSize()
|
||||
height -= 1
|
||||
selected = self.selector
|
||||
start = min(selected - height//2, len(self.items)-height)
|
||||
start = max(start, 0)
|
||||
end = start + height
|
||||
win.erase()
|
||||
win.addLine((0,0), (self.titlebar.format(self.title))[:width])
|
||||
for i, item in enumerate(self.items[start:end]):
|
||||
if i + start == selected:
|
||||
win.addLine((0, i+1), self.selectorChar)
|
||||
win.addLine((1, i+1), self.itemName(item))
|
||||
if end < len(self.items):
|
||||
win.addLine((width-1, height), "+")
|
||||
if start > 0:
|
||||
win.addLine((width-1, 1), "-")
|
||||
win.noutrefresh()
|
|
@ -1,56 +0,0 @@
|
|||
|
||||
import textwrap
|
||||
|
||||
from .widimp import WidImp
|
||||
|
||||
class Messages(WidImp):
|
||||
|
||||
def __init__(self, colours):
|
||||
self.changed = False
|
||||
self.messages = []
|
||||
self.scrolledBack = 0
|
||||
self.colours = colours
|
||||
|
||||
def addMessage(self, message, type=None):
|
||||
self.messages.append([message, type])
|
||||
if self.scrolledBack:
|
||||
self.scrolledBack += 1
|
||||
self.change()
|
||||
|
||||
def scroll(self, amount, relative=True):
|
||||
if relative:
|
||||
self.scrolledBack += amount
|
||||
else:
|
||||
self.scrolledBack = amount
|
||||
self.scrolledBack = max(self.scrolledBack, 0)
|
||||
self.change()
|
||||
|
||||
def update(self, win):
|
||||
width, height = win.getSize()
|
||||
if height < 1:
|
||||
return
|
||||
lines = []
|
||||
messages = self.messages
|
||||
for message, type in messages:
|
||||
colour = self.colours.get(type, (7,0))
|
||||
for line in textwrap.wrap(message, width):
|
||||
lines.append((line, colour))
|
||||
self.scrolledBack = max(min(self.scrolledBack, len(lines)-height), 0)
|
||||
moreDown = False
|
||||
if self.scrolledBack > 0:
|
||||
lines = lines[:-self.scrolledBack]
|
||||
moreDown = True
|
||||
moreUp = False
|
||||
if len(lines) > height:
|
||||
moreUp = True
|
||||
lines = lines[len(lines)-height:]
|
||||
elif len(lines) < height:
|
||||
lines = (height-len(lines)) * [("",)] + lines
|
||||
win.erase()
|
||||
for i, line in enumerate(lines):
|
||||
win.addLine((0,i), *line)
|
||||
if moreUp:
|
||||
win.addLine((width-1, 0), '-')
|
||||
if moreDown:
|
||||
win.addLine((width-1, height-1), '+')
|
||||
win.noutrefresh()
|
|
@ -1,95 +0,0 @@
|
|||
|
||||
import curses
|
||||
from asciifarm.common.utils import clamp
|
||||
from .window import Window
|
||||
|
||||
import signal
|
||||
|
||||
class Screen:
|
||||
|
||||
def __init__(self, display, stdscr, colours):
|
||||
self.display = display
|
||||
try:
|
||||
curses.curs_set(0)
|
||||
self.cursorSet = False
|
||||
except curses.error:
|
||||
# Not all terminals support this functionality.
|
||||
# When the error is ignored the screen will look a little uglier,
|
||||
# A cursor will move around, but that's not terrible
|
||||
# So in order to keep the game as accesible as possible to everyone, it should be safe to ignore the error.
|
||||
self.cursorSet = True
|
||||
# It is probably possible to make sure the cursor is only in a corner of the screen
|
||||
# but I can't figure out how.
|
||||
# it seems to ignore all my move commands unless I press a key
|
||||
# I give up
|
||||
self.stdscr = stdscr
|
||||
self.colours = colours
|
||||
self.setWins()
|
||||
signal.signal(signal.SIGWINCH, self.updateSize)
|
||||
|
||||
def _limitHeight(self, h, y):
|
||||
return min(h + y, self.height) - y
|
||||
|
||||
def setWins(self):
|
||||
height, width = self.height, self.width = self.stdscr.getmaxyx()
|
||||
|
||||
sideW = 20
|
||||
sideX = width-sideW
|
||||
|
||||
msgH = clamp(height // 5, 3, 5)
|
||||
msgY = height - msgH-1
|
||||
inputH = 1
|
||||
inputY = msgY + msgH
|
||||
|
||||
healthY = 0
|
||||
healthH = self._limitHeight(2, healthY)
|
||||
indexY = healthY + healthH
|
||||
indexH = self._limitHeight(4, indexY)
|
||||
listY = indexY + indexH + 1
|
||||
listH = self._limitHeight(12, listY)
|
||||
infoY = listY + listH
|
||||
infoH = self._limitHeight(20, infoY)
|
||||
|
||||
lists = self.makeWin(sideX, listY, sideW, listH)
|
||||
|
||||
self.windows = {
|
||||
"field": self.makeWin(0, 0, sideX - 1, msgY),
|
||||
"msg": self.makeWin(0, msgY, sideX - 1, msgH),
|
||||
"textinput": self.makeWin(0, inputY, sideX - 1, inputH),
|
||||
|
||||
"health": self.makeWin(sideX, healthY, sideW, healthH),
|
||||
"switch": self.makeWin(sideX, indexY, sideW, indexH),
|
||||
"ground": lists,
|
||||
"inventory": lists,
|
||||
"equipment": lists,
|
||||
"info": self.makeWin(sideX, infoY, sideW, infoH)
|
||||
}
|
||||
|
||||
|
||||
def makeWin(self, x, y, width, height):
|
||||
if width < 1 or height < 1:
|
||||
win = None
|
||||
else:
|
||||
win = curses.newwin(height, width, y, x)
|
||||
return Window(win, self.colours)
|
||||
|
||||
def getWin(self, name):
|
||||
return self.windows.get(name, None)
|
||||
|
||||
def updateSize(self, *args):
|
||||
curses.endwin()
|
||||
curses.initscr()
|
||||
self.setWins()
|
||||
self.stdscr.clear()
|
||||
self.display.forceUpdate()
|
||||
|
||||
def update(self):
|
||||
curses.doupdate()
|
||||
|
||||
def getWidth(self):
|
||||
return self.width
|
||||
|
||||
def getHeight(self):
|
||||
return self.height
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
|
||||
from .inventory import Inventory
|
||||
|
||||
class Switcher(Inventory):
|
||||
"""An area that can contain multiple widgets but only shows one at a time.
|
||||
There is a function to switch between the displayed widgets.
|
||||
"""
|
||||
|
||||
#def __init__(self, widgets, initial=0):
|
||||
#Inventory.__init__(self, "", "", "=")
|
||||
#self.setInventory(widgets)
|
||||
|
||||
#for wid in widgets:
|
||||
#wid.hidden = True
|
||||
|
||||
#self.select(initial)
|
||||
|
||||
#def doSelect(self, value):
|
||||
#self.getSelectedItem().hidden = True
|
||||
#self.selector = value
|
||||
#self.change()
|
||||
#newWid = self.getSelectedItem()
|
||||
#newWid.hidden = False
|
||||
#newWid.change()
|
||||
|
||||
def itemName(self, item):
|
||||
return item.getImpl().title
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
import curses
|
||||
from .widimp import WidImp
|
||||
|
||||
class TextInput(WidImp):
|
||||
|
||||
def __init__(self):
|
||||
self.text = ""
|
||||
self.cursor = -1
|
||||
|
||||
def setText(self, text, cursor):
|
||||
self.text = text
|
||||
self.cursor = cursor
|
||||
self.change()
|
||||
|
||||
def update(self, win):
|
||||
width, height = win.getSize()
|
||||
win.erase()
|
||||
win.addLine((0, 0), self.text[:width])
|
||||
if self.cursor >= 0 and self.cursor <= len(self.text):
|
||||
win.setAttr((min(self.cursor, width-1), 0), curses.A_REVERSE)
|
||||
win.noutrefresh()
|
|
@ -1,35 +0,0 @@
|
|||
|
||||
class Widget:
|
||||
|
||||
|
||||
def __init__(self, impl, name=None):
|
||||
self.impl = impl
|
||||
|
||||
self.win = None
|
||||
self.screen = None
|
||||
self.changed = False
|
||||
self.hidden = False
|
||||
self.name = name
|
||||
self.impl.setWidget(self)
|
||||
|
||||
def setWin(self, win, screen):
|
||||
self.win = win
|
||||
self.screen = screen
|
||||
|
||||
def getWin(self):
|
||||
return self.win and self.screen and self.screen.getWin(self.win)
|
||||
|
||||
def getImpl(self):
|
||||
return self.impl
|
||||
|
||||
def change(self):
|
||||
self.changed = True
|
||||
|
||||
def isChanged(self):
|
||||
return self.changed
|
||||
|
||||
def update(self):
|
||||
if not self.getWin() or self.hidden:
|
||||
return
|
||||
self.impl.update(self.getWin())
|
||||
self.changed = False
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
|
||||
class WidImp:
|
||||
|
||||
"""widget implementation"""
|
||||
|
||||
_widget = None
|
||||
|
||||
def setWidget(self, widget):
|
||||
self._widget = widget
|
||||
self.change()
|
||||
|
||||
def change(self):
|
||||
if self._widget is not None:
|
||||
self._widget.change()
|
||||
|
||||
def update(self, win):
|
||||
pass
|
|
@ -1,74 +0,0 @@
|
|||
|
||||
import curses
|
||||
|
||||
class Window:
|
||||
""" Small wrapper around curses windows """
|
||||
|
||||
def __init__(self, win, colours=None):
|
||||
|
||||
self.win = win
|
||||
self.colours = colours
|
||||
|
||||
def getSize(self):
|
||||
if not self.win:
|
||||
return (0, 0)
|
||||
height, width = self.win.getmaxyx()
|
||||
return (width, height)
|
||||
|
||||
def getPos(self):
|
||||
if not self.win:
|
||||
return (0, 0)
|
||||
y, x = self.win.getparyx()
|
||||
return (x, y)
|
||||
|
||||
def addLine(self, pos, string, colour=(0,0)):
|
||||
"""Draw a string that does not contain newlines or characters with larger width
|
||||
|
||||
long lines are cropped to fit in the window"""
|
||||
|
||||
if not self.win:
|
||||
return
|
||||
x, y = pos
|
||||
width, height = self.getSize()
|
||||
string = string[:width-x]
|
||||
drawLast = None
|
||||
if self.colours:
|
||||
self._addstr(y, x, string, self.colours.get(*colour))
|
||||
else:
|
||||
self._addstr(y, x, string)
|
||||
|
||||
|
||||
def _addstr(self, y, x, string, *args):
|
||||
if not self.win:
|
||||
return
|
||||
width, height = self.getSize()
|
||||
if y == height-1 and x+len(string) == width:
|
||||
if len(string) > 1:
|
||||
self.win.addstr(y, x, string[:-1], *args)
|
||||
try:
|
||||
self.win.addstr(height-1, width-1, string[-1], *args)
|
||||
except curses.error:
|
||||
# ncurses has a weird problem:
|
||||
# it always raises an error when drawing to the last character in the window
|
||||
# it draws first and then raises the error
|
||||
# therefore to draw in the last place of the window the last character needs to be ingored
|
||||
# other solutions might be possible, but are more hacky
|
||||
pass
|
||||
else:
|
||||
self.win.addstr(y, x, string, *args)
|
||||
|
||||
def erase(self):
|
||||
if self.win:
|
||||
self.win.erase()
|
||||
|
||||
def noutrefresh(self):
|
||||
if self.win:
|
||||
self.win.noutrefresh()
|
||||
|
||||
def setAttr(self, pos, attr, num=1):
|
||||
if self.win:
|
||||
x, y = pos
|
||||
self.win.chgat(y, x, num, attr)
|
||||
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ from .inputhandler import InputHandler
|
|||
class Client:
|
||||
|
||||
def __init__(self, display, name, connection, keybindings, logFile=None):
|
||||
#self.stdscr = stdscr
|
||||
|
||||
self.display = display
|
||||
self.name = name
|
||||
self.keepalive = True
|
||||
|
@ -54,13 +54,9 @@ class Client:
|
|||
self.queue.put(("error", error))
|
||||
|
||||
def getInput(self):
|
||||
#try:
|
||||
while True:
|
||||
key = ratuil.inputs.get_key()
|
||||
#key = self.stdscr.getch()
|
||||
self.queue.put(("input", key))
|
||||
#except Exception as e:
|
||||
#self.queue.put(("error", e))
|
||||
|
||||
def close(self, msg=None):
|
||||
self.keepalive = False
|
||||
|
@ -112,23 +108,14 @@ class Client:
|
|||
if maxHealth is None:
|
||||
self.log("You have died. Restart the client to respawn")
|
||||
if msgType == "inventory":
|
||||
self.display.inventory.setItems(msg[1])
|
||||
#invbox = self.display.getWidget("inventory")
|
||||
#invbox.setInventory(self.inventory.items)
|
||||
#invbox.select(self.inventory.selector)
|
||||
#self.display.setInventory(msg[1])
|
||||
self.display.inventory.setItems(msg[1])
|
||||
if msgType == "equipment":
|
||||
#self.display.setEquipment(msg[1])
|
||||
self.display.equipment.setItems(msg[1])
|
||||
#eqbox = self.display.getWidget("equipment")
|
||||
#eqbox.setInventory(self.inventory.items)
|
||||
#eqbox.select(self.equipment.selector)
|
||||
if msgType == "ground":
|
||||
#self.display.setGround(msg[1])
|
||||
self.display.ground.setItems(msg[1])
|
||||
#grbox = self.display.getWidget("ground")
|
||||
#grbox.setInventory(self.ground.items)
|
||||
#grbox.select(self.ground.selector)
|
||||
if msgType == "message":
|
||||
self.log(*msg[1:])
|
||||
if msgType == "options":
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
|
||||
#import curses
|
||||
#import curses.ascii
|
||||
=
|
||||
import string
|
||||
|
||||
from .commandhandler import CommandHandler, InvalidCommandException
|
||||
#from .keynames import nameFromKey
|
||||
|
||||
import ratuil.inputs as inp
|
||||
|
||||
|
@ -23,7 +20,7 @@ class InputHandler:
|
|||
|
||||
def onInput(self, key):
|
||||
if not self.typing:
|
||||
keyName = key#nameFromKey(key)
|
||||
keyName = key
|
||||
if keyName in self.keybindings:
|
||||
self.commandHandler.execute(self.keybindings[keyName])
|
||||
else:
|
||||
|
@ -61,36 +58,36 @@ class InputHandler:
|
|||
self.client.display.setInputString(self.string, self.cursor if self.typing else -1)
|
||||
|
||||
def addKey(self, key):
|
||||
if key in string.printable:#curses.ascii.isprint(key):
|
||||
if key in string.printable:
|
||||
self.string = self.string[:self.cursor] + key + self.string[self.cursor:]
|
||||
self.cursor += 1
|
||||
elif key == inp.BACKSPACE: #== curses.KEY_BACKSPACE or key == curses.ascii.BS or key == curses.ascii.DEL:
|
||||
elif key == inp.BACKSPACE:
|
||||
self.string = self.string[:self.cursor-1] + self.string[self.cursor:]
|
||||
self.cursor = max(self.cursor - 1, 0)
|
||||
elif key == inp.RIGHT:#curses.KEY_RIGHT:
|
||||
elif key == inp.RIGHT:
|
||||
self.cursor = min(self.cursor + 1, len(self.string))
|
||||
elif key == inp.LEFT:#curses.KEY_LEFT:
|
||||
elif key == inp.LEFT:
|
||||
self.cursor = max(self.cursor - 1, 0)
|
||||
elif key == inp.DELETE:#curses.KEY_DC:
|
||||
elif key == inp.DELETE:
|
||||
self.string = self.string[:self.cursor] + self.string[self.cursor+1:]
|
||||
elif key == inp.HOME:#curses.KEY_HOME:
|
||||
elif key == inp.HOME:
|
||||
self.cursor = 0
|
||||
elif key == inp.END:#curses.KEY_END:
|
||||
elif key == inp.END:
|
||||
self.cursor = len(self.string)
|
||||
|
||||
elif key == inp.ESCAPE:#curses.ascii.ESC or key == curses.KEY_DL:
|
||||
elif key == inp.ESCAPE:
|
||||
# throw away entered string and go back to game
|
||||
self.typing = False
|
||||
self.string = ""
|
||||
self.cursor = 0
|
||||
elif key == inp.ENTER:#curses.ascii.LF or key == curses.ascii.CR:
|
||||
elif key == inp.ENTER:
|
||||
# process entered string and reset it
|
||||
message = self.string
|
||||
self.string = ""
|
||||
self.cursor = 0
|
||||
self.typing = False
|
||||
self.processString(message)
|
||||
elif key == "^I":#curses.ascii.TAB:
|
||||
elif key == "^I": # tab
|
||||
# return to game but keep entered string
|
||||
self.typing = False
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
import curses
|
||||
|
||||
prenamed = {
|
||||
10: "NEWLINE"
|
||||
}
|
||||
|
||||
def nameFromKey(key):
|
||||
if key in prenamed:
|
||||
return prenamed[key]
|
||||
try:
|
||||
keyname = curses.keyname(key)
|
||||
except ValueError:
|
||||
return None
|
||||
return str(keyname, "utf-8")
|
|
@ -6,6 +6,7 @@ import sys
|
|||
import termios
|
||||
import tty
|
||||
import signal
|
||||
#import os
|
||||
|
||||
from .connection import Connection
|
||||
from .gameclient import Client
|
||||
|
@ -34,27 +35,6 @@ def main(argv=None):
|
|||
oldterm = termios.tcgetattr(fd)
|
||||
|
||||
try:
|
||||
# Initialize curses
|
||||
#stdscr = curses.initscr()
|
||||
|
||||
# Turn off echoing of keys, and enter cbreak mode,
|
||||
# where no buffering is performed on keyboard input
|
||||
#curses.noecho()
|
||||
#curses.cbreak()
|
||||
|
||||
## In keypad mode, escape sequences for special keys
|
||||
## (like the cursor keys) will be interpreted and
|
||||
## a special value like curses.KEY_LEFT will be returned
|
||||
#stdscr.keypad(1)
|
||||
|
||||
# Start color, too. Harmless if the terminal doesn't have
|
||||
# color; user can test with has_color() later on. The try/catch
|
||||
# works around a minor bit of over-conscientiousness in the curses
|
||||
# module -- the error return from C start_color() is ignorable.
|
||||
#try:
|
||||
#curses.start_color()
|
||||
#except:
|
||||
#pass
|
||||
|
||||
tty.setraw(sys.stdin)
|
||||
Screen.default.hide_cursor()
|
||||
|
@ -73,11 +53,6 @@ def main(argv=None):
|
|||
closeMessage = client.closeMessage
|
||||
finally:
|
||||
## Set everything back to normal
|
||||
#if 'stdscr' in locals():
|
||||
#stdscr.keypad(0)
|
||||
#curses.echo()
|
||||
#curses.nocbreak()
|
||||
#curses.endwin()
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, oldterm)
|
||||
Screen.default.finalize()
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ class Display:
|
|||
self.ground = ListSelector(self.getWidget("ground"))
|
||||
self.switch = ListSelector(self.getWidget("switchtitles"))
|
||||
|
||||
# it is important that these lists have the same order!
|
||||
self.switch.setItems(["inventory", "equipment", "ground"])
|
||||
self.menus = {
|
||||
"inventory": self.inventory,
|
||||
|
@ -76,14 +75,9 @@ class Display:
|
|||
|
||||
def getWidget(self, name):
|
||||
return self.layout.get(name)
|
||||
#if name in self.widgets:
|
||||
#return self.widgets[name].getImpl()
|
||||
#else:
|
||||
#return None
|
||||
|
||||
def resizeField(self, size):
|
||||
self.getWidget("field").set_size(*size)
|
||||
#self.forced = True
|
||||
|
||||
def drawFieldCells(self, cells):
|
||||
field = self.getWidget("field")
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
|
||||
|
||||
from .listselector import ListSelector
|
||||
|
||||
class SwitchSelector(ListSelector):
|
||||
|
||||
|
||||
|
||||
#def setItems(self, items):
|
||||
#super().setItems(items)
|
||||
#self.updateVisibility()
|
||||
|
||||
#def updateVisibility(self):
|
||||
#pass
|
||||
##for i, (_menu, widget, _title) in enumerate(self.items):
|
||||
##if i == self.selector:
|
||||
##widget.hidden = False
|
||||
##widget.change()
|
||||
##else:
|
||||
##widget.hidden = True
|
||||
|
||||
def doSelect(self, value):
|
||||
|
||||
#self.getSelectedItem().widget.hidden = True
|
||||
super().doSelect(value)
|
||||
#self.updateVisibility()
|
||||
#self.getSelectedItem().widimp.change()
|
||||
#newWid.hidden = False
|
||||
#newWid.change()
|
||||
|
||||
def itemName(self, item):
|
||||
_menu, _widget, title = item
|
||||
return title
|
Loading…
Reference in New Issue