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

Declarative API for widgets #222

Open
peterbrittain opened this issue Aug 16, 2019 · 0 comments
Open

Declarative API for widgets #222

peterbrittain opened this issue Aug 16, 2019 · 0 comments

Comments

@peterbrittain
Copy link
Owner

peterbrittain commented Aug 16, 2019

@boxed has proposed this API for creating a more declarative model for creating widgets...

I experimented a bit with how the API could be nicer... here's from the contacts example using some tri.declarative magic:

class ContactView(Frame):
    def __init__(self, screen, model):
        super(ContactView, self).__init__(screen,
                                          screen.height * 2 // 3,
                                          screen.width * 2 // 3,
                                          hover_focus=True,
                                          can_scroll=False,
                                          title="Contact Details",
                                          reduce_cpu=True)
        # Save off the model that accesses the contacts database.
        self._model = model
        self.widget_by_name = Struct()

        layout(
            frame=self,
            fill_frame=True,
            widgets=dict(
                name=widget(Text, label="Name:"),
                address=widget(Text, label="Address:"),
                phone=widget(Text, label="Phone number:"),
                email=widget(Text, label="Email address:"),
                notes=widget(TextBox, height=Widget.FILL_FRAME, label="Notes:", as_string=True, line_wrap=True),
            ),
            grid=[
                ['name'],
                ['address'],
                ['phone'],
                ['email'],
                ['notes']
            ]
        )

        layout(
            frame=self,
            widgets=dict(
                ok=widget(Btn, on_click=self._ok),
                cancel=widget(Btn, on_click=self._cancel),
            ),
            grid=[
                ['ok', None, 'cancel']
            ]
        )

        self.fix()

where layout is:

@dispatch(
    widgets=EMPTY,
)
def layout(*, frame, widgets, grid, fill_frame=False):
    assert len(set(len(row) for row in grid)), 'All columns must be the same width'

    columns = [1 for _ in grid[0]]
    l = Layout(columns=columns, fill_frame=fill_frame)
    frame.add_layout(l)
    for row in grid:
        for i, widget_name in enumerate(row):
            if widget_name is None:
                # blank space in the layout
                continue
            widgets[widget_name].name = widget_name

            widget = widgets[widget_name]()
            l.add_widget(widget, i)
            frame.widget_by_name[widget_name] = widget

    return l

It's a big rough still, but I stopped working on it for unrelated reasons. I hope it can give you some things to think about.

Originally posted by @boxed in #24 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant