mousefox.app.lobbyframe
Home of LobbyFrame
.
1"""Home of `LobbyFrame`.""" 2 3from typing import Optional 4import arrow 5import kvex as kx 6import pgnet 7 8 9LINE_WIDGET_HEIGHT = 40 10AUTO_REFRESH_INTERVAL = 1 11 12 13class LobbyFrame(kx.XAnchor): 14 """Widget for interacting with the server lobby.""" 15 16 _conpath = "client.user.lobby" 17 18 def __init__(self, client: pgnet.Client): 19 """Initialize the class.""" 20 super().__init__() 21 self._client = client 22 self._next_dir_refresh: arrow.Arrow = arrow.now() 23 self.game_dir = dict() 24 self._make_widgets() 25 self.app.controller.bind(f"{self._conpath}.focus", self._focus_list) 26 self.app.controller.bind(f"{self._conpath}.focus_create", self._focus_create) 27 self.app.controller.bind(f"{self._conpath}.focus_list", self._focus_list) 28 self.app.controller.set_active_callback(self._conpath, self._focus_list) 29 30 def update(self): 31 """Priodically refresh game directory.""" 32 if not self.app.controller.is_active(self._conpath): 33 return 34 if not self._client.connected: 35 return 36 if arrow.now() < self._next_dir_refresh: 37 return 38 self._next_dir_refresh = arrow.now().shift(seconds=AUTO_REFRESH_INTERVAL) 39 self._refresh_games() 40 41 def on_parent(self, w, parent): 42 """Refresh when shown.""" 43 if parent: 44 self._refresh_games() 45 self._show_game() 46 self.games_list.focus = True 47 48 def _make_widgets(self): 49 # Game list 50 with self.app.subtheme_context("secondary"): 51 title = kx.fwrap(kx.XLabel(text="[b]Server lobby[/b]", font_size="18sp")) 52 title.set_size(y=LINE_WIDGET_HEIGHT) 53 self.games_list = kx.XList( 54 items=[""], 55 selection_color=(1, 1, 1), 56 item_height=LINE_WIDGET_HEIGHT, 57 ) 58 self.games_list.bind( 59 on_invoke=self._on_game_invoke, 60 selection=self._show_game, 61 ) 62 list_box = kx.XBox(orientation="vertical") 63 list_box.add_widgets(title, self.games_list) 64 list_frame = kx.pwrap(kx.fpwrap(list_box)) 65 66 # Game info 67 join_iwidgets = dict(password=kx.XInputPanelWidget("Password", "password")) 68 with self.app.subtheme_context("secondary"): 69 info_title = kx.XLabel(text="[b]Game Details[/b]") 70 info_title.set_size(y=LINE_WIDGET_HEIGHT) 71 self.game_info_label = kx.XLabel(halign="left", valign="top") 72 self.join_panel = kx.XInputPanel( 73 join_iwidgets, 74 reset_text="", 75 invoke_text="Join", 76 ) 77 self.join_panel.bind(on_invoke=self._join_game) 78 self.join_panel.set_size(y=LINE_WIDGET_HEIGHT * 2) 79 info_panel = kx.XBox(orientation="vertical") 80 info_panel.add_widgets( 81 info_title, 82 self.game_info_label, 83 self.join_panel, 84 ) 85 right_box = kx.XBox(orientation="vertical") 86 right_box.add_widget(kx.pwrap(info_panel)) 87 right_frame = kx.fwrap(right_box) 88 89 # Create game 90 pwidgets = dict( 91 name=kx.XInputPanelWidget("Name"), 92 password=kx.XInputPanelWidget("Password", "password"), 93 ) 94 with self.app.subtheme_context("accent"): 95 create_title = kx.XLabel(text="[b]Create new game[/b]") 96 create_title.set_size(y=LINE_WIDGET_HEIGHT) 97 self.create_panel = kx.XInputPanel( 98 pwidgets, 99 invoke_text="Create game", 100 reset_text="", 101 ) 102 self.create_panel.bind(on_invoke=self._create_game) 103 self.create_panel.set_size(y="200dp") 104 create_box = kx.XBox(orientation="vertical") 105 create_box.add_widgets(create_title, self.create_panel) 106 create_frame = kx.pwrap(kx.fpwrap(create_box)) 107 create_frame.set_size(y=self.create_panel.height + create_title.height) 108 right_box.add_widget(create_frame) 109 110 # Assemble 111 main_frame = kx.XBox() 112 main_frame.add_widgets(list_frame, kx.pwrap(right_frame)) 113 self.add_widget(main_frame) 114 115 def _create_game(self, *args): 116 values = self.create_panel.get_values() 117 name = values["name"] 118 password = values["password"] 119 self._client.create_game( 120 name, 121 password=password, 122 callback=self.app.feedback_response, 123 ) 124 125 def _join_game(self, *args, name: Optional[str] = None): 126 name = name or self.games_list.items[self.games_list.selection] 127 password = None 128 game = self.game_dir.get(name) 129 if not game: 130 return 131 if game.get("password_protected"): 132 password = self.join_panel.get_value("password") 133 self._client.join_game( 134 name, 135 password=password, 136 callback=self.app.feedback_response, 137 ) 138 139 def _refresh_games(self, *args): 140 self._client.get_game_dir(self._on_game_dir_response) 141 142 def _on_game_dir_response(self, game_dir_response: pgnet.Response): 143 self.game_dir = game_dir_response.payload.get("games") or dict() 144 games = sorted(self.game_dir.keys()) or [""] 145 self.games_list.items = games 146 self._show_game() 147 148 def _on_game_invoke(self, w, index: int, label: str): 149 self._join_game(name=label) 150 151 def _show_game(self, *args, name: str = ""): 152 name = self.games_list.items[self.games_list.selection] 153 game = self.game_dir.get(name) 154 if not game: 155 self.game_info_label.text = "No games found. Create a new game." 156 self.join_panel.set_showing("password", False) 157 return 158 users = game.get("users") 159 passprot = game.get("password_protected") 160 password = "[i]Password protected.[/i]" if passprot else "" 161 ginfo = game.get("info") 162 if ginfo: 163 ginfo = kx.escape_markup(ginfo) 164 else: 165 ginfo = "[i]No game information available.[/i]" 166 text = "\n\n".join([ 167 f"[b]{name}[/b]", 168 f"{users} users in game.", 169 password, 170 "[u]Game info[/u]", 171 ginfo, 172 ]) 173 self.game_info_label.text = text 174 self.join_panel.set_showing("password", passprot) 175 176 def _focus_create(self): 177 self.create_panel.set_focus("name") 178 179 def _focus_list(self): 180 self.games_list.focus = True 181 182 set_focus = _focus_list
14class LobbyFrame(kx.XAnchor): 15 """Widget for interacting with the server lobby.""" 16 17 _conpath = "client.user.lobby" 18 19 def __init__(self, client: pgnet.Client): 20 """Initialize the class.""" 21 super().__init__() 22 self._client = client 23 self._next_dir_refresh: arrow.Arrow = arrow.now() 24 self.game_dir = dict() 25 self._make_widgets() 26 self.app.controller.bind(f"{self._conpath}.focus", self._focus_list) 27 self.app.controller.bind(f"{self._conpath}.focus_create", self._focus_create) 28 self.app.controller.bind(f"{self._conpath}.focus_list", self._focus_list) 29 self.app.controller.set_active_callback(self._conpath, self._focus_list) 30 31 def update(self): 32 """Priodically refresh game directory.""" 33 if not self.app.controller.is_active(self._conpath): 34 return 35 if not self._client.connected: 36 return 37 if arrow.now() < self._next_dir_refresh: 38 return 39 self._next_dir_refresh = arrow.now().shift(seconds=AUTO_REFRESH_INTERVAL) 40 self._refresh_games() 41 42 def on_parent(self, w, parent): 43 """Refresh when shown.""" 44 if parent: 45 self._refresh_games() 46 self._show_game() 47 self.games_list.focus = True 48 49 def _make_widgets(self): 50 # Game list 51 with self.app.subtheme_context("secondary"): 52 title = kx.fwrap(kx.XLabel(text="[b]Server lobby[/b]", font_size="18sp")) 53 title.set_size(y=LINE_WIDGET_HEIGHT) 54 self.games_list = kx.XList( 55 items=[""], 56 selection_color=(1, 1, 1), 57 item_height=LINE_WIDGET_HEIGHT, 58 ) 59 self.games_list.bind( 60 on_invoke=self._on_game_invoke, 61 selection=self._show_game, 62 ) 63 list_box = kx.XBox(orientation="vertical") 64 list_box.add_widgets(title, self.games_list) 65 list_frame = kx.pwrap(kx.fpwrap(list_box)) 66 67 # Game info 68 join_iwidgets = dict(password=kx.XInputPanelWidget("Password", "password")) 69 with self.app.subtheme_context("secondary"): 70 info_title = kx.XLabel(text="[b]Game Details[/b]") 71 info_title.set_size(y=LINE_WIDGET_HEIGHT) 72 self.game_info_label = kx.XLabel(halign="left", valign="top") 73 self.join_panel = kx.XInputPanel( 74 join_iwidgets, 75 reset_text="", 76 invoke_text="Join", 77 ) 78 self.join_panel.bind(on_invoke=self._join_game) 79 self.join_panel.set_size(y=LINE_WIDGET_HEIGHT * 2) 80 info_panel = kx.XBox(orientation="vertical") 81 info_panel.add_widgets( 82 info_title, 83 self.game_info_label, 84 self.join_panel, 85 ) 86 right_box = kx.XBox(orientation="vertical") 87 right_box.add_widget(kx.pwrap(info_panel)) 88 right_frame = kx.fwrap(right_box) 89 90 # Create game 91 pwidgets = dict( 92 name=kx.XInputPanelWidget("Name"), 93 password=kx.XInputPanelWidget("Password", "password"), 94 ) 95 with self.app.subtheme_context("accent"): 96 create_title = kx.XLabel(text="[b]Create new game[/b]") 97 create_title.set_size(y=LINE_WIDGET_HEIGHT) 98 self.create_panel = kx.XInputPanel( 99 pwidgets, 100 invoke_text="Create game", 101 reset_text="", 102 ) 103 self.create_panel.bind(on_invoke=self._create_game) 104 self.create_panel.set_size(y="200dp") 105 create_box = kx.XBox(orientation="vertical") 106 create_box.add_widgets(create_title, self.create_panel) 107 create_frame = kx.pwrap(kx.fpwrap(create_box)) 108 create_frame.set_size(y=self.create_panel.height + create_title.height) 109 right_box.add_widget(create_frame) 110 111 # Assemble 112 main_frame = kx.XBox() 113 main_frame.add_widgets(list_frame, kx.pwrap(right_frame)) 114 self.add_widget(main_frame) 115 116 def _create_game(self, *args): 117 values = self.create_panel.get_values() 118 name = values["name"] 119 password = values["password"] 120 self._client.create_game( 121 name, 122 password=password, 123 callback=self.app.feedback_response, 124 ) 125 126 def _join_game(self, *args, name: Optional[str] = None): 127 name = name or self.games_list.items[self.games_list.selection] 128 password = None 129 game = self.game_dir.get(name) 130 if not game: 131 return 132 if game.get("password_protected"): 133 password = self.join_panel.get_value("password") 134 self._client.join_game( 135 name, 136 password=password, 137 callback=self.app.feedback_response, 138 ) 139 140 def _refresh_games(self, *args): 141 self._client.get_game_dir(self._on_game_dir_response) 142 143 def _on_game_dir_response(self, game_dir_response: pgnet.Response): 144 self.game_dir = game_dir_response.payload.get("games") or dict() 145 games = sorted(self.game_dir.keys()) or [""] 146 self.games_list.items = games 147 self._show_game() 148 149 def _on_game_invoke(self, w, index: int, label: str): 150 self._join_game(name=label) 151 152 def _show_game(self, *args, name: str = ""): 153 name = self.games_list.items[self.games_list.selection] 154 game = self.game_dir.get(name) 155 if not game: 156 self.game_info_label.text = "No games found. Create a new game." 157 self.join_panel.set_showing("password", False) 158 return 159 users = game.get("users") 160 passprot = game.get("password_protected") 161 password = "[i]Password protected.[/i]" if passprot else "" 162 ginfo = game.get("info") 163 if ginfo: 164 ginfo = kx.escape_markup(ginfo) 165 else: 166 ginfo = "[i]No game information available.[/i]" 167 text = "\n\n".join([ 168 f"[b]{name}[/b]", 169 f"{users} users in game.", 170 password, 171 "[u]Game info[/u]", 172 ginfo, 173 ]) 174 self.game_info_label.text = text 175 self.join_panel.set_showing("password", passprot) 176 177 def _focus_create(self): 178 self.create_panel.set_focus("name") 179 180 def _focus_list(self): 181 self.games_list.focus = True 182 183 set_focus = _focus_list
Widget for interacting with the server lobby.
LobbyFrame(client: pgnet.client.Client)
19 def __init__(self, client: pgnet.Client): 20 """Initialize the class.""" 21 super().__init__() 22 self._client = client 23 self._next_dir_refresh: arrow.Arrow = arrow.now() 24 self.game_dir = dict() 25 self._make_widgets() 26 self.app.controller.bind(f"{self._conpath}.focus", self._focus_list) 27 self.app.controller.bind(f"{self._conpath}.focus_create", self._focus_create) 28 self.app.controller.bind(f"{self._conpath}.focus_list", self._focus_list) 29 self.app.controller.set_active_callback(self._conpath, self._focus_list)
Initialize the class.
def
update(self):
31 def update(self): 32 """Priodically refresh game directory.""" 33 if not self.app.controller.is_active(self._conpath): 34 return 35 if not self._client.connected: 36 return 37 if arrow.now() < self._next_dir_refresh: 38 return 39 self._next_dir_refresh = arrow.now().shift(seconds=AUTO_REFRESH_INTERVAL) 40 self._refresh_games()
Priodically refresh game directory.
def
on_parent(self, w, parent):
42 def on_parent(self, w, parent): 43 """Refresh when shown.""" 44 if parent: 45 self._refresh_games() 46 self._show_game() 47 self.games_list.focus = True
Refresh when shown.
Inherited Members
- kivy.uix.anchorlayout.AnchorLayout
- padding
- anchor_x
- anchor_y
- do_layout
- kivy.uix.layout.Layout
- add_widget
- remove_widget
- layout_hint_with_bounds
- kivy.uix.widget.Widget
- proxy_ref
- apply_class_lang_rules
- collide_point
- collide_widget
- on_motion
- on_touch_down
- on_touch_move
- on_touch_up
- on_kv_post
- clear_widgets
- register_for_motion_event
- unregister_for_motion_event
- export_to_png
- export_as_image
- get_root_window
- get_parent_window
- walk
- walk_reverse
- to_widget
- to_window
- to_parent
- to_local
- get_window_matrix
- x
- y
- width
- height
- pos
- size
- get_right
- set_right
- right
- get_top
- set_top
- top
- get_center_x
- set_center_x
- center_x
- get_center_y
- set_center_y
- center_y
- center
- cls
- children
- parent
- size_hint_x
- size_hint_y
- size_hint
- pos_hint
- size_hint_min_x
- size_hint_min_y
- size_hint_min
- size_hint_max_x
- size_hint_max_y
- size_hint_max
- ids
- opacity
- on_opacity
- canvas
- get_disabled
- set_disabled
- inc_disabled
- dec_disabled
- disabled
- motion_filter
- kivy._event.EventDispatcher
- register_event_type
- unregister_event_types
- unregister_event_type
- is_event_type
- bind
- unbind
- fbind
- funbind
- unbind_uid
- get_property_observers
- events
- dispatch
- dispatch_generic
- dispatch_children
- setter
- getter
- property
- properties
- create_property
- apply_property