We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Inconsistent behaviour with toga.Selection value attribute between Windows and Android
### Describe the bug

On Windows, when a selection widget is created with a list containing an empty string (eg: toga.Selection(items=['1','a','','4']) ), the widget returns '' for the "value" attribute.

On Android, the selection's "value" attribute is set to None if the selection item is an empty string.

I don't have MacOS, iOS, or Linux devices so I don't know what happens there.

### Steps to reproduce

0. Create Beeware Project
1. Go to the app.py file
2. Create a list "list_1" containing an empty string
3. Create the base app class with the startup function and setup main box + window
4. In the startup function, create a selection with the items being that of list_1. Store it as a class attribute for future access.
5. Define a class function that outputs the selection value via print or info_dialog.
6. Create Button to call the output function
7. Add Selector & Button to main box
9. Compile the code for both Windows and Android & launch them.
11. Select the empty item of the selector
12. Press the button
13. Watch as the devices disagree on the value.

### Expected behavior

I would expect the selector value attribute to be an empty string as that was what the item was, and that is what the selector widget understands when values are written to it.

### Screenshots

The source code I used:
```
"""
Testing Crashes
"""
import toga
class TestLab(toga.App):
    def startup(self):
        main_box=toga.Box()
        self.select=toga.Selection(items=['A','B','0','','1','+','-'])
        main_box.add(self.select)
        main_box.add(toga.Button('Get',on_press=self.valuedump))
        self.main_window=toga.MainWindow(title=self.formal_name)
        self.main_window.content=main_box
        self.main_window.show()
    async def valuedump(self,widget):
        q=self.select.value
        print('GET',q,type(q))
        self.main_window.info_dialog('Selection Value',f'Value: "{q}"\n Type: {type(q)}')
def main():return TestLab()
```

On Windows:

