bauiv1lib.gather.nearbytab

Defines the nearby tab in the gather UI.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Defines the nearby tab in the gather UI."""
  4
  5from __future__ import annotations
  6
  7import weakref
  8from typing import TYPE_CHECKING, override
  9
 10import bauiv1 as bui
 11import bascenev1 as bs
 12
 13from bauiv1lib.gather import GatherTab
 14
 15if TYPE_CHECKING:
 16    from typing import Any
 17
 18    from bauiv1lib.gather import GatherWindow
 19
 20
 21class NetScanner:
 22    """Class for scanning for nearby games (lan, bluetooth, etc)."""
 23
 24    def __init__(
 25        self,
 26        tab: GatherTab,
 27        scrollwidget: bui.Widget,
 28        tab_button: bui.Widget,
 29        width: float,
 30    ):
 31        self._tab = weakref.ref(tab)
 32        self._scrollwidget = scrollwidget
 33        self._tab_button = tab_button
 34        self._columnwidget = bui.columnwidget(
 35            parent=self._scrollwidget, border=2, margin=0, left_border=10
 36        )
 37        bui.widget(edit=self._columnwidget, up_widget=tab_button)
 38        self._width = width
 39        self._last_selected_host: dict[str, Any] | None = None
 40
 41        self._update_timer = bui.AppTimer(
 42            1.0, bui.WeakCall(self.update), repeat=True
 43        )
 44        # Go ahead and run a few *almost* immediately so we don't
 45        # have to wait a second.
 46        self.update()
 47        bui.apptimer(0.25, bui.WeakCall(self.update))
 48
 49    def __del__(self) -> None:
 50        bs.end_host_scanning()
 51
 52    def _on_select(self, host: dict[str, Any]) -> None:
 53        self._last_selected_host = host
 54
 55    def _on_activate(self, host: dict[str, Any]) -> None:
 56
 57        # Store UI location to return to when done.
 58        if bs.app.classic is not None:
 59            bs.app.classic.save_ui_state()
 60
 61        bs.connect_to_party(host['address'])
 62
 63    def update(self) -> None:
 64        """(internal)"""
 65
 66        # In case our UI was killed from under us.
 67        if not self._columnwidget:
 68            print(
 69                f'ERROR: NetScanner running without UI at time {bui.apptime()}.'
 70            )
 71            return
 72
 73        t_scale = 1.6
 74        for child in self._columnwidget.get_children():
 75            child.delete()
 76
 77        # Grab this now this since adding widgets will change it.
 78        last_selected_host = self._last_selected_host
 79        hosts = bs.host_scan_cycle()
 80        for i, host in enumerate(hosts):
 81            txt3 = bui.textwidget(
 82                parent=self._columnwidget,
 83                size=(self._width / t_scale, 30),
 84                selectable=True,
 85                color=(1, 1, 1),
 86                on_select_call=bui.Call(self._on_select, host),
 87                on_activate_call=bui.Call(self._on_activate, host),
 88                click_activate=True,
 89                text=host['display_string'],
 90                h_align='left',
 91                v_align='center',
 92                corner_scale=t_scale,
 93                maxwidth=(self._width / t_scale) * 0.93,
 94            )
 95            if host == last_selected_host:
 96                bui.containerwidget(
 97                    edit=self._columnwidget,
 98                    selected_child=txt3,
 99                    visible_child=txt3,
100                )
101            if i == 0:
102                bui.widget(edit=txt3, up_widget=self._tab_button)
103
104
105class NearbyGatherTab(GatherTab):
106    """The nearby tab in the gather UI"""
107
108    def __init__(self, window: GatherWindow) -> None:
109        super().__init__(window)
110        self._net_scanner: NetScanner | None = None
111        self._container: bui.Widget | None = None
112
113    @override
114    def on_activate(
115        self,
116        parent_widget: bui.Widget,
117        tab_button: bui.Widget,
118        region_width: float,
119        region_height: float,
120        region_left: float,
121        region_bottom: float,
122    ) -> bui.Widget:
123        # pylint: disable=too-many-positional-arguments
124        c_width = region_width
125        c_height = region_height - 20
126        sub_scroll_height = c_height - 85
127        sub_scroll_width = 650
128        self._container = bui.containerwidget(
129            parent=parent_widget,
130            position=(
131                region_left,
132                region_bottom + (region_height - c_height) * 0.5,
133            ),
134            size=(c_width, c_height),
135            background=False,
136            selection_loops_to_parent=True,
137        )
138        v = c_height - 30
139        bui.textwidget(
140            parent=self._container,
141            position=(c_width * 0.5, v - 3),
142            color=(0.6, 1.0, 0.6),
143            scale=1.3,
144            size=(0, 0),
145            maxwidth=c_width * 0.9,
146            h_align='center',
147            v_align='center',
148            text=bui.Lstr(
149                resource='gatherWindow.' 'localNetworkDescriptionText'
150            ),
151        )
152        v -= 15
153        v -= sub_scroll_height + 23
154        scrollw = bui.scrollwidget(
155            parent=self._container,
156            position=((region_width - sub_scroll_width) * 0.5, v),
157            size=(sub_scroll_width, sub_scroll_height),
158        )
159
160        self._net_scanner = NetScanner(
161            self, scrollw, tab_button, width=sub_scroll_width
162        )
163
164        bui.widget(edit=scrollw, autoselect=True, up_widget=tab_button)
165        return self._container
166
167    @override
168    def on_deactivate(self) -> None:
169        self._net_scanner = None
class NetScanner:
 22class NetScanner:
 23    """Class for scanning for nearby games (lan, bluetooth, etc)."""
 24
 25    def __init__(
 26        self,
 27        tab: GatherTab,
 28        scrollwidget: bui.Widget,
 29        tab_button: bui.Widget,
 30        width: float,
 31    ):
 32        self._tab = weakref.ref(tab)
 33        self._scrollwidget = scrollwidget
 34        self._tab_button = tab_button
 35        self._columnwidget = bui.columnwidget(
 36            parent=self._scrollwidget, border=2, margin=0, left_border=10
 37        )
 38        bui.widget(edit=self._columnwidget, up_widget=tab_button)
 39        self._width = width
 40        self._last_selected_host: dict[str, Any] | None = None
 41
 42        self._update_timer = bui.AppTimer(
 43            1.0, bui.WeakCall(self.update), repeat=True
 44        )
 45        # Go ahead and run a few *almost* immediately so we don't
 46        # have to wait a second.
 47        self.update()
 48        bui.apptimer(0.25, bui.WeakCall(self.update))
 49
 50    def __del__(self) -> None:
 51        bs.end_host_scanning()
 52
 53    def _on_select(self, host: dict[str, Any]) -> None:
 54        self._last_selected_host = host
 55
 56    def _on_activate(self, host: dict[str, Any]) -> None:
 57
 58        # Store UI location to return to when done.
 59        if bs.app.classic is not None:
 60            bs.app.classic.save_ui_state()
 61
 62        bs.connect_to_party(host['address'])
 63
 64    def update(self) -> None:
 65        """(internal)"""
 66
 67        # In case our UI was killed from under us.
 68        if not self._columnwidget:
 69            print(
 70                f'ERROR: NetScanner running without UI at time {bui.apptime()}.'
 71            )
 72            return
 73
 74        t_scale = 1.6
 75        for child in self._columnwidget.get_children():
 76            child.delete()
 77
 78        # Grab this now this since adding widgets will change it.
 79        last_selected_host = self._last_selected_host
 80        hosts = bs.host_scan_cycle()
 81        for i, host in enumerate(hosts):
 82            txt3 = bui.textwidget(
 83                parent=self._columnwidget,
 84                size=(self._width / t_scale, 30),
 85                selectable=True,
 86                color=(1, 1, 1),
 87                on_select_call=bui.Call(self._on_select, host),
 88                on_activate_call=bui.Call(self._on_activate, host),
 89                click_activate=True,
 90                text=host['display_string'],
 91                h_align='left',
 92                v_align='center',
 93                corner_scale=t_scale,
 94                maxwidth=(self._width / t_scale) * 0.93,
 95            )
 96            if host == last_selected_host:
 97                bui.containerwidget(
 98                    edit=self._columnwidget,
 99                    selected_child=txt3,
100                    visible_child=txt3,
101                )
102            if i == 0:
103                bui.widget(edit=txt3, up_widget=self._tab_button)

Class for scanning for nearby games (lan, bluetooth, etc).

NetScanner( tab: bauiv1lib.gather.GatherTab, scrollwidget: _bauiv1.Widget, tab_button: _bauiv1.Widget, width: float)
25    def __init__(
26        self,
27        tab: GatherTab,
28        scrollwidget: bui.Widget,
29        tab_button: bui.Widget,
30        width: float,
31    ):
32        self._tab = weakref.ref(tab)
33        self._scrollwidget = scrollwidget
34        self._tab_button = tab_button
35        self._columnwidget = bui.columnwidget(
36            parent=self._scrollwidget, border=2, margin=0, left_border=10
37        )
38        bui.widget(edit=self._columnwidget, up_widget=tab_button)
39        self._width = width
40        self._last_selected_host: dict[str, Any] | None = None
41
42        self._update_timer = bui.AppTimer(
43            1.0, bui.WeakCall(self.update), repeat=True
44        )
45        # Go ahead and run a few *almost* immediately so we don't
46        # have to wait a second.
47        self.update()
48        bui.apptimer(0.25, bui.WeakCall(self.update))
class NearbyGatherTab(bauiv1lib.gather.GatherTab):
106class NearbyGatherTab(GatherTab):
107    """The nearby tab in the gather UI"""
108
109    def __init__(self, window: GatherWindow) -> None:
110        super().__init__(window)
111        self._net_scanner: NetScanner | None = None
112        self._container: bui.Widget | None = None
113
114    @override
115    def on_activate(
116        self,
117        parent_widget: bui.Widget,
118        tab_button: bui.Widget,
119        region_width: float,
120        region_height: float,
121        region_left: float,
122        region_bottom: float,
123    ) -> bui.Widget:
124        # pylint: disable=too-many-positional-arguments
125        c_width = region_width
126        c_height = region_height - 20
127        sub_scroll_height = c_height - 85
128        sub_scroll_width = 650
129        self._container = bui.containerwidget(
130            parent=parent_widget,
131            position=(
132                region_left,
133                region_bottom + (region_height - c_height) * 0.5,
134            ),
135            size=(c_width, c_height),
136            background=False,
137            selection_loops_to_parent=True,
138        )
139        v = c_height - 30
140        bui.textwidget(
141            parent=self._container,
142            position=(c_width * 0.5, v - 3),
143            color=(0.6, 1.0, 0.6),
144            scale=1.3,
145            size=(0, 0),
146            maxwidth=c_width * 0.9,
147            h_align='center',
148            v_align='center',
149            text=bui.Lstr(
150                resource='gatherWindow.' 'localNetworkDescriptionText'
151            ),
152        )
153        v -= 15
154        v -= sub_scroll_height + 23
155        scrollw = bui.scrollwidget(
156            parent=self._container,
157            position=((region_width - sub_scroll_width) * 0.5, v),
158            size=(sub_scroll_width, sub_scroll_height),
159        )
160
161        self._net_scanner = NetScanner(
162            self, scrollw, tab_button, width=sub_scroll_width
163        )
164
165        bui.widget(edit=scrollw, autoselect=True, up_widget=tab_button)
166        return self._container
167
168    @override
169    def on_deactivate(self) -> None:
170        self._net_scanner = None

The nearby tab in the gather UI

NearbyGatherTab(window: bauiv1lib.gather.GatherWindow)
109    def __init__(self, window: GatherWindow) -> None:
110        super().__init__(window)
111        self._net_scanner: NetScanner | None = None
112        self._container: bui.Widget | None = None
@override
def on_activate( self, parent_widget: _bauiv1.Widget, tab_button: _bauiv1.Widget, region_width: float, region_height: float, region_left: float, region_bottom: float) -> _bauiv1.Widget:
114    @override
115    def on_activate(
116        self,
117        parent_widget: bui.Widget,
118        tab_button: bui.Widget,
119        region_width: float,
120        region_height: float,
121        region_left: float,
122        region_bottom: float,
123    ) -> bui.Widget:
124        # pylint: disable=too-many-positional-arguments
125        c_width = region_width
126        c_height = region_height - 20
127        sub_scroll_height = c_height - 85
128        sub_scroll_width = 650
129        self._container = bui.containerwidget(
130            parent=parent_widget,
131            position=(
132                region_left,
133                region_bottom + (region_height - c_height) * 0.5,
134            ),
135            size=(c_width, c_height),
136            background=False,
137            selection_loops_to_parent=True,
138        )
139        v = c_height - 30
140        bui.textwidget(
141            parent=self._container,
142            position=(c_width * 0.5, v - 3),
143            color=(0.6, 1.0, 0.6),
144            scale=1.3,
145            size=(0, 0),
146            maxwidth=c_width * 0.9,
147            h_align='center',
148            v_align='center',
149            text=bui.Lstr(
150                resource='gatherWindow.' 'localNetworkDescriptionText'
151            ),
152        )
153        v -= 15
154        v -= sub_scroll_height + 23
155        scrollw = bui.scrollwidget(
156            parent=self._container,
157            position=((region_width - sub_scroll_width) * 0.5, v),
158            size=(sub_scroll_width, sub_scroll_height),
159        )
160
161        self._net_scanner = NetScanner(
162            self, scrollw, tab_button, width=sub_scroll_width
163        )
164
165        bui.widget(edit=scrollw, autoselect=True, up_widget=tab_button)
166        return self._container

Called when the tab becomes the active one.

The tab should create and return a container widget covering the specified region.

@override
def on_deactivate(self) -> None:
168    @override
169    def on_deactivate(self) -> None:
170        self._net_scanner = None

Called when the tab will no longer be the active one.