# project-2 **Repository Path**: jswrt/project-2 ## Basic Information - **Project Name**: project-2 - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 17 - **Created**: 2023-04-25 - **Last Updated**: 2023-04-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # project-2 #### 介绍 目前已经基本整合完Flutter的所有控件,并完成了相应测试 ![输入图片说明](home.png) #### 实现 1. Banners ![输入图片说明](pics/banners.png) ```python class MaterialBanner: def __init__(self, content=None, leading=None, actions=None): if content is not None: assert hasattr(content, 'render') and callable(content.render) if leading is not None: assert isinstance(leading, Icon) if actions is not None: assert isinstance(actions, (tuple, list)) for action in actions: assert hasattr(action, 'render') and callable(action.render) self.content = content self.leading = leading self.actions = actions def render(self): e = maketag('div', {'class': 'mdc-banner', 'role': 'banner'}, style={'display': 'flex', 'flex-flow': 'column', 'align-items': 'center', 'justify-content': 'center', 'width': '100%', 'height': '100%'}) con = maketag('div', {'class': 'mdc-banner__content', 'role': 'alertdialog', 'aria-live': 'assertive'}) e.appendChild(con) gtext = maketag('div', {'class': 'mdc-banner__graphic-text-wrapper'}) con.appendChild(gtext) if self.leading is not None: graphic = maketag('div', {'class': 'mdc-banner__graphic', 'role': 'img'}) icon = maketag('i', {'class': 'material-icons mdc-banner__icon'}) icon.appendChild(javascript.document.createTextNode(self.leading.icon)) graphic.appendChild(icon) gtext.appendChild(graphic) cont = maketag('div', {'class': 'mdc-banner__text'}) gtext.appendChild(cont) if self.content is not None: cont.appendChild(self.content.render()) if self.actions is not None: for action in self.actions: action = action.render() add_class(action, 'mdc-banner__actions') con.appendChild(action) javascript.mdc.banner.MDCBanner.new(e) return e class FlatButton: def __init__(self, child, onPressed): assert isinstance(child, Text) if onPressed is not None: assert callable(onPressed) self.child = child self.onPressed = onPressed def render(self): e = maketag('button', {'class': 'mdc-button mdc-banner__primary-action'}) e.appendChild(self.child.render()) rip = maketag('span', {'class': 'mdc-button__ripple'}) e.appendChild(rip) if self.onPressed is not None: e.bind('click', self.onPressed) javascript.mdc.ripple.MDCRipple.new(e) return e ``` 2. Buttons ![输入图片说明](pics/buttons.png) ```python class TextButton: def __init__(self, onPressed=None, icon=None, label=None): self.onPressed = onPressed if icon is not None: assert isinstance(icon, Icon) self.icon = icon if label is not None: assert isinstance(label, Text) self.label = label def render(self): tb = maketag('div', {'class': 'mdc-touch-target-wrapper'}, style={'display': 'flex'}) butt = maketag('button', {'class': 'mdc-button mdc-button--touch'}) rip = maketag('span', {'class': 'mdc-button__ripple'}) but_tou = maketag('span', {'class': 'mdc-button__touch'}) if self.icon is not None: ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'}) ic.appendChild(javascript.document.createTextNode(self.icon.icon)) if self.label is not None: la = maketag('span', {'class': 'mdc-button__label'}) la.appendChild(self.label.render()) butt.appendChild(rip) butt.appendChild(but_tou) butt.appendChild(ic) butt.appendChild(la) tb.appendChild(butt) return tb class OutlinedButton: def __init__(self, onPressed=None, icon=None, label=None): self.onPressed = onPressed if icon is not None: assert isinstance(icon, Icon) self.icon = icon if label is not None: assert isinstance(label, Text) self.label = label def render(self): butt = maketag('button', {'class': 'mdc-button mdc-button--outlined mdc-button--icon-leading'}, style={'display': 'flex'}) rip = maketag('span', {'class': 'mdc-button__ripple'}) if self.icon is not None: ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'}) ic.appendChild(javascript.document.createTextNode(self.icon.icon)) if self.label is not None: la = maketag('span', {'class': 'mdc-button__label'}) la.appendChild(self.label.render()) butt.appendChild(rip) butt.appendChild(ic) butt.appendChild(la) return butt class ContainedButton: def __init__(self, onPressed=None, icon=None, label=None): self.onPressed = onPressed if icon is not None: assert isinstance(icon, Icon) self.icon = icon if label is not None: assert isinstance(label, Text) self.label = label def render(self): butt = maketag('button', {'class': 'mdc-button mdc-button--raised mdc-button--leading'}, style={'display': 'flex'}) rip = maketag('span', {'class': 'mdc-button__ripple'}) if self.icon is not None: ic = maketag('i', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'}) ic.appendChild(javascript.document.createTextNode(self.icon.icon)) if self.label is not None: la = maketag('span', {'class': 'mdc-button__label'}) la.appendChild(self.label.render()) butt.appendChild(rip) butt.appendChild(ic) butt.appendChild(la) return butt ``` 3. Cards ![输入图片说明](pics/cards.png) ```python class Card: def __init__(self, clipBehavior=None, priActions=None, actions=None): self.clipBehavior = clipBehavior if priActions is not None: assert isinstance(priActions, (tuple, list)) for preAct in priActions: assert hasattr(preAct, 'render') and callable(preAct.render) self.priActions = priActions if actions is not None: assert hasattr(actions, 'render') and callable(actions.render) self.actions = actions def render(self): card = maketag('div', {'class': 'mdc-card'}, style={'width': '500px', 'height': '150px', 'text-align': 'center'}) pri_act = maketag('div', {'class': 'mdc-card__primary-action'}) if self.priActions is not None: media = maketag('div', {'class': 'mdc-card__media mdc-card__media--square'}) media_con = maketag('div', {'class': 'mdc-card__media-content'}) for priAct in self.priActions: media_con.appendChild(priAct.render()) media.appendChild(media_con) rip = maketag('div', {'class': 'mdc-card__ripple'}) pri_act.appendChild(media) pri_act.appendChild(rip) acts = maketag('div', {'class': 'mdc-card__actions'}) if self.actions is not None: acts.appendChild(self.actions.render()) card.appendChild(pri_act) card.appendChild(acts) return card class ButtonBar: def __init__(self, alignment=None, children=None): self.alignment = alignment if children is not None: assert isinstance(children, (tuple, list)) for child in children: assert hasattr(child, 'render') and callable(child.render) self.children = children def render(self): act_but = maketag('div', {'class': 'mdc-card__action-buttons'}) if self.children is not None: for child in self.children: act_but.appendChild(child.render()) return act_but ``` 4. Chips ![输入图片说明](pics/chips.png) ```python class Chips: def __init__(self, children=None): if children is not None: assert isinstance(children, (tuple, list)) for child in children: assert hasattr(child, 'render') and callable(child.render) self.children = children def render(self): ichip = maketag('span', {'class': 'mdc-evolution-chip-set', 'role': 'grid'}) pre = maketag('span', {'class': 'mdc-evolution-chip-set__chips', 'role': 'presentation'}, style={'display': 'flex'}) ichip.appendChild(pre) if self.children is not None: for child in self.children: pre.appendChild(child.render()) return ichip class InputChip: def __init__(self, avatar=None, label=None, onSelected=False): if avatar is not None: assert isinstance(avatar, Icon) self.avatar = avatar if label is not None: assert isinstance(label, Text) self.label = label self.onSelected = onSelected def render(self): mec = maketag('span', {'class': 'mdc-evolution-chip', 'role': 'row'}) mecc = maketag('span', {'class': 'mdc-evolution-chip__cell mdc-evolution-chip__cell--primary', 'role': 'gridcell'}) mec.appendChild(mecc) butt = maketag('button',{'class': 'mdc-evolution-chip__action mdc-evolution-chip__action--primary', 'type': 'button', 'tabindex': '0'}, style={'display': 'flex', 'align-items': 'center'}) # rip = maketag('span', {'class': 'mdc-evolution-chip__ripple mdc-evolution-chip__ripple--primary'}) rip = maketag('span', {'class': 'mdc-button__ripple'}) butt.appendChild(rip) if self.avatar is not None: ava = maketag('span', {'class': 'material-icons mdc-button__icon', 'aria-hidden': 'true'}) ava.appendChild(javascript.document.createTextNode(self.avatar.icon)) butt.appendChild(ava) if self.label is not None: lab = maketag('span', {'class': 'mdc-evolution-chip__text-label'}) lab.appendChild(self.label.render()) butt.appendChild(lab) mecc.appendChild(butt) return mec ``` 5. Lists ![输入图片说明](pics/lists.png) ```python class ListView: def __init__(self, children): if children is not None: assert isinstance(children, (tuple, list)) for child in children: assert hasattr(child, 'render') and callable(child.render) self.children = children def render(self): list = maketag('ul', {'class': 'mdc-list'}) if self.children is not None: for child in self.children: child = child.render() list.appendChild(child) javascript.mdc.list.MDCList.new(list) return list class ListTile: def __init__(self, title, subtitle=None, leading=None, trailing=None): assert isinstance(title, Text) if subtitle is not None: assert isinstance(subtitle, Text) if leading is not None: assert isinstance(leading, Icon) if trailing is not None: assert hasattr(trailing, 'render') and callable(trailing.render) self.title = title self.subtitle = subtitle self.leading = leading self.trailing = trailing def render(self): lt = maketag('li', {'class': 'mdc-list-item'}) rip = maketag('span', {'class': 'mdc-list-item__ripple'}) lt.appendChild(rip) if self.leading is not None: icon = maketag('i', {'class': 'material-icons mdc-list-item_graphic', 'aria-hidden': 'true'}) icon.appendChild(javascript.document.createTextNode(self.leading.icon)) lt.appendChild(icon) text_ = maketag('span', {'class': 'mdc-list-item__text'}) if self.subtitle is not None: pri_text = maketag('span', {'class': 'mdc-list-item__primary-text'}) pri_text.appendChild(self.title.render()) sec_text = maketag('span', {'class': 'mdc-list-item__secondary-text'}) sec_text.appendChild(self.subtitle.render()) text_.appendChild(pri_text) text_.appendChild(sec_text) else: text_.appendChild(self.title.render()) lt.appendChild(text_) return lt ``` 6. Menus ![输入图片说明](pics/menus.png) ```python class PopupMenuButton: def __init__(self, icon=None, itemBuilder=None): if icon is not None: assert isinstance(icon, Icon) if itemBuilder is not None: assert isinstance(itemBuilder, (tuple, list)) for item in itemBuilder: assert hasattr(item, 'render') and callable(item.render) self.icon = icon self.itemBuilder = itemBuilder def render(self): menu = maketag('div', {'class': 'mdc-menu mdc-menu-surface mdc-menu-surface--is--open-below mdc-menu-surface--open'}, style={'display': 'flex'}) # javascript.mdc.menu.MDCMenu.new(menu) builder = maketag('ul', {'class': 'mdc-list', 'role': 'menu', 'aria-hidden': 'true', 'aria-orientation': 'vertical', 'tabindex': '-1'}) menu.appendChild(builder) if self.itemBuilder is not None: for item in self.itemBuilder: builder.appendChild(item.render()) return menu class PopupMenuItem: def __init__(self, child): assert hasattr(child, 'render') and callable(child.render) self.child = child def render(self): if isinstance(self.child, ListTile): return self.child.render() else: menuItem = maketag('li', {'class': 'mdc-list-item', 'role': 'menuitem'}) rip = maketag('span', {'class': 'mdc-list-item__ripple'}) menuItem.appendChild(rip) text = maketag('span', {'class': 'mdc-list-item__text'}) text.appendChild(self.child.render()) menuItem.appendChild(text) return menuItem class PopupMenuDivider: def render(self): div = maketag('li', {'class': 'mdc-list-divider', 'role': 'separator'}) return div ``` #### 测试代码(主要部分) 1. Banners ```python def banner(): return Scaffold( appBar=AppBar( title=Text('Banners Demo'), ), body=Center( children=[ MaterialBanner( content=Text('Your password was updated on your other device. Please sign in again.'), leading=Icon(Icons.error_outline), actions=[ FlatButton( child=Text('CONTINUE AS A GUEST'), onPressed=None, ), FlatButton( child=Text('SIGN IN'), onPressed=None, ), ], ), ] ), ) ``` 2. Buttons ```python def buttons(): return Scaffold( appBar=AppBar( title=Text('Buttons Demo'), ), body=Center( children=[ TextButton( icon=Icon(Icons.bookmark), label=Text("TEXT BUTTON"), ), OutlinedButton( icon=Icon(Icons.add), label=Text("OUTLINED BUTTON"), ), ContainedButton( icon=Icon(Icons.start), label=Text("CONTAINED BUTTON"), ) ] ), ) ``` 3. Cards ```python def cards(): return Scaffold( appBar=AppBar( title=Text('Cards Demo'), ), body=Center( children=[ Card( clipBehavior=None, priActions=[ ListTile( leading=Icon(Icons.arrow_drop_down_circle), title=Text('Card title 1'), subtitle=Text( 'Secondary Text', # style=TextStyle(color=Colors.black.withOpacity(0.6)) ), ), ], actions=ButtonBar( alignment=MainAxisAlignment.start, children=[ TextButton( icon=Icon(Icons.add), label=Text("Action 1"), ), TextButton( icon=Icon(Icons.delete), label=Text("Action 2"), ), TextButton( icon=Icon(Icons.star), label=Text("Action 3"), ), TextButton( icon=Icon(Icons.adobe), label=Text("Action 4"), ) ], ), ), ], ), ) ``` 4. Chips ```python def chips(): return Scaffold( appBar=AppBar( title=Text('Chips Demo'), ), body=Center( children=[ Chips( children=[ InputChip( avatar=Icon(Icons.add), label=Text('Chip 1'), onSelected=False ), InputChip( avatar=Icon(Icons.remove), label=Text('Chip 2'), onSelected=False ), InputChip( avatar=Icon(Icons.delete), label=Text('Chip 3'), onSelected=False ), ], ), ], ), ) ``` 5. Lists ```python def lists(): return Scaffold( appBar=AppBar( title=Text('Lists Demo'), ), body=Center( children=[ ListView( # single-line list children=[ ListTile( title=Text('SingleList item 1'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ListTile( title=Text('SingleList item 2'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ListTile( title=Text('SingleList item 3'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ListTile( title=Text('Two-lineList item 1'), subtitle=Text('Secondary text'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ListTile( title=Text('Two-lineList item 2'), subtitle=Text('Secondary text'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ListTile( title=Text('Two-lineList item 3'), subtitle=Text('Secondary text'), leading=Icon(Icons.label), trailing=Text('Metadata'), ), ], ), ], ), ) ``` 6. Menus ```python def menus(): return Scaffold( appBar=AppBar( title=Text('Menus Demo'), ), body=Center( children=[ PopupMenuButton( # icon=Icon(Icons.more_vert), itemBuilder=[ PopupMenuItem( child=ListTile( # leading=Icon(Icons.add), # title=Text('Item 1'), leading=Icon(Icons.cancel), title=Text('Bananas'), ), ), PopupMenuItem( child=ListTile( # leading=Icon(Icons.anchor), # title=Text('Item 2'), leading=Icon(Icons.star), title=Text('Apples'), ), ), PopupMenuItem( child=ListTile( # leading=Icon(Icons.article), # title=Text('Item 3'), leading=Icon(Icons.upload), title=Text('Strawberries'), ), ), # PopupMenuDivider(), # PopupMenuItem(child=Text('Item A')), # PopupMenuItem(child=Text('Item B')), PopupMenuDivider(), PopupMenuItem(child=Text('Vegetables')), PopupMenuItem(child=Text('Meat')), PopupMenuDivider(), PopupMenuItem(child=Text('Clothes')), PopupMenuItem(child=Text('Furniture')), ], ), ] ), ) def run_app(): menu = menus() javascript.document.body.appendChild(menu.render()) ``` #### 测试结果 1. Banners ![banners_test_result](test_result/banner_result.png) 2. Buttons ![buttons_test_result](test_result/buttons_result.png) 3. Cards ![cards_test_result](test_result/cards_result.png) 4. Chips ![chips_test_result](test_result/chips_result.png) 5. Lists ![lists_test_result](test_result/lists_result.png) 6. Menus ![menus_test_result](test_result/menus_result.png) ![menus_test_result2](test_result/menus_result2.png)