mirror of
https://github.com/rr-/pq-cli.git
synced 2026-09-29 06:44:00 -06:00
ui: sketch game view
This commit is contained in:
@@ -6,6 +6,7 @@ from pqcli import random
|
||||
from pqcli.mechanic import Player
|
||||
from pqcli.roster import Roster
|
||||
from pqcli.ui.confirm_dialog import ConfirmDialog
|
||||
from pqcli.ui.game_view import GameView
|
||||
from pqcli.ui.new_game_view import NewGameView
|
||||
from pqcli.ui.roster_view import RosterView
|
||||
|
||||
@@ -17,6 +18,8 @@ PALETTE: T.List[T.Tuple[str, str, str]] = [
|
||||
("linebox-focus", "light red", "black"),
|
||||
("linebox-content", "", ""),
|
||||
("linebox-content-focus", "", ""),
|
||||
("progressbar-done", "black", "light red"),
|
||||
("progressbar-incomplete", "", ""),
|
||||
]
|
||||
|
||||
|
||||
@@ -93,7 +96,9 @@ class Ui:
|
||||
self.switch_to_roster_view()
|
||||
|
||||
def switch_to_game_view(self, player_idx: int) -> None:
|
||||
raise NotImplementedError("not implemented")
|
||||
player = self.roster.players[player_idx]
|
||||
self.loop.widget = GameView(self.loop, player)
|
||||
self._connect("cancel", self.switch_to_roster_view)
|
||||
|
||||
def switch_to_delete_player_view(self, player_idx: int) -> None:
|
||||
adjective = random.choice(["faithful", "noble", "loyal", "brave"])
|
||||
|
||||
@@ -2,7 +2,7 @@ import typing as T
|
||||
|
||||
import urwid
|
||||
|
||||
from pqcli.ui.button import MenuButton
|
||||
from pqcli.ui.custom_button import CustomButton
|
||||
|
||||
|
||||
class ConfirmDialog(urwid.Overlay):
|
||||
@@ -10,10 +10,10 @@ class ConfirmDialog(urwid.Overlay):
|
||||
|
||||
def __init__(self, label: str, parent: urwid.Widget) -> None:
|
||||
question = urwid.Text(("bold", label), "center")
|
||||
yes_btn = MenuButton(
|
||||
yes_btn = CustomButton(
|
||||
"Yes", hint="Y", on_press=lambda _user_data: self.confirm()
|
||||
)
|
||||
no_btn = MenuButton(
|
||||
no_btn = CustomButton(
|
||||
"No", hint="N", on_press=lambda _user_data: self.cancel()
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import typing as T
|
||||
import urwid
|
||||
|
||||
|
||||
class MenuButton(urwid.Button):
|
||||
class CustomButton(urwid.Button):
|
||||
def __init__(
|
||||
self,
|
||||
label: str,
|
||||
@@ -3,7 +3,7 @@ import typing as T
|
||||
import urwid
|
||||
|
||||
|
||||
class LineBox(urwid.AttrWrap):
|
||||
class CustomLineBox(urwid.AttrWrap):
|
||||
def __init__(
|
||||
self, widget: urwid.Widget, *args: T.Any, **kwargs: T.Any
|
||||
) -> None:
|
||||
@@ -0,0 +1,9 @@
|
||||
import urwid
|
||||
|
||||
|
||||
class CustomProgressBar(urwid.ProgressBar):
|
||||
def __init__(self) -> None:
|
||||
super().__init__("progressbar-incomplete", "progressbar-done", 0, 1)
|
||||
|
||||
def set_max(self, value: int) -> None:
|
||||
self._done = value
|
||||
@@ -0,0 +1,115 @@
|
||||
import typing as T
|
||||
|
||||
import urwid
|
||||
|
||||
from pqcli.config import StatType
|
||||
from pqcli.mechanic import Player, Simulation
|
||||
from pqcli.ui.custom_line_box import CustomLineBox
|
||||
from pqcli.ui.custom_progress_bar import CustomProgressBar
|
||||
|
||||
|
||||
class CharacterSheetView(CustomLineBox):
|
||||
def __init__(self, player: Player) -> None:
|
||||
self.player = player
|
||||
|
||||
self.level_text = urwid.Text("")
|
||||
self.stat_texts = {stat: urwid.Text("") for stat in list(StatType)}
|
||||
|
||||
self.list_box = urwid.ListBox(
|
||||
[
|
||||
urwid.Columns([urwid.Text("Name"), urwid.Text(player.name)]),
|
||||
urwid.Columns(
|
||||
[urwid.Text("Race"), urwid.Text(player.race.name)]
|
||||
),
|
||||
urwid.Columns(
|
||||
[urwid.Text("Class"), urwid.Text(player.class_.name)]
|
||||
),
|
||||
urwid.Columns([urwid.Text("Level"), self.level_text]),
|
||||
urwid.Divider(),
|
||||
]
|
||||
+ [
|
||||
urwid.Columns([urwid.Text(stat.value), self.stat_texts[stat]])
|
||||
for stat in StatType
|
||||
]
|
||||
)
|
||||
|
||||
self.player.connect("level_up", self.sync_level)
|
||||
self.player.stats.connect("change", self.sync_stats)
|
||||
self.sync_level()
|
||||
self.sync_stats()
|
||||
|
||||
super().__init__(self.list_box, title="Character Sheet")
|
||||
|
||||
def sync_level(self) -> None:
|
||||
self.level_text.set_text(str(self.player.level))
|
||||
|
||||
def sync_stats(self) -> None:
|
||||
for stat in StatType:
|
||||
self.stat_texts[stat].set_text(str(self.player.stats[stat]))
|
||||
|
||||
|
||||
class TaskView(urwid.Pile):
|
||||
def __init__(self, player: Player) -> None:
|
||||
self.player = player
|
||||
|
||||
self.current_task_text = urwid.Text("...")
|
||||
self.current_task_bar = CustomProgressBar()
|
||||
|
||||
self.player.task_bar.connect("change", self.sync_position)
|
||||
self.player.connect("new_task", self.sync_task_name)
|
||||
self.sync_position()
|
||||
self.sync_task_name()
|
||||
|
||||
super().__init__([self.current_task_text, self.current_task_bar])
|
||||
|
||||
def sync_position(self) -> None:
|
||||
self.current_task_bar.set_completion(self.player.task_bar.position)
|
||||
self.current_task_bar.set_max(self.player.task_bar.max_)
|
||||
|
||||
def sync_task_name(self) -> None:
|
||||
self.current_task_text.set_text(
|
||||
f"{self.player.task.description}..." if self.player.task else "?"
|
||||
)
|
||||
|
||||
def pack(self, size: T.Tuple[int, int]) -> T.Tuple[int, int]:
|
||||
return (size[0], 2)
|
||||
|
||||
|
||||
class GameView(urwid.Pile):
|
||||
signals = ["cancel"]
|
||||
|
||||
def __init__(self, loop: urwid.MainLoop, player: Player) -> None:
|
||||
self.loop = loop
|
||||
self.player = player
|
||||
self.simulation = Simulation(player)
|
||||
|
||||
self.character_sheet_view = CharacterSheetView(player)
|
||||
self.task_view = TaskView(player)
|
||||
|
||||
super().__init__(
|
||||
[
|
||||
urwid.Columns(
|
||||
[
|
||||
urwid.Pile([self.character_sheet_view]),
|
||||
]
|
||||
),
|
||||
("pack", self.task_view),
|
||||
]
|
||||
)
|
||||
|
||||
self.tick()
|
||||
|
||||
def cancel(self) -> None:
|
||||
self._emit("cancel")
|
||||
|
||||
def tick(self) -> None:
|
||||
elapsed = 100 # TODO
|
||||
self.simulation.tick(elapsed)
|
||||
self.loop.set_alarm_in(0.1, lambda _loop, _user_data: self.tick())
|
||||
|
||||
def unhandled_input(self, key: str) -> bool:
|
||||
if key == "esc":
|
||||
self.cancel()
|
||||
return True
|
||||
|
||||
return False
|
||||
+10
-10
@@ -6,11 +6,11 @@ import urwid_readline
|
||||
|
||||
from pqcli.config import CLASSES, PRIME_STATS, RACES
|
||||
from pqcli.mechanic import StatsBuilder, create_player, generate_name
|
||||
from pqcli.ui.button import MenuButton
|
||||
from pqcli.ui.line_box import LineBox
|
||||
from pqcli.ui.custom_button import CustomButton
|
||||
from pqcli.ui.custom_line_box import CustomLineBox
|
||||
|
||||
|
||||
class StatsBox(LineBox):
|
||||
class StatsBox(CustomLineBox):
|
||||
def __init__(self) -> None:
|
||||
self.stats_builder = StatsBuilder()
|
||||
self.stats = self.stats_builder.roll()
|
||||
@@ -18,10 +18,10 @@ class StatsBox(LineBox):
|
||||
self.total_label = urwid.Text("0")
|
||||
self.update_values()
|
||||
|
||||
roll_button = MenuButton(
|
||||
roll_button = CustomButton(
|
||||
"Roll", hint="F5", on_press=self.on_roll_press
|
||||
)
|
||||
unroll_button = MenuButton(
|
||||
unroll_button = CustomButton(
|
||||
"Unroll", hint="F6", on_press=self.on_unroll_press
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ class StatsBox(LineBox):
|
||||
)
|
||||
|
||||
|
||||
class RaceBox(LineBox):
|
||||
class RaceBox(CustomLineBox):
|
||||
def __init__(self) -> None:
|
||||
self.race = random.choice(RACES)
|
||||
|
||||
@@ -92,7 +92,7 @@ class RaceBox(LineBox):
|
||||
self.race = user_data
|
||||
|
||||
|
||||
class ClassBox(LineBox):
|
||||
class ClassBox(CustomLineBox):
|
||||
def __init__(self) -> None:
|
||||
self.class_ = random.choice(CLASSES)
|
||||
|
||||
@@ -126,7 +126,7 @@ class NewGameView(urwid.Pile):
|
||||
self.char_name_edit = urwid_readline.ReadlineEdit(
|
||||
"Name: ", generate_name()
|
||||
)
|
||||
generate_char_name_btn = MenuButton(
|
||||
generate_char_name_btn = CustomButton(
|
||||
"Generate random name",
|
||||
hint="F7",
|
||||
on_press=self.on_generate_char_name_press,
|
||||
@@ -136,10 +136,10 @@ class NewGameView(urwid.Pile):
|
||||
urwid.Padding(
|
||||
urwid.Pile(
|
||||
[
|
||||
MenuButton(
|
||||
CustomButton(
|
||||
"Sold!", hint="F10", on_press=self.on_confirm_press
|
||||
),
|
||||
MenuButton(
|
||||
CustomButton(
|
||||
"Cancel", hint="Esc", on_press=self.on_cancel_press
|
||||
),
|
||||
]
|
||||
|
||||
@@ -3,7 +3,7 @@ import typing as T
|
||||
import urwid
|
||||
|
||||
from pqcli.roster import Roster
|
||||
from pqcli.ui.button import MenuButton
|
||||
from pqcli.ui.custom_button import CustomButton
|
||||
|
||||
|
||||
class RosterView(urwid.Filler):
|
||||
@@ -19,14 +19,14 @@ class RosterView(urwid.Filler):
|
||||
buttons.append(
|
||||
urwid.Columns(
|
||||
[
|
||||
MenuButton(
|
||||
CustomButton(
|
||||
label=player.name,
|
||||
on_press=self.on_resume_game_press,
|
||||
user_data=player_idx,
|
||||
),
|
||||
(
|
||||
10,
|
||||
MenuButton(
|
||||
CustomButton(
|
||||
label="Delete",
|
||||
on_press=self.on_delete_game_press,
|
||||
user_data=player_idx,
|
||||
@@ -37,7 +37,7 @@ class RosterView(urwid.Filler):
|
||||
)
|
||||
|
||||
buttons.append(
|
||||
MenuButton(
|
||||
CustomButton(
|
||||
label="Create a new character",
|
||||
hint="F1",
|
||||
on_press=self.on_new_game_press,
|
||||
@@ -45,7 +45,7 @@ class RosterView(urwid.Filler):
|
||||
)
|
||||
|
||||
buttons.append(
|
||||
MenuButton(label="Exit", hint="Esc", on_press=self.on_exit_press)
|
||||
CustomButton(label="Exit", hint="Esc", on_press=self.on_exit_press)
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
|
||||
Reference in New Issue
Block a user