File: Frigcal/code/Frigcal--source/common.kv

#===============================================================================
# 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 (<name@super>) for repeated code or common appearance
# Use Factory.name() or class name(super) in .py to access <name> class in .kv
# Use <name> 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. 


<Widget>:

    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
#------------------------------------------------------------------------------


<LabelTextDisplay@MDLabel>:

    # 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)


<FormTextField@MDTextField_FixSelectPasteBubble>:     
    
    # 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)

<SplitTextBoxLayout@MDBoxLayout>:
    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
#
#<LabelTextDisplayHalf1@LabelTextDisplay>:
#    padding: (dp(10), dp(10), dp(10), 0)    # [left, top, right, bottom]
#
#<LabelTextDisplayHalf2@LabelTextDisplay>:
#    padding: (dp(10), 0, dp(10), dp(10))
#
#<HalvesBoxLayout@MDBoxLayout>:
#    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


<DialogButton@Button>
    background_color: app.theme_cls.primary_color    # was 'navy' pre kivymd
    #border: (2, 2, 2, 2)                            # borders require canvas code


<DialogButtonsRows1@GridLayout>:
    rows: 1
    size_hint_y: None
    height: buttonheight                # and add N DialogButton, cols = N


<DialogButtonsRows2@GridLayout>:
    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