Skip to content
Kartik Hariharan edited this page Oct 29, 2016 · 3 revisions

mGui uses a CSS like styling mechanism to help separate the visual look of controls from their logical layout.

mgui.styles.css is basically just a dictionary of options. It can include any maya gui flags (for example 'backgroundColor' or 'width' or 'numberOfChildren'). These options can be applied to an mGui class in two ways:

Explicit assignment

To explicitly assign a CSS style to an element, pass it into the object using the 'css' keyword. This is a simple way to split your style info from the logical layout:

from mGui.gui import *
from mGui.styles import CSS
bg_style = CSS(None, backgroundColor = (0,1,1), columnAlign='right', width = 100)
btn_style = CSS(None, backgroundColor = (1,1,0), height = 72)

with Window('example') as w:
    with ColumnLayout(None, css=bg_style):
         Button(None, label = "example", css = btn_style)
w.show()

This will create a window with a cyan background and a button with a yellow background

Automatic assignment

The first argument to the CSS constructor is the target. If target is a class, the style applies to any instance of that class. If target is a string, the style applies to a control with that name. Thus

Inheritance

Styles can inherit content (NOT targets!) from each other. The second argument to the constructor is the 'parent' CSS. Thus:

outer = CSS('a', color = 'red', margin = 1)
inner = CSS('b', outer, width = 128}  # inner's parent is outer 
print inner
# {'color':'red', 'margin':1, 'width':128}

Inheritance is is passed along through multiple parents.

a = CSS('a', color = 'red'}            
b = CSS('b', width = 128}
c = CSS('c', a, b, margin = 1}
print c
# {'color':'red', 'margin':1, 'width':128}

Later assignments overwrite earlier ones. Explicit assignments are the 'latest' of all:

a = CSS('a', color = 'red'}            
b = CSS('b', color = 'blue', width = 128}
c = CSS('c', a, b, width = 256}
print c
# {'color':'blue',  'width':256}

Styles can be used as context managers. All styles declared inside a context manager automatically inherit from it:

 with styles.CSS('outer', width = 100, height = 100) as outer:
     with styles.CSS('inner', bgc = (1,0,0), size = 3) as inner:
         q = styles.CSS('innermost', size = 4)
     assert q['width'] == outer['width']
     assert q['bgc'] == inner['bgc']
     ssert q['size'] == 4

Styles can be nested. The context manager syntax does this automatically, or users can explicitly add child styles with add_child. Using the find method to get the appropriate style for a control will walk the nested control hierarchy from the bottom upwards, so more specific styles would be at the bottom of the hierarchy

        with styles.CSS(MockCtrl, name ='outer') as outer:
                with styles.CSS(MockButton, name = 'middle') as middle:
                    inner = styles.CSS(MockRedButton, name = 'inner')
  
        test = MockRedButton('mrb')
        assert outer.find(test)['name'] == 'inner'  
        # inner style wins because it's lowest in the the nesting. this IS NOT 
        # based on class hierarchy among targets! If inner looked at MockButton 
        # (the parent class of MockRedButton) it would STILL win in this example

The context manager functionality is REUSABLE. The examples above show how nested contexts can be use to prioritize the search order for different styles. The other use is to activate a style for use in the creation of controls:

    with styles.CSS(StyledMockCtrl, width = 100, height = 100, expected = False) as outer:
        with styles.CSS(StyledMockButton, bgc = (1,0,0), size = 3, expected = None):
            deepest = styles.CSS(StyledMockRedButton, size = 4, expected = True)
                    
    with outer:
        test = StyledMockRedButton('fred')  # uses deepest on creation, as in earlier example
        test2 = StyledMockList('barney')    # uses uses outer, since its the closes match for the class
        test3 = UnStyledButton('nostyle')   # if the class does not derive from Styled, nothing happens
        test4 = StyledMockButton('custom', style = CSS('custom', width = 11, height=91)) 
                                            # explicitly passed style wins over the styles in outer.