#=============================================================================== # Kivy-lang code common to / shared by multiple .kv files that #:include it #=============================================================================== # Include this just once (#:include) before code that uses it; any .kv # code loaded/run after this code is loaded/run has access to its names. # Use kivy-lang variables (#:set) for repeated constants # Use kivy-lang classes () for repeated code or common appearance # Use Factory.name() or class name(super) in .py to access class in .kv # Use in .kv to access [class name:] class defined in .py (via Factory) #------------------------------------------------------------------------------ # Global imports and settings #------------------------------------------------------------------------------ # for refs in py code here (TBD: unused?) #:import os os #:import sys sys #:import Clock kivy.clock.Clock # for phone/pc-specific tweaks (TBD: used?) #:set RunningOnAndroid hasattr(sys, 'getandroidapilevel') #:set RunningOnMacos sys.platform.startswith('darwin') #:set RunningOnWindows sys.platform.startswith('win') # for disabling glitchy overscroll effects # ScrollView.effect_cls can be a class (here) or a string (looked up in Factory) #:import ScrollEffect kivy.effects.scroll.ScrollEffect #------------------------------------------------------------------------------ # Global font size #------------------------------------------------------------------------------ # Global font size, applied to _every_ Widget subclass by inheritance. # Yes, it works, if bound to property app.dynamic_font_size, not self|root. # TL;DR: font_size works but with KivyMD requires post-create rebinds and does # not apply to drop-down menus. Ditto for font_name, but it was cut because # (1) setting Widget's font_name globally also breaks the hamburger button # and main-menu icons, and not setting it means already-displayed text isn't # updated; and (2) font_name doesn't apply to all widgets, unlike font_size. # KIVYMD OVERRIDES: # Apps using KivyMD must also explicitly set font_size in .py code _after_ # creation for KivyMD widgets that override it per MD theme defaults or styles # in their construction code. This is not required for base Kivy widgets, but # is for some KivyMD widgets, including MDLabel and OneLineListItem used in # this app. Set this in a widget-subclass instance, like LabelTextDisplay. # For OneLineListItem, this must access the MDLabel embedded in the FloatLayout # package by private _x widget id, which is subpar, but beats reimplementing OLLI. # DROP-DOWNS CAVEAT: # KivyMD drop-down menus in this app do not respect the Widget font size here, # because there seems no way to access their OneLineListItems after their creation. # Menus use a declarative dict, not widgets, and RecycleView may defer their widget # builds. Hence, an open TBD, but punt for now: drop-down font size follows MD # guidelines, for better or worse. See main.py and *_screen.py for setter code. # FONT-NAME TRY: # A related font name was later added on the settings screen. The font_name it # sets globally in Widget is similarly overriden by KivyMD and must be reset post # construction in all the same contexts as font_size to take effect. (This arose # from an attempt at Emoji fonts, which seem a fail in 4.0: see monthgui.py.) # FONT-NAME FAIL: # Unlike font_size, we cannot set font_name for all Widget instances here, # because KivyMD icons are implemented as characters in a specific icon font # (Material Design Icons). These characters are not present in other fonts, # so changing global font_name here breaks both the hamburger button and # main-menu icons. Moreover, even with an all-widget setting here, font_name # is not applied to every Widget like font_size but only to those expicitly # bound to it post creation. This is likely due to other KivyMD overrides. # # THE VERDICT: # Hence, keep the font_size setting, but drop font_name. For the latter, the # best we could do is not set it in Widget here, but then it would apply only # to new text, not to already-displayed text, and even so it would work only # for a handful of widgets. This is inconsistent with font_size and convoluted # to explain in Help, which are both bad signs. Given that its few built-in # fonts make it marginal in the first place, it's not worth keeping or honing. : font_size: app.dynamic_font_size # applied to every Widget-subclass instance (!) #font_name: app.dynamic_font_name # likewise, with same KivyMD requirements (nope) #------------------------------------------------------------------------------ # Text display fields #------------------------------------------------------------------------------ : # for showing text in labels: dialogs, large-text splits # TextInput/Field handles larger text, but has no markup # use MDLabel for features, not TextInputNoSelect in .py # font_size+name must be bound after created in .py else auto-set per MD markup: True # use '[]' for bold, italic, under, etc. multiline: True do_wrap: True # also splits text on embedded \n adaptive_height: True # enables scrolling: = [size_hint_y: None] + [height: self.minimum_height] theme_text_color: 'Primary' # see also foreground_color, background_color halign: 'left' padding: dp(10) # h=v, or [h, v], was (8, 0, 8, 0) before density scaling # other tries... # readonly: True # labels have no readonly property # adaptive_width: True # = [size_hint_x: None] + [width: self.minimum_width] # font_size: app.dynamic_font_size # bind after create else kivymd overrides # font_name: 'RobotoMono-Regular' # monospace (later a user Setting, also rebound) : # for text input fields, with help-text labels # use kivymd textfield for its label+styling # override defaults here in concrete widgets # uses main.py MDTextField with bubble workariund text: '' # content set/fetched explicity in monthgui.py mode: 'fill' # 'rectangle' broken in kivymd 2.3.1: use fill adaptive_height: True # sizes to content, enables note vscrolls multiline: False text_color_normal: app.manual_theme_color_fg() text_color_focus: app.manual_theme_color_fg() use_handles: False # selection handles on taps use_bubble: False # select/copy bubbles taps+longpress #mode: 'rectangle', 'round', 'fill', 'line' (not 'outline') #mode: 'rectangle' <= kivymd 1.2.0 bug: border line overlaps label, wrong bg #pos_hint: {'center_x': .5, 'center_y': .5} #padding: [dp(10), dp(10)] # scale to screen density #------------------------------------------------------------------------------ # Multi-label text splits #------------------------------------------------------------------------------ # Custom paddings and container for Label halves of Help and About screens # A workaround to unreasonable Label text-size limts (see allscreens.kv) : orientation: 'vertical' # stack children on top of each other adaptive_height: True # adjust height based on children's content # NO LONGER USED: generalized for any size text and number labels in main.py # Done to make Label textures smaller for old phones and pause/resume blanks # #: # padding: (dp(10), dp(10), dp(10), 0) # [left, top, right, bottom] # #: # padding: (dp(10), 0, dp(10), dp(10)) # #: # orientation: 'vertical' # stack children on top of each other # adaptive_height: True # adjust height based on children's content #------------------------------------------------------------------------------ # Web-link and action buttons #------------------------------------------------------------------------------ # Tbd: row height is a % relative to window size; use absolute dp() instead? # or, use [height: buttonheight] to make rows consistent everywhere # yes: a % grows/shrinks with window size on PCs oddly; use abs dp() # use density-scaled pixels for varying displays #:set buttonheight dp(40) # use reponsive sizing for varying displays (now unused) #:set dialogButtonRowHeight 0.08 background_color: app.theme_cls.primary_color # was 'navy' pre kivymd #border: (2, 2, 2, 2) # borders require canvas code : rows: 1 size_hint_y: None height: buttonheight # and add N DialogButton, cols = N : rows: 2 size_hint_y: None height: buttonheight * 2 # and add N DialogButton, cols = ceil(N / 2) # was... # GridLayout: # cols: 2 # size_hint_y: dialogButtonRowHeight # ...2 items, rows=1 # # GridLayout: # cols: 2 # size_hint_y: dialogButtonRowHeight * 2 # ...4 items, rows=2 # # BoxLayout: # size_hint_y: None # height: buttonheight # orientation: 'horizontal' #------------------------------------------------------------------------------ # Temp dev notes #------------------------------------------------------------------------------ # adaptive_height: True (in kivymd only) # sizes to content, enables scrolls, and is the same as kivy's: # # size_hint_y: None # disable vertical size hint # height: self.minimum_height # set to the sum of children's heights # # for labels, height may also be equivalently set to: # height: self.texture_size[1] # adjust height based on widget's content