Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible method of making Compound Controls #84

Closed
wants to merge 4 commits into from

Conversation

bob-white
Copy link
Collaborator

Initial example is an IntSpinner.
Based on the conversation over at TAO

Basically just expands the IntField with a new step value, and links the two buttons to increment and decrement the value.

from mGui import gui, forms, core
from mGui.core.compound import IntSpinner

with gui.Window() as win:
    with forms.VerticalForm() as main:
        spinner = IntSpinner(width=256, height=24)
        gui.Separator()
        spinner2 = IntSpinner(width=256, height=24, step=5)

win.show()

If we want to further expose the button commands, we'd need some kind of descriptor to route the Events from the sub commands, but that should be fairly simple.

Initial example is an IntSpinner.
Also moved to using regular buttons with silly labels for now.
Seems that `IconTextButton` has a minimum width that would cause it to
overflow onto the `IntField`, and I'm not entirely sure what is causing
it.
@bob-white bob-white changed the title Possible method of making Compout Controls Possible method of making Compound Controls Jul 20, 2017
Copy link
Owner

@theodox theodox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in seeing what we can do to handle property and event forwarding from the components up to the main compound object.

@theodox
Copy link
Owner

theodox commented Jul 20, 2017

In other words:: I'd like to write a class without too much custom code where my compound thing has a tree of widgets:

  Root
      - label
      - field
      -form 
          -up-button
          -down-button

and have a nice, clean and clear way of setting properties on root.form.down-button wiithout needing to know that internal strucuture -- something like compound.decrement.backgroundColor = xxx from the user side even though its root.form.down-button.backgroundcolor = xxx under the hood

The tricky bit is how to make inot too painful to set up, ideally with a nice metaclass to make it really uncluttered

@bob-white
Copy link
Collaborator Author

So something along these lines

class CompoundControlMeta(type):
    # Some magic will happen here
    pass

class CompoundControl:
    __metaclass__ = CompoundControlMeta

class IntSpinner(CompoundControl):

    _CONTROLS = {
        'root': HorizontalStretchForm,
        'field': IntField,
        'label': Text,
        'decrement': Button,
        'increment': Button,
        'form': VerticalStretchForm,
    }
    _HIERARCHY = {
        'root': (
            'label',
            'field', {
                'form': (
                    'increment',
                    'decrement'
                )
            }
        )
    }

CompoundControlMeta would need to walk _CONTROLS to generate the widget properties for routing those properly. It would also need to be able to walk _HIERARCHY to generate the actual internal layout.

Other issues:

  • How do we handle **kwargs for each sub-widget?
  • What on earth does repr return?
  • Do CompoundControls have a widget field? If so which widget?
  • How would we tackle something like this with wrap/find?

@bob-white
Copy link
Collaborator Author

Also something like this might benefit from #65.
Or maybe something closer to the kv DSL from kivy.

@theodox
Copy link
Owner

theodox commented Jul 20, 2017

I think I'm OK with the compound widget assembly process being code rather than data -- the list classes, which are effectively examples of compound widgets, needed some finagling to work the way I liked. At this early stage of the idea it feels like the main issue is a painless way for the owning compound object to expose properties correctly -- some of them will be unique to the compoiund and need custom code but some will basically be pass-throughs of properites on lower level stuff.

I've been assuming that the widget of the compound is going to be the root of the underlying pieces, so you can set things like position, size and so on easily

Uses `__getattr__` and `__setattr__` to defer requests to the root
control.
Exposes the other controls as public fields.
@bob-white
Copy link
Collaborator Author

bob-white commented Jul 20, 2017

Updated the PR with just another thought. Instead of subclassing any mGui object, this acts more as a facade.
It uses __getattr__ and __setattr__ to route attribute lookup to the root object, if a field happens to exist there, otherwise it defaults to normal behavior. Also, given the way __getattr__ works, anything that already exists on the facade gets precedence.

Each of the controls is exposed as a public field, so no need to generate properties to route information to them.

Still have to manually generate any IntSpinner specific code though, which seems like a place where we can probably get a metaclass involved to simplify it.

Might just throw this out, but don't want to lose it yet.
@bob-white bob-white closed this Mar 2, 2018
@bob-white bob-white deleted the IntSpinner branch March 2, 2018 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants