1
1
import typing
2
2
from typing import Callable , List , Optional , Union
3
-
3
+ from dataclasses import dataclass
4
4
import datetime
5
5
6
- from flet import (AlertDialog ,
7
- Column ,
8
- Container ,
9
- Dropdown ,
10
- ElevatedButton ,
11
- FilledButton ,
12
- Icon ,
13
- Image ,
14
- PopupMenuButton ,
15
- PopupMenuItem ,
16
- ProgressBar ,
17
- ResponsiveRow ,
18
- Row ,
19
- Text ,
20
- TextField ,
21
- TextStyle ,
22
- UserControl ,
23
- alignment ,
24
- border_radius ,
25
- dropdown ,
26
- icons ,
27
- padding ,)
6
+ from flet import (
7
+ AlertDialog ,
8
+ Column ,
9
+ Container ,
10
+ Dropdown ,
11
+ ElevatedButton ,
12
+ FilledButton ,
13
+ Icon ,
14
+ Image ,
15
+ PopupMenuButton ,
16
+ PopupMenuItem ,
17
+ ProgressBar ,
18
+ margin ,
19
+ NavigationRail ,
20
+ Row ,
21
+ Text ,
22
+ TextField ,
23
+ TextStyle ,
24
+ UserControl ,
25
+ alignment ,
26
+ border_radius ,
27
+ dropdown ,
28
+ icons ,
29
+ padding ,
30
+ )
28
31
29
32
from res import colors , dimens , fonts , image_paths
30
33
31
34
from .abstractions import DialogHandler
32
- from .utils import (AUTO_SCROLL ,
33
- CENTER_ALIGNMENT ,
34
- CONTAIN ,
35
- KEYBOARD_MULTILINE ,
36
- KEYBOARD_NONE ,
37
- KEYBOARD_PASSWORD ,
38
- KEYBOARD_TEXT ,
39
- SPACE_BETWEEN_ALIGNMENT ,
40
- START_ALIGNMENT ,
41
- TXT_ALIGN_CENTER ,
42
- TXT_ALIGN_LEFT ,
43
- AlertDialogControls ,)
35
+ from . import utils
44
36
45
37
lgSpace = Container (height = dimens .SPACE_LG , width = dimens .SPACE_STD , padding = 0 , margin = 0 )
46
38
mdSpace = Container (height = dimens .SPACE_MD , width = dimens .SPACE_MD , padding = 0 , margin = 0 )
@@ -55,7 +47,7 @@ def get_heading(
55
47
title : str = "" ,
56
48
size : int = fonts .SUBTITLE_1_SIZE ,
57
49
color : Optional [str ] = None ,
58
- align : str = TXT_ALIGN_LEFT ,
50
+ align : str = utils . TXT_ALIGN_LEFT ,
59
51
show : bool = True ,
60
52
):
61
53
"""Displays text formatted as a headline"""
@@ -74,7 +66,7 @@ def get_sub_heading_txt(
74
66
subtitle : str = "" ,
75
67
size : int = fonts .SUBTITLE_2_SIZE ,
76
68
color : Optional [str ] = None ,
77
- align : str = TXT_ALIGN_LEFT ,
69
+ align : str = utils . TXT_ALIGN_LEFT ,
78
70
show : bool = True ,
79
71
expand : bool = False ,
80
72
):
@@ -93,8 +85,8 @@ def get_sub_heading_txt(
93
85
def get_heading_with_subheading (
94
86
title : str ,
95
87
subtitle : str ,
96
- alignment_in_container : str = START_ALIGNMENT ,
97
- txt_alignment : str = TXT_ALIGN_LEFT ,
88
+ alignment_in_container : str = utils . START_ALIGNMENT ,
89
+ txt_alignment : str = utils . TXT_ALIGN_LEFT ,
98
90
title_size : int = fonts .SUBTITLE_1_SIZE ,
99
91
subtitle_size : int = fonts .SUBTITLE_2_SIZE ,
100
92
subtitle_color : Optional [str ] = None ,
@@ -125,7 +117,7 @@ def get_body_txt(
125
117
color : Optional [str ] = None ,
126
118
show : bool = True ,
127
119
col : Optional [dict ] = None ,
128
- align : str = TXT_ALIGN_LEFT ,
120
+ align : str = utils . TXT_ALIGN_LEFT ,
129
121
** kwargs ,
130
122
):
131
123
"""Displays text standard-formatted for body"""
@@ -144,7 +136,7 @@ def get_std_txt_field(
144
136
on_change : typing .Optional [Callable ] = None ,
145
137
label : str = "" ,
146
138
hint : str = "" ,
147
- keyboard_type : str = KEYBOARD_TEXT ,
139
+ keyboard_type : str = utils . KEYBOARD_TEXT ,
148
140
on_focus : typing .Optional [Callable ] = None ,
149
141
initial_value : typing .Optional [str ] = None ,
150
142
expand : typing .Optional [int ] = None ,
@@ -164,10 +156,10 @@ def get_std_txt_field(
164
156
focused_border_width = 1 ,
165
157
on_focus = on_focus ,
166
158
on_change = on_change ,
167
- password = keyboard_type == KEYBOARD_PASSWORD ,
159
+ password = keyboard_type == utils . KEYBOARD_PASSWORD ,
168
160
expand = expand ,
169
161
width = width ,
170
- disabled = keyboard_type == KEYBOARD_NONE ,
162
+ disabled = keyboard_type == utils . KEYBOARD_NONE ,
171
163
text_size = fonts .BODY_1_SIZE ,
172
164
label_style = TextStyle (size = fonts .BODY_2_SIZE ),
173
165
error_style = TextStyle (size = fonts .BODY_2_SIZE , color = colors .ERROR_COLOR ),
@@ -180,7 +172,7 @@ def get_std_multiline_field(
180
172
label : str ,
181
173
hint : str ,
182
174
on_focus : typing .Optional [Callable ] = None ,
183
- keyboardType : str = KEYBOARD_MULTILINE ,
175
+ keyboardType : str = utils . KEYBOARD_MULTILINE ,
184
176
minLines : int = 3 ,
185
177
maxLines : int = 5 ,
186
178
):
@@ -244,29 +236,31 @@ def get_profile_photo_img(pic_src: str = image_paths.default_avatar):
244
236
width = 72 ,
245
237
height = 72 ,
246
238
border_radius = border_radius .all (36 ),
247
- fit = CONTAIN ,
239
+ fit = utils . CONTAIN ,
248
240
)
249
241
250
242
251
243
def get_image (path : str , semantic_label : str , width : int ):
252
244
return Container (
253
245
width = width ,
254
- content = Image (src = path , fit = CONTAIN , semantics_label = semantic_label ),
246
+ content = Image (src = path , fit = utils . CONTAIN , semantics_label = semantic_label ),
255
247
)
256
248
257
249
258
250
def get_app_logo (width : int = 12 ):
259
251
"""Returns app logo"""
260
252
return Container (
261
253
width = width ,
262
- content = Image (src = image_paths .logoPath , fit = CONTAIN , semantics_label = "logo" ),
254
+ content = Image (
255
+ src = image_paths .logoPath , fit = utils .CONTAIN , semantics_label = "logo"
256
+ ),
263
257
)
264
258
265
259
266
260
def get_labelled_logo ():
267
261
"""Returns app logo with app name next to it"""
268
262
return Row (
269
- vertical_alignment = CENTER_ALIGNMENT ,
263
+ vertical_alignment = utils . CENTER_ALIGNMENT ,
270
264
controls = [
271
265
get_app_logo (),
272
266
get_heading (
@@ -494,7 +488,7 @@ class AlertDisplayPopUp(DialogHandler):
494
488
495
489
def __init__ (
496
490
self ,
497
- dialog_controller : Callable [[any , AlertDialogControls ], None ],
491
+ dialog_controller : Callable [[any , utils . AlertDialogControls ], None ],
498
492
title : str ,
499
493
description : str ,
500
494
on_complete : Optional [Callable ] = None ,
@@ -507,7 +501,7 @@ def __init__(
507
501
content = Container (
508
502
height = pop_up_height ,
509
503
content = Column (
510
- scroll = AUTO_SCROLL ,
504
+ scroll = utils . AUTO_SCROLL ,
511
505
controls = [
512
506
get_heading (
513
507
title = title ,
@@ -542,7 +536,7 @@ class ConfirmDisplayPopUp(DialogHandler):
542
536
543
537
def __init__ (
544
538
self ,
545
- dialog_controller : Callable [[any , AlertDialogControls ], None ],
539
+ dialog_controller : Callable [[any , utils . AlertDialogControls ], None ],
546
540
title : str ,
547
541
description : str ,
548
542
data_on_confirmed : any ,
@@ -557,7 +551,7 @@ def __init__(
557
551
content = Container (
558
552
height = pop_up_height ,
559
553
content = Column (
560
- scroll = AUTO_SCROLL ,
554
+ scroll = utils . AUTO_SCROLL ,
561
555
controls = [
562
556
get_heading (
563
557
title = title ,
@@ -675,8 +669,10 @@ def get_or_txt(show_lines: Optional[bool] = True, show: bool = True):
675
669
"""Returns a view representing ---- OR ----"""
676
670
return Row (
677
671
visible = show ,
678
- alignment = SPACE_BETWEEN_ALIGNMENT if show_lines else CENTER_ALIGNMENT ,
679
- vertical_alignment = CENTER_ALIGNMENT ,
672
+ alignment = utils .SPACE_BETWEEN_ALIGNMENT
673
+ if show_lines
674
+ else utils .CENTER_ALIGNMENT ,
675
+ vertical_alignment = utils .CENTER_ALIGNMENT ,
680
676
controls = [
681
677
Container (
682
678
height = 2 ,
@@ -685,7 +681,7 @@ def get_or_txt(show_lines: Optional[bool] = True, show: bool = True):
685
681
alignment = alignment .center ,
686
682
visible = show_lines ,
687
683
),
688
- get_body_txt ("OR" , align = TXT_ALIGN_CENTER , color = colors .GRAY_COLOR ),
684
+ get_body_txt ("OR" , align = utils . TXT_ALIGN_CENTER , color = colors .GRAY_COLOR ),
689
685
Container (
690
686
height = 2 ,
691
687
bgcolor = colors .GRAY_COLOR ,
@@ -695,3 +691,59 @@ def get_or_txt(show_lines: Optional[bool] = True, show: bool = True):
695
691
),
696
692
],
697
693
)
694
+
695
+
696
+ @dataclass
697
+ class NavigationMenuItem :
698
+ """defines a menu item used in navigation rails"""
699
+
700
+ index : int
701
+ label : str
702
+ icon : str
703
+ selected_icon : str
704
+ destination : UserControl
705
+ on_new_screen_route : Optional [str ] = None
706
+ on_new_intent : Optional [str ] = None
707
+
708
+
709
+ def get_std_navigation_menu (
710
+ title : str ,
711
+ on_change ,
712
+ selected_index : Optional [int ] = 0 ,
713
+ destinations = [],
714
+ menu_height : int = 300 ,
715
+ width : int = int (dimens .MIN_WINDOW_WIDTH * 0.3 ),
716
+ left_padding : int = dimens .SPACE_STD ,
717
+ top_margin : int = dimens .SPACE_STD ,
718
+ ):
719
+ """
720
+ Returns a navigation menu for the application.
721
+
722
+ :param title: Title of the navigation menu.
723
+ :param on_change: Callable function to be called when the selected item in the menu changes.
724
+ :param selected_index: The index of the selected item in the menu.
725
+ :param destinations: List of destinations in the menu.
726
+ :param menu_height: The height of the menu.
727
+ :return: A NavigationRail widget containing the navigation menu.
728
+ """
729
+ return NavigationRail (
730
+ leading = Container (
731
+ content = get_sub_heading_txt (
732
+ subtitle = title ,
733
+ align = utils .START_ALIGNMENT ,
734
+ expand = True ,
735
+ color = colors .GRAY_DARK_COLOR ,
736
+ ),
737
+ expand = True ,
738
+ width = width ,
739
+ margin = margin .only (top = top_margin ),
740
+ padding = padding .only (left = left_padding ),
741
+ ),
742
+ selected_index = selected_index ,
743
+ min_width = utils .COMPACT_RAIL_WIDTH ,
744
+ extended = True ,
745
+ height = menu_height ,
746
+ min_extended_width = width ,
747
+ destinations = destinations ,
748
+ on_change = on_change ,
749
+ )
0 commit comments