![A_val](https://user-images.githubusercontent.com/113656324/209735390-f7e31b6e-c8d7-4cf3-9d51-2f47a69c7a62.png)
![sel_vals](https://user-images.githubusercontent.com/113656324/209735397-60442c7c-28dd-413c-a7c4-bae10003363e.png)
![Null_val](https://user-images.githubusercontent.com/113656324/209735402-9cdf611c-e512-4a52-bc9b-28ea193dae86.png)

On Android:

![Screenshot_20221227-171610](https://user-images.githubusercontent.com/113656324/209735964-7f7ae864-d2ce-4203-99b5-87dddc5f8938.png)
![Screenshot_20221227-171624](https://user-images.githubusercontent.com/113656324/209735970-d459f355-0390-490f-ba56-1adee2c6eef9.png)
![Screenshot_20221227-171635](https://user-images.githubusercontent.com/113656324/209735971-84bca7d5-5590-454f-9f6f-effe244a4126.png)


### Environment


Windows 8.1 / Android 11
- Python version: 3.10.0
  - Briefcase: 3.11
  - Toga: 0.3.0.dev8


### Logs

Windows:
[briefcase.2022_12_27-17_09_47.run.log](https://github.com/beeware/toga/files/10311153/briefcase.2022_12_27-17_09_47.run.log)

Android:
[briefcase.2022_12_27-17_17_14.run.log](https://github.com/beeware/toga/files/10311154/briefcase.2022_12_27-17_17_14.run.log)


### Additional context

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cocoa/src/toga_cocoa/widgets/selection.py`
Content:
```
1 from travertino.size import at_least
2 
3 from toga_cocoa.libs import SEL, NSPopUpButton, objc_method, objc_property
4 
5 from .base import Widget
6 
7 
8 class TogaPopupButton(NSPopUpButton):
9     interface = objc_property(object, weak=True)
10     impl = objc_property(object, weak=True)
11 
12     @objc_method
13     def onSelect_(self, obj) -> None:
14         if self.interface.on_select:
15             self.interface.on_select(self.interface)
16 
17 
18 class Selection(Widget):
19     def create(self):
20         self.native = TogaPopupButton.alloc().init()
21         self.native.interface = self.interface
22         self.native.impl = self
23 
24         self.native.target = self.native
25         self.native.action = SEL("onSelect:")
26 
27         self.add_constraints()
28 
29     def rehint(self):
30         content_size = self.native.intrinsicContentSize()
31         self.interface.intrinsic.height = content_size.height
32         self.interface.intrinsic.width = at_least(
33             max(self.interface._MIN_WIDTH, content_size.width)
34         )
35 
36     def remove_all_items(self):
37         self.native.removeAllItems()
38 
39     def add_item(self, item):
40         self.native.addItemWithTitle(item)
41 
42     def select_item(self, item):
43         self.native.selectItemWithTitle(item)
44 
45     def get_selected_item(self):
46         return str(self.native.titleOfSelectedItem)
47 
48     def set_on_select(self, handler):
49         pass
50
```

Path: `iOS/src/toga_iOS/widgets/selection.py`
Content:
```
1 from rubicon.objc import CGSize, objc_method, objc_property
2 from travertino.size import at_least
3 
4 from toga_iOS.libs import UIColor, UIPickerView, UITextBorderStyle, UITextField
5 from toga_iOS.widgets.base import Widget
6 
7 
8 class TogaPickerView(UIPickerView):
9     interface = objc_property(object, weak=True)
10     impl = objc_property(object, weak=True)
11 
12     @objc_method
13     def numberOfComponentsInPickerView_(self, pickerView) -> int:
14         return 1
15 
16     @objc_method
17     def pickerView_numberOfRowsInComponent_(self, pickerView, component: int) -> int:
18         return len(self.interface.items)
19 
20     @objc_method
21     def pickerView_titleForRow_forComponent_(
22         self, pickerView, row: int, component: int
23     ):
24         return str(self.interface.items[row])
25 
26     @objc_method
27     def pickerView_didSelectRow_inComponent_(
28         self, pickerView, row: int, component: int
29     ):
30         self.native.text = self.interface.items[row]
31         if self.interface.on_select:
32             self.interface.on_select(self.interface)
33 
34 
35 class Selection(Widget):
36     def create(self):
37         self.native = UITextField.alloc().init()
38         self.native.interface = self.interface
39         self.native.impl = self
40         self.native.tintColor = UIColor.clearColor
41         self.native.borderStyle = UITextBorderStyle.RoundedRect
42 
43         self.picker = TogaPickerView.alloc().init()
44         self.picker.interface = self.interface
45         self.picker.native = self.native
46         self.picker.delegate = self.picker
47         self.picker.dataSource = self.picker
48 
49         self.native.inputView = self.picker
50         self.native.delegate = self.picker
51 
52         self.add_constraints()
53 
54     def rehint(self):
55         # Height of a text input is known.
56         fitting_size = self.native.systemLayoutSizeFittingSize(CGSize(0, 0))
57         self.interface.intrinsic.width = at_least(fitting_size.width)
58         self.interface.intrinsic.height = fitting_size.height
59 
60     def remove_all_items(self):
61         # No special handling required
62         pass
63 
64     def add_item(self, item):
65         if not self.native.text:
66             self.native.text = item
67 
68     def select_item(self, item):
69         self.interface.factory.not_implemented("Selection.select_item()")
70 
71     def get_selected_item(self):
72         return self.interface.items[self.picker.selectedRowInComponent(0)]
73 
74     def set_on_select(self, handler):
75         # No special handling required
76         pass
77
```

Path: `examples/selection/selection/app.py`
Content:
```
1 import toga
2 from toga.constants import COLUMN, ROW
3 from toga.style import Pack
4 
5 
6 class SelectionApp(toga.App):
7     CARBON = "Carbon"
8     YTTERBIUM = "Ytterbium"
9     THULIUM = "Thulium"
10     OPTIONS = [CARBON, YTTERBIUM, THULIUM]
11 
12     def startup(self):
13         # Main window of the application with title and size
14         self.main_window = toga.MainWindow(title=self.name, size=(640, 400))
15 
16         # set up common styles
17         label_style = Pack(flex=1, padding_right=24)
18         box_style = Pack(direction=ROW, padding=10)
19 
20         # Add the content on the main window
21         self.selection = toga.Selection(items=self.OPTIONS)
22 
23         self.main_window.content = toga.Box(
24             children=[
25                 toga.Box(
26                     style=box_style,
27                     children=[
28                         toga.Label("Select an element", style=label_style),
29                         self.selection,
30                     ],
31                 ),
32                 toga.Box(
33                     style=box_style,
34                     children=[
35                         toga.Label(
36                             "Selection value can be set by property setter",
37                             style=label_style,
38                         ),
39                         toga.Button(text="Set Carbon", on_press=self.set_carbon),
40                         toga.Button(text="Set Ytterbium", on_press=self.set_ytterbium),
41                         toga.Button(text="Set THULIUM", on_press=self.set_thulium),
42                     ],
43                 ),
44                 toga.Box(
45                     style=box_style,
46                     children=[
47                         toga.Label(
48                             "use the 'on_select' callback to respond to changes",
49                             style=label_style,
50                         ),
51                         toga.Selection(
52                             on_select=self.my_on_select,
53                             items=["Dubnium", "Holmium", "Zirconium"],
54                         ),
55                     ],
56                 ),
57                 toga.Box(
58                     style=box_style,
59                     children=[
60                         toga.Label(
61                             "Long lists of items should scroll", style=label_style
62                         ),
63                         toga.Selection(items=dir(toga)),
64                     ],
65                 ),
66                 toga.Box(
67                     style=box_style,
68                     children=[
69                         toga.Label("use some style!", style=label_style),
70                         toga.Selection(
71                             style=Pack(width=200, padding=24),
72                             items=["Curium", "Titanium", "Copernicium"],
73                         ),
74                     ],
75                 ),
76                 toga.Box(
77                     style=box_style,
78                     children=[
79                         toga.Label(
80                             "Selection widgets can be disabled", style=label_style
81                         ),
82                         toga.Selection(
83                             items=[
84                                 "Helium",
85                                 "Neon",
86                                 "Argon",
87                                 "Krypton",
88                                 "Xenon",
89                                 "Radon",
90                                 "Oganesson",
91                             ],
92                             enabled=False,
93                         ),
94                     ],
95                 ),
96             ],
97             style=Pack(direction=COLUMN, padding=24),
98         )
99 
100         self.main_window.show()
101 
102     def set_carbon(self, widget):
103         self.selection.value = self.CARBON
104 
105     def set_ytterbium(self, widget):
106         self.selection.value = self.YTTERBIUM
107 
108     def set_thulium(self, widget):
109         self.selection.value = self.THULIUM
110 
111     def my_on_select(self, selection):
112         # get the current value of the slider with `selection.value`
113 
114         print(f"The selection widget changed to {selection.value}")
115 
116 
117 def main():
118     # App name and namespace
119     return SelectionApp("Selection", "org.beeware.selection")
120 
121 
122 if __name__ == "__main__":
123     app = main()
124     app.main_loop()
125
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cocoa/src/toga_cocoa/widgets/selection.py b/cocoa/src/toga_cocoa/widgets/selection.py
--- a/cocoa/src/toga_cocoa/widgets/selection.py
+++ b/cocoa/src/toga_cocoa/widgets/selection.py
@@ -43,7 +43,9 @@
         self.native.selectItemWithTitle(item)
 
     def get_selected_item(self):
-        return str(self.native.titleOfSelectedItem)
+        selected = self.native.titleOfSelectedItem
+        if selected:
+            return str(selected)
 
     def set_on_select(self, handler):
         pass
diff --git a/examples/selection/selection/app.py b/examples/selection/selection/app.py
--- a/examples/selection/selection/app.py
+++ b/examples/selection/selection/app.py
@@ -19,6 +19,9 @@
 
         # Add the content on the main window
         self.selection = toga.Selection(items=self.OPTIONS)
+        self.empty_selection = toga.Selection()
+
+        self.report_label = toga.Label("", style=label_style)
 
         self.main_window.content = toga.Box(
             children=[
@@ -29,6 +32,22 @@
                         self.selection,
                     ],
                 ),
+                toga.Box(
+                    style=box_style,
+                    children=[
+                        toga.Label("Empty selection", style=label_style),
+                        self.empty_selection,
+                    ],
+                ),
+                toga.Box(
+                    style=box_style,
+                    children=[
+                        toga.Button(
+                            "Report on selection", on_press=self.report_selection
+                        ),
+                        self.report_label,
+                    ],
+                ),
                 toga.Box(
                     style=box_style,
                     children=[
@@ -66,7 +85,7 @@
                 toga.Box(
                     style=box_style,
                     children=[
-                        toga.Label("use some style!", style=label_style),
+                        toga.Label("Use some style!", style=label_style),
                         toga.Selection(
                             style=Pack(width=200, padding=24),
                             items=["Curium", "Titanium", "Copernicium"],
@@ -113,6 +132,11 @@
 
         print(f"The selection widget changed to {selection.value}")
 
+    def report_selection(self, widget):
+        self.report_label.text = (
+            f"Element: {self.selection.value!r}; Empty: {self.empty_selection.value!r}"
+        )
+
 
 def main():
     # App name and namespace
diff --git a/iOS/src/toga_iOS/widgets/selection.py b/iOS/src/toga_iOS/widgets/selection.py
--- a/iOS/src/toga_iOS/widgets/selection.py
+++ b/iOS/src/toga_iOS/widgets/selection.py
@@ -69,7 +69,10 @@
         self.interface.factory.not_implemented("Selection.select_item()")
 
     def get_selected_item(self):
-        return self.interface.items[self.picker.selectedRowInComponent(0)]
+        try:
+            return self.interface.items[self.picker.selectedRowInComponent(0)]
+        except IndexError:
+            return None
 
     def set_on_select(self, handler):
         # No special handling required

{"golden_diff": "diff --git a/cocoa/src/toga_cocoa/widgets/selection.py b/cocoa/src/toga_cocoa/widgets/selection.py\n--- a/cocoa/src/toga_cocoa/widgets/selection.py\n+++ b/cocoa/src/toga_cocoa/widgets/selection.py\n@@ -43,7 +43,9 @@\n         self.native.selectItemWithTitle(item)\n \n     def get_selected_item(self):\n-        return str(self.native.titleOfSelectedItem)\n+        selected = self.native.titleOfSelectedItem\n+        if selected:\n+            return str(selected)\n \n     def set_on_select(self, handler):\n         pass\ndiff --git a/examples/selection/selection/app.py b/examples/selection/selection/app.py\n--- a/examples/selection/selection/app.py\n+++ b/examples/selection/selection/app.py\n@@ -19,6 +19,9 @@\n \n         # Add the content on the main window\n         self.selection = toga.Selection(items=self.OPTIONS)\n+        self.empty_selection = toga.Selection()\n+\n+        self.report_label = toga.Label(\"\", style=label_style)\n \n         self.main_window.content = toga.Box(\n             children=[\n@@ -29,6 +32,22 @@\n                         self.selection,\n                     ],\n                 ),\n+                toga.Box(\n+                    style=box_style,\n+                    children=[\n+                        toga.Label(\"Empty selection\", style=label_style),\n+                        self.empty_selection,\n+                    ],\n+                ),\n+                toga.Box(\n+                    style=box_style,\n+                    children=[\n+                        toga.Button(\n+                            \"Report on selection\", on_press=self.report_selection\n+                        ),\n+                        self.report_label,\n+                    ],\n+                ),\n                 toga.Box(\n                     style=box_style,\n                     children=[\n@@ -66,7 +85,7 @@\n                 toga.Box(\n                     style=box_style,\n                     children=[\n-                        toga.Label(\"use some style!\", style=label_style),\n+                        toga.Label(\"Use some style!\", style=label_style),\n                         toga.Selection(\n                             style=Pack(width=200, padding=24),\n                             items=[\"Curium\", \"Titanium\", \"Copernicium\"],\n@@ -113,6 +132,11 @@\n \n         print(f\"The selection widget changed to {selection.value}\")\n \n+    def report_selection(self, widget):\n+        self.report_label.text = (\n+            f\"Element: {self.selection.value!r}; Empty: {self.empty_selection.value!r}\"\n+        )\n+\n \n def main():\n     # App name and namespace\ndiff --git a/iOS/src/toga_iOS/widgets/selection.py b/iOS/src/toga_iOS/widgets/selection.py\n--- a/iOS/src/toga_iOS/widgets/selection.py\n+++ b/iOS/src/toga_iOS/widgets/selection.py\n@@ -69,7 +69,10 @@\n         self.interface.factory.not_implemented(\"Selection.select_item()\")\n \n     def get_selected_item(self):\n-        return self.interface.items[self.picker.selectedRowInComponent(0)]\n+        try:\n+            return self.interface.items[self.picker.selectedRowInComponent(0)]\n+        except IndexError:\n+            return None\n \n     def set_on_select(self, handler):\n         # No special handling required\n", "issue": "Inconsistent behaviour with toga.Selection value attribute between Windows and Android\n### Describe the bug\n\nOn Windows, when a selection widget is created with a list containing an empty string (eg: toga.Selection(items=['1','a','','4']) ), the widget returns '' for the \"value\" attribute.\r\n\r\nOn Android, the selection's \"value\" attribute is set to None if the selection item is an empty string.\r\n\r\nI don't have MacOS, iOS, or Linux devices so I don't know what happens there.\n\n### Steps to reproduce\n\n0. Create Beeware Project\r\n1. Go to the app.py file\r\n2. Create a list \"list_1\" containing an empty string\r\n3. Create the base app class with the startup function and setup main box + window\r\n4. In the startup function, create a selection with the items being that of list_1. Store it as a class attribute for future access.\r\n5. Define a class function that outputs the selection value via print or info_dialog.\r\n6. Create Button to call the output function\r\n7. Add Selector & Button to main box\r\n9. Compile the code for both Windows and Android & launch them.\r\n11. Select the empty item of the selector\r\n12. Press the button\r\n13. Watch as the devices disagree on the value.\n\n### Expected behavior\n\nI would expect the selector value attribute to be an empty string as that was what the item was, and that is what the selector widget understands when values are written to it.\n\n### Screenshots\n\nThe source code I used:\r\n```\r\n\"\"\"\r\nTesting Crashes\r\n\"\"\"\r\nimport toga\r\nclass TestLab(toga.App):\r\n    def startup(self):\r\n        main_box=toga.Box()\r\n        self.select=toga.Selection(items=['A','B','0','','1','+','-'])\r\n        main_box.add(self.select)\r\n        main_box.add(toga.Button('Get',on_press=self.valuedump))\r\n        self.main_window=toga.MainWindow(title=self.formal_name)\r\n        self.main_window.content=main_box\r\n        self.main_window.show()\r\n    async def valuedump(self,widget):\r\n        q=self.select.value\r\n        print('GET',q,type(q))\r\n        self.main_window.info_dialog('Selection Value',f'Value: \"{q}\"\\n Type: {type(q)}')\r\ndef main():return TestLab()\r\n```\r\n\r\nOn Windows:\r\n\r\n![A_val](https://user-images.githubusercontent.com/113656324/209735390-f7e31b6e-c8d7-4cf3-9d51-2f47a69c7a62.png)\r\n![sel_vals](https://user-images.githubusercontent.com/113656324/209735397-60442c7c-28dd-413c-a7c4-bae10003363e.png)\r\n![Null_val](https://user-images.githubusercontent.com/113656324/209735402-9cdf611c-e512-4a52-bc9b-28ea193dae86.png)\r\n\r\nOn Android:\r\n\r\n![Screenshot_20221227-171610](https://user-images.githubusercontent.com/113656324/209735964-7f7ae864-d2ce-4203-99b5-87dddc5f8938.png)\r\n![Screenshot_20221227-171624](https://user-images.githubusercontent.com/113656324/209735970-d459f355-0390-490f-ba56-1adee2c6eef9.png)\r\n![Screenshot_20221227-171635](https://user-images.githubusercontent.com/113656324/209735971-84bca7d5-5590-454f-9f6f-effe244a4126.png)\r\n\n\n### Environment\n\n\r\nWindows 8.1 / Android 11\r\n- Python version: 3.10.0\r\n  - Briefcase: 3.11\r\n  - Toga: 0.3.0.dev8\r\n\n\n### Logs\n\nWindows:\r\n[briefcase.2022_12_27-17_09_47.run.log](https://github.com/beeware/toga/files/10311153/briefcase.2022_12_27-17_09_47.run.log)\r\n\r\nAndroid:\r\n[briefcase.2022_12_27-17_17_14.run.log](https://github.com/beeware/toga/files/10311154/briefcase.2022_12_27-17_17_14.run.log)\r\n\n\n### Additional context\n\n_No response_\n", "before_files": [{"content": "from travertino.size import at_least\n\nfrom toga_cocoa.libs import SEL, NSPopUpButton, objc_method, objc_property\n\nfrom .base import Widget\n\n\nclass TogaPopupButton(NSPopUpButton):\n    interface = objc_property(object, weak=True)\n    impl = objc_property(object, weak=True)\n\n    @objc_method\n    def onSelect_(self, obj) -> None:\n        if self.interface.on_select:\n            self.interface.on_select(self.interface)\n\n\nclass Selection(Widget):\n    def create(self):\n        self.native = TogaPopupButton.alloc().init()\n        self.native.interface = self.interface\n        self.native.impl = self\n\n        self.native.target = self.native\n        self.native.action = SEL(\"onSelect:\")\n\n        self.add_constraints()\n\n    def rehint(self):\n        content_size = self.native.intrinsicContentSize()\n        self.interface.intrinsic.height = content_size.height\n        self.interface.intrinsic.width = at_least(\n            max(self.interface._MIN_WIDTH, content_size.width)\n        )\n\n    def remove_all_items(self):\n        self.native.removeAllItems()\n\n    def add_item(self, item):\n        self.native.addItemWithTitle(item)\n\n    def select_item(self, item):\n        self.native.selectItemWithTitle(item)\n\n    def get_selected_item(self):\n        return str(self.native.titleOfSelectedItem)\n\n    def set_on_select(self, handler):\n        pass\n", "path": "cocoa/src/toga_cocoa/widgets/selection.py"}, {"content": "from rubicon.objc import CGSize, objc_method, objc_property\nfrom travertino.size import at_least\n\nfrom toga_iOS.libs import UIColor, UIPickerView, UITextBorderStyle, UITextField\nfrom toga_iOS.widgets.base import Widget\n\n\nclass TogaPickerView(UIPickerView):\n    interface = objc_property(object, weak=True)\n    impl = objc_property(object, weak=True)\n\n    @objc_method\n    def numberOfComponentsInPickerView_(self, pickerView) -> int:\n        return 1\n\n    @objc_method\n    def pickerView_numberOfRowsInComponent_(self, pickerView, component: int) -> int:\n        return len(self.interface.items)\n\n    @objc_method\n    def pickerView_titleForRow_forComponent_(\n        self, pickerView, row: int, component: int\n    ):\n        return str(self.interface.items[row])\n\n    @objc_method\n    def pickerView_didSelectRow_inComponent_(\n        self, pickerView, row: int, component: int\n    ):\n        self.native.text = self.interface.items[row]\n        if self.interface.on_select:\n            self.interface.on_select(self.interface)\n\n\nclass Selection(Widget):\n    def create(self):\n        self.native = UITextField.alloc().init()\n        self.native.interface = self.interface\n        self.native.impl = self\n        self.native.tintColor = UIColor.clearColor\n        self.native.borderStyle = UITextBorderStyle.RoundedRect\n\n        self.picker = TogaPickerView.alloc().init()\n        self.picker.interface = self.interface\n        self.picker.native = self.native\n        self.picker.delegate = self.picker\n        self.picker.dataSource = self.picker\n\n        self.native.inputView = self.picker\n        self.native.delegate = self.picker\n\n        self.add_constraints()\n\n    def rehint(self):\n        # Height of a text input is known.\n        fitting_size = self.native.systemLayoutSizeFittingSize(CGSize(0, 0))\n        self.interface.intrinsic.width = at_least(fitting_size.width)\n        self.interface.intrinsic.height = fitting_size.height\n\n    def remove_all_items(self):\n        # No special handling required\n        pass\n\n    def add_item(self, item):\n        if not self.native.text:\n            self.native.text = item\n\n    def select_item(self, item):\n        self.interface.factory.not_implemented(\"Selection.select_item()\")\n\n    def get_selected_item(self):\n        return self.interface.items[self.picker.selectedRowInComponent(0)]\n\n    def set_on_select(self, handler):\n        # No special handling required\n        pass\n", "path": "iOS/src/toga_iOS/widgets/selection.py"}, {"content": "import toga\nfrom toga.constants import COLUMN, ROW\nfrom toga.style import Pack\n\n\nclass SelectionApp(toga.App):\n    CARBON = \"Carbon\"\n    YTTERBIUM = \"Ytterbium\"\n    THULIUM = \"Thulium\"\n    OPTIONS = [CARBON, YTTERBIUM, THULIUM]\n\n    def startup(self):\n        # Main window of the application with title and size\n        self.main_window = toga.MainWindow(title=self.name, size=(640, 400))\n\n        # set up common styles\n        label_style = Pack(flex=1, padding_right=24)\n        box_style = Pack(direction=ROW, padding=10)\n\n        # Add the content on the main window\n        self.selection = toga.Selection(items=self.OPTIONS)\n\n        self.main_window.content = toga.Box(\n            children=[\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\"Select an element\", style=label_style),\n                        self.selection,\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Selection value can be set by property setter\",\n                            style=label_style,\n                        ),\n                        toga.Button(text=\"Set Carbon\", on_press=self.set_carbon),\n                        toga.Button(text=\"Set Ytterbium\", on_press=self.set_ytterbium),\n                        toga.Button(text=\"Set THULIUM\", on_press=self.set_thulium),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"use the 'on_select' callback to respond to changes\",\n                            style=label_style,\n                        ),\n                        toga.Selection(\n                            on_select=self.my_on_select,\n                            items=[\"Dubnium\", \"Holmium\", \"Zirconium\"],\n                        ),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Long lists of items should scroll\", style=label_style\n                        ),\n                        toga.Selection(items=dir(toga)),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\"use some style!\", style=label_style),\n                        toga.Selection(\n                            style=Pack(width=200, padding=24),\n                            items=[\"Curium\", \"Titanium\", \"Copernicium\"],\n                        ),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Selection widgets can be disabled\", style=label_style\n                        ),\n                        toga.Selection(\n                            items=[\n                                \"Helium\",\n                                \"Neon\",\n                                \"Argon\",\n                                \"Krypton\",\n                                \"Xenon\",\n                                \"Radon\",\n                                \"Oganesson\",\n                            ],\n                            enabled=False,\n                        ),\n                    ],\n                ),\n            ],\n            style=Pack(direction=COLUMN, padding=24),\n        )\n\n        self.main_window.show()\n\n    def set_carbon(self, widget):\n        self.selection.value = self.CARBON\n\n    def set_ytterbium(self, widget):\n        self.selection.value = self.YTTERBIUM\n\n    def set_thulium(self, widget):\n        self.selection.value = self.THULIUM\n\n    def my_on_select(self, selection):\n        # get the current value of the slider with `selection.value`\n\n        print(f\"The selection widget changed to {selection.value}\")\n\n\ndef main():\n    # App name and namespace\n    return SelectionApp(\"Selection\", \"org.beeware.selection\")\n\n\nif __name__ == \"__main__\":\n    app = main()\n    app.main_loop()\n", "path": "examples/selection/selection/app.py"}], "after_files": [{"content": "from travertino.size import at_least\n\nfrom toga_cocoa.libs import SEL, NSPopUpButton, objc_method, objc_property\n\nfrom .base import Widget\n\n\nclass TogaPopupButton(NSPopUpButton):\n    interface = objc_property(object, weak=True)\n    impl = objc_property(object, weak=True)\n\n    @objc_method\n    def onSelect_(self, obj) -> None:\n        if self.interface.on_select:\n            self.interface.on_select(self.interface)\n\n\nclass Selection(Widget):\n    def create(self):\n        self.native = TogaPopupButton.alloc().init()\n        self.native.interface = self.interface\n        self.native.impl = self\n\n        self.native.target = self.native\n        self.native.action = SEL(\"onSelect:\")\n\n        self.add_constraints()\n\n    def rehint(self):\n        content_size = self.native.intrinsicContentSize()\n        self.interface.intrinsic.height = content_size.height\n        self.interface.intrinsic.width = at_least(\n            max(self.interface._MIN_WIDTH, content_size.width)\n        )\n\n    def remove_all_items(self):\n        self.native.removeAllItems()\n\n    def add_item(self, item):\n        self.native.addItemWithTitle(item)\n\n    def select_item(self, item):\n        self.native.selectItemWithTitle(item)\n\n    def get_selected_item(self):\n        selected = self.native.titleOfSelectedItem\n        if selected:\n            return str(selected)\n\n    def set_on_select(self, handler):\n        pass\n", "path": "cocoa/src/toga_cocoa/widgets/selection.py"}, {"content": "from rubicon.objc import CGSize, objc_method, objc_property\nfrom travertino.size import at_least\n\nfrom toga_iOS.libs import UIColor, UIPickerView, UITextBorderStyle, UITextField\nfrom toga_iOS.widgets.base import Widget\n\n\nclass TogaPickerView(UIPickerView):\n    interface = objc_property(object, weak=True)\n    impl = objc_property(object, weak=True)\n\n    @objc_method\n    def numberOfComponentsInPickerView_(self, pickerView) -> int:\n        return 1\n\n    @objc_method\n    def pickerView_numberOfRowsInComponent_(self, pickerView, component: int) -> int:\n        return len(self.interface.items)\n\n    @objc_method\n    def pickerView_titleForRow_forComponent_(\n        self, pickerView, row: int, component: int\n    ):\n        return str(self.interface.items[row])\n\n    @objc_method\n    def pickerView_didSelectRow_inComponent_(\n        self, pickerView, row: int, component: int\n    ):\n        self.native.text = self.interface.items[row]\n        if self.interface.on_select:\n            self.interface.on_select(self.interface)\n\n\nclass Selection(Widget):\n    def create(self):\n        self.native = UITextField.alloc().init()\n        self.native.interface = self.interface\n        self.native.impl = self\n        self.native.tintColor = UIColor.clearColor\n        self.native.borderStyle = UITextBorderStyle.RoundedRect\n\n        self.picker = TogaPickerView.alloc().init()\n        self.picker.interface = self.interface\n        self.picker.native = self.native\n        self.picker.delegate = self.picker\n        self.picker.dataSource = self.picker\n\n        self.native.inputView = self.picker\n        self.native.delegate = self.picker\n\n        self.add_constraints()\n\n    def rehint(self):\n        # Height of a text input is known.\n        fitting_size = self.native.systemLayoutSizeFittingSize(CGSize(0, 0))\n        self.interface.intrinsic.width = at_least(fitting_size.width)\n        self.interface.intrinsic.height = fitting_size.height\n\n    def remove_all_items(self):\n        # No special handling required\n        pass\n\n    def add_item(self, item):\n        if not self.native.text:\n            self.native.text = item\n\n    def select_item(self, item):\n        self.interface.factory.not_implemented(\"Selection.select_item()\")\n\n    def get_selected_item(self):\n        try:\n            return self.interface.items[self.picker.selectedRowInComponent(0)]\n        except IndexError:\n            return None\n\n    def set_on_select(self, handler):\n        # No special handling required\n        pass\n", "path": "iOS/src/toga_iOS/widgets/selection.py"}, {"content": "import toga\nfrom toga.constants import COLUMN, ROW\nfrom toga.style import Pack\n\n\nclass SelectionApp(toga.App):\n    CARBON = \"Carbon\"\n    YTTERBIUM = \"Ytterbium\"\n    THULIUM = \"Thulium\"\n    OPTIONS = [CARBON, YTTERBIUM, THULIUM]\n\n    def startup(self):\n        # Main window of the application with title and size\n        self.main_window = toga.MainWindow(title=self.name, size=(640, 400))\n\n        # set up common styles\n        label_style = Pack(flex=1, padding_right=24)\n        box_style = Pack(direction=ROW, padding=10)\n\n        # Add the content on the main window\n        self.selection = toga.Selection(items=self.OPTIONS)\n        self.empty_selection = toga.Selection()\n\n        self.report_label = toga.Label(\"\", style=label_style)\n\n        self.main_window.content = toga.Box(\n            children=[\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\"Select an element\", style=label_style),\n                        self.selection,\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\"Empty selection\", style=label_style),\n                        self.empty_selection,\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Button(\n                            \"Report on selection\", on_press=self.report_selection\n                        ),\n                        self.report_label,\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Selection value can be set by property setter\",\n                            style=label_style,\n                        ),\n                        toga.Button(text=\"Set Carbon\", on_press=self.set_carbon),\n                        toga.Button(text=\"Set Ytterbium\", on_press=self.set_ytterbium),\n                        toga.Button(text=\"Set THULIUM\", on_press=self.set_thulium),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"use the 'on_select' callback to respond to changes\",\n                            style=label_style,\n                        ),\n                        toga.Selection(\n                            on_select=self.my_on_select,\n                            items=[\"Dubnium\", \"Holmium\", \"Zirconium\"],\n                        ),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Long lists of items should scroll\", style=label_style\n                        ),\n                        toga.Selection(items=dir(toga)),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\"Use some style!\", style=label_style),\n                        toga.Selection(\n                            style=Pack(width=200, padding=24),\n                            items=[\"Curium\", \"Titanium\", \"Copernicium\"],\n                        ),\n                    ],\n                ),\n                toga.Box(\n                    style=box_style,\n                    children=[\n                        toga.Label(\n                            \"Selection widgets can be disabled\", style=label_style\n                        ),\n                        toga.Selection(\n                            items=[\n                                \"Helium\",\n                                \"Neon\",\n                                \"Argon\",\n                                \"Krypton\",\n                                \"Xenon\",\n                                \"Radon\",\n                                \"Oganesson\",\n                            ],\n                            enabled=False,\n                        ),\n                    ],\n                ),\n            ],\n            style=Pack(direction=COLUMN, padding=24),\n        )\n\n        self.main_window.show()\n\n    def set_carbon(self, widget):\n        self.selection.value = self.CARBON\n\n    def set_ytterbium(self, widget):\n        self.selection.value = self.YTTERBIUM\n\n    def set_thulium(self, widget):\n        self.selection.value = self.THULIUM\n\n    def my_on_select(self, selection):\n        # get the current value of the slider with `selection.value`\n\n        print(f\"The selection widget changed to {selection.value}\")\n\n    def report_selection(self, widget):\n        self.report_label.text = (\n            f\"Element: {self.selection.value!r}; Empty: {self.empty_selection.value!r}\"\n        )\n\n\ndef main():\n    # App name and namespace\n    return SelectionApp(\"Selection\", \"org.beeware.selection\")\n\n\nif __name__ == \"__main__\":\n    app = main()\n    app.main_loop()\n", "path": "examples/selection/selection/app.py"}]}