├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── bash ├── controls │ ├── barchart.sh │ ├── button.sh │ ├── callout.sh │ ├── checkbox.sh │ ├── choicegroup.sh │ ├── datepicker.sh │ ├── dialog.sh │ ├── dropdown.sh │ ├── grid.sh │ ├── icon.sh │ ├── iframe.sh │ ├── image.sh │ ├── linechart.sh │ ├── link.sh │ ├── message.sh │ ├── nav.sh │ ├── panel.sh │ ├── piechart.sh │ ├── searchbox.sh │ ├── slider.sh │ ├── spinbutton.sh │ ├── tabs.sh │ ├── text.sh │ ├── theme_example.sh │ ├── toggle.sh │ ├── toolbar.sh │ └── vertical_barchart.sh ├── greeter │ ├── greeter-app.sh │ └── greeter.sh ├── hello-world │ ├── hello-app.sh │ └── hello.sh └── todo │ └── todo.sh ├── csharp ├── .gitignore ├── Buttons │ ├── Buttons.csproj │ └── Program.cs ├── PgletExamples.sln └── Stack │ ├── Program.cs │ └── Stack.csproj ├── node ├── greeter │ ├── greeter-app.js │ └── greeter.js └── hello-world │ ├── hello-app.js │ ├── hello.js │ └── hello.ts ├── package-lock.json ├── package.json ├── pglet.sh ├── powershell ├── controls │ ├── buttons.ps1 │ ├── html.ps1 │ ├── iframe.ps1 │ ├── progress.ps1 │ ├── signin-entire-app.ps1 │ ├── signin-on-demand.ps1 │ ├── stack.ps1 │ └── textbox.ps1 ├── greeter │ ├── greeter-app.ps1 │ └── greeter.ps1 ├── hello-world │ ├── hello-app.ps1 │ └── hello.ps1 ├── monitor │ └── monitor.ps1 └── remote-console │ └── remote-console.ps1 └── python ├── README.md ├── controls ├── barchart_control.py ├── button │ ├── action_button.py │ ├── basic_buttons.py │ ├── button_control.py │ ├── button_with_click_event.py │ ├── buttons_with_icons.py │ ├── compound_buttons.py │ ├── context_menu_buttons.py │ ├── icon_only_buttons.py │ ├── link_buttons.py │ ├── split_buttons.py │ └── toolbar_buttons.py ├── callout │ ├── basic_callout.py │ ├── callout_cover_target.py │ └── callout_with_directional_hint.py ├── checkbox │ ├── basic_checkboxes.py │ ├── checkbox_control.py │ └── checkbox_with_change_event.py ├── choicegroup │ ├── basic_choicegroup.py │ ├── change_choicegroup_options.py │ ├── choicegroup_control.py │ ├── choicegroup_with_change_event.py │ └── choicegroup_with_icons.py ├── datepicker │ ├── basic_datepicker.py │ ├── datepicker_allow_text_input.py │ ├── datepicker_control.py │ └── datepicker_with_change_event.py ├── dialog │ └── basic_dialog.py ├── dropdown │ ├── basic_dropdown.py │ ├── change_dropdown_options.py │ ├── dropdown_control.py │ ├── dropdown_with_change_event.py │ └── dropdown_with_label_and_placeholder.py ├── form_control │ ├── README.md │ ├── main.py │ └── manual_content.py ├── grid │ ├── basic_grid.py │ ├── compact_grid.py │ ├── dynamic_grid.py │ ├── grid_control.py │ └── sortable_grid.py ├── icon │ ├── icon_control.py │ └── icons.py ├── image_control.py ├── linechart_control.py ├── link │ ├── basic_links.py │ ├── link_control.py │ ├── link_with_child_controls.py │ └── link_with_click_event.py ├── message │ ├── basic_messages.py │ ├── message_control.py │ ├── message_with_dismiss_event.py │ ├── message_with_dismiss_event_and_buttons.py │ ├── messages_with_buttons.py │ └── truncated_message.py ├── nav_control.py ├── panel │ ├── basic_panel.py │ ├── panel-autodismiss.py │ ├── panel-custom.py │ ├── panel-dismiss-options.py │ └── panel-size.py ├── piechart_control.py ├── progress │ ├── basic_progress.py │ ├── indeterminate_progress.py │ └── progress_control.py ├── resize_stacks.py ├── searchbox │ ├── basic_searchboxes.py │ ├── searchbox-with-change-event.py │ ├── searchbox-with-search-clear-escape-events.py │ └── searchbox_control.py ├── signin_app.py ├── slider │ ├── basic_sliders.py │ ├── slider-with-change-event.py │ ├── slider_control.py │ └── sliders-with-values.py ├── spinbutton │ ├── basic_spinbutton.py │ ├── spinbutton_control.py │ └── spinbutton_with_change_event.py ├── spinner │ ├── spinner_control.py │ ├── spinner_label_positioning.py │ └── spinner_size.py ├── split.py ├── stack │ ├── horizontal_stack_gap_padding.py │ ├── horizontal_stack_horizontal_alignments.py │ ├── horizontal_stack_vertical_alignments.py │ ├── horizontal_stack_wrapping.py │ ├── stack_control.py │ ├── stack_with_submit_event.py │ └── vertical_stack_vertical_alignments.py ├── tabs_control.py ├── text │ ├── text_alignments.py │ ├── text_control.py │ ├── text_font_styles.py │ ├── text_markdown.py │ ├── text_rounded_corners.py │ └── text_size.py ├── textbox │ ├── basic_textboxes.py │ ├── multiline_textboxes.py │ ├── password_with_reveal_button.py │ ├── required_textboxes.py │ ├── suffix_prefix_textboxes.py │ ├── textbox-with-change-event.py │ ├── textbox_control.py │ └── underlined_and_borderless_textboxes.py ├── toggle │ ├── basic_toggles.py │ ├── toggle_control.py │ ├── toggle_with_change_event.py │ └── toggles_with_inline_labels.py ├── toolbar_control.py └── vertical_barchart_control.py ├── greeter └── greeter.py ├── hello-world ├── hello-app.py └── hello.py ├── icon-browser ├── fluent-icons.txt └── main.py ├── todo ├── README.md ├── todo-app-class.py ├── todo-complete.py ├── todo-with-delete.py └── todo-with-filter.py └── wordle └── main.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Appveyor Systems Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pglet Examples 2 | 3 | Pglet ("piglet") is a rich user interface (UI) framework for scripts and programs written in any language and a service for securely sharing your application UI. 4 | 5 | This repository contains sample applications using [Pglet framework](https://pglet.io) in different languages: 6 | 7 | * [Python](python) 8 | * [Bash](bash) 9 | * [PowerShell](powershell) 10 | * [C#](bash) 11 | * [JavaScript](node) 12 | -------------------------------------------------------------------------------- /bash/controls/barchart.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | text value='Horizontal Bar Chart' size=xlarge 7 | barChart dataMode=fraction width='50%' tooltips 8 | data 9 | p legend='C:' x=20 y=250 xtooltip='20%' ytooltip='250 GB' 10 | p legend='D:' x=50 y=250 xtooltip='50%' color=yellow 11 | p legend='E:' x=30 y=250 xtooltip='30%' 12 | " 13 | } 14 | 15 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/button.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function buttons() { 5 | pglet_send " 6 | add 7 | stack gap=30 8 | 9 | stack 10 | text value='Regular buttons' size=large 11 | stack horizontal 12 | button text='Standard' 13 | button disabled text='Standard disabled' 14 | stack horizontal 15 | button primary text='Primary' 16 | button primary disabled text='Primary disabled' 17 | 18 | stack 19 | text value='Compound buttons' size=large 20 | stack horizontal 21 | button compound text='Compound' secondaryText='This is a secondary text' 22 | button primary compound text='Primary compound' secondaryText='This is a secondary text' 23 | 24 | stack 25 | text value='Buttons with icon' size=large 26 | stack horizontal 27 | button primary icon='AddFriend' text='Create account' 28 | button icon='Add' text='New item' 29 | button icon='Delete' text='Delete' 30 | 31 | stack 32 | text value='Toolbar buttons' size=large 33 | stack horizontal 34 | button toolbar icon='Add' text='New item' 35 | button toolbar icon='Mail' text='Send' 36 | button toolbar icon='ChevronDown' text='Show example' 37 | button toolbar icon='Delete' iconColor=red text='Delete' 38 | 39 | stack 40 | text value='Icon only buttons' size=large 41 | stack horizontal 42 | button icon='Emoji2' title=Emoji! 43 | button icon='Calendar' title=Calendar! 44 | 45 | stack 46 | text value='Link buttons' size=large 47 | stack horizontal 48 | button action icon='Globe' text='Pglet website' url='https://pglet.io' newWindow 49 | button icon='MyMoviesTV' text='Go to Disney' url='https://disney.com' newWindow 50 | 51 | stack 52 | text value='Context menu buttons' size=large 53 | stack horizontal 54 | button icon='Add' text='New item' 55 | item text='Email message' icon='Mail' 56 | item text='Calendar event' icon='Calendar' 57 | button text='Button with sub-menus' 58 | item text='New' icon='Add' 59 | item text='Email message' icon='Mail' 60 | item text='Calendar event' icon='Calendar' 61 | item text='Share' icon='Share' split 62 | item text='Share to Twitter' key='sharetotwitter' 63 | item text='Share to Facebook' key='sharetofacebook' 64 | item text='Share to Somewhere' disabled 65 | item text='Share to Email' key='sharetoemail' 66 | item text='Share to Outlook' 67 | item text='Share to Gmail' 68 | item divider 69 | item text='To to Pglet' icon='Globe' iconColor=green url='https://pglet.io' newWindow secondaryText='New window' 70 | 71 | stack 72 | text value='Split buttons' size=large 73 | stack horizontal 74 | button split text='Standard' 75 | item text='Email message' icon='Mail' 76 | item text='Calendar event' icon='Calendar' 77 | button split primary text='Primary' 78 | item text='Email message' icon='Mail' 79 | item text='Calendar event' icon='Calendar' 80 | " 81 | } 82 | 83 | pglet_app "index" "buttons" -------------------------------------------------------------------------------- /bash/controls/callout.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page padding=0" 6 | pglet_send "add 7 | stack horizontal 8 | button id=showCallout text='Show bottom callout' 9 | button id=showCallout2 text='Show right callout' 10 | callout id=callout1 target='showCallout' focus=true visible=false 11 | stack padding=20 width=300 12 | text value='Choose your style' size=xlarge 13 | choicegroup 14 | option key=red 15 | option key=green 16 | option key=blue 17 | stack horizontal 18 | button id=yes primary text=Yes 19 | button id=no text=No 20 | callout id=callout2 target='showCallout2' beak=true cover=false position=rightTop pagePadding=0 visible=false 21 | stack padding=20 width=300 height=100 22 | text value='That\'s a button callout!' size=xlarge" 23 | 24 | while true 25 | do 26 | pglet_wait_event 27 | if [[ "$PGLET_EVENT_TARGET" == "showCallout" ]]; then 28 | pglet_send "set callout1 visible=true" 29 | elif [[ "$PGLET_EVENT_TARGET" == "showCallout2" ]]; then 30 | pglet_send "set callout2 visible=true" 31 | fi 32 | done 33 | } 34 | 35 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/checkbox.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | checkbox label='Unchecked checkbox' 7 | checkbox label='Checked checkbox' value='true' 8 | checkbox disabled label='Disabled checkbox' 9 | checkbox label='Checkbox with rendered boxSide=\'end\'' boxSide=end 10 | " 11 | } 12 | 13 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/choicegroup.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | stack gap=30 7 | 8 | stack 9 | text value='Basic ChoiceGroup' size=large 10 | choicegroup label='Select color' value='green' 11 | option key=red 12 | option key=green 13 | option key=blue 14 | 15 | stack 16 | text value='ChoiceGroup with icons' size=large 17 | choicegroup label='Pick one icon' 18 | option key=day text=Day icon=CalendarDay 19 | option key=week text=Week icon=CalendarWeek 20 | option key=month text=Month icon=Calendar 21 | " 22 | } 23 | 24 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/datepicker.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | datepicker label='Start date' value='10/02/2021' 7 | datepicker label='End date' 8 | datepicker allowTextInput label='Allow text input' 9 | datepicker allowTextInput label='Allow text input with placeholder' placeholder='Select date...' width='30%' 10 | datepicker value='01/01/2012' allowTextInput label='Required' placeholder='Select date...' width='30%' 11 | " 12 | } 13 | 14 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/dialog.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | button id=openMinimal text='Open minimal dialog' 8 | dialog id=dialogMinimal title='Hello' close 9 | text value='Hi, are you OK?' 10 | footer 11 | button text=Yes 12 | button text=No 13 | 14 | button id=openBasic text='Open basic dialog' 15 | dialog id=dialogBasic blocking=false type=largeHeader title='Missing Subject' subText='Do you want to send this message without a subject?' 16 | footer 17 | button id=yes primary text=Yes 18 | button id=no text=No 19 | 20 | button id=open text='Open dialog' 21 | dialog id=dialog blocking=true type=close title='Missing Subject' subText='Do you want to send this message without a subject?' width=600 22 | choicegroup id=color 23 | option key=red 24 | option key=green 25 | option key=blue 26 | footer 27 | button id=yes primary text=Yes 28 | button id=no text=No 29 | " 30 | 31 | while true 32 | do 33 | pglet_wait_event 34 | echo "Event: $PGLET_EVENT_TARGET $PGLET_EVENT_NAME $PGLET_EVENT_DATA" 35 | 36 | if [[ "$PGLET_EVENT_TARGET" == "openBasic" ]]; then 37 | pglet_send "set dialogBasic open=true" 38 | elif [[ "$PGLET_EVENT_TARGET" == "openMinimal" ]]; then 39 | pglet_send "set dialogMinimal open=true" 40 | elif [[ "$PGLET_EVENT_TARGET" == "open" ]]; then 41 | pglet_send "set dialog open=true" 42 | elif [[ "$PGLET_EVENT_TARGET" == "dialog:yes" ]] || [[ "$PGLET_EVENT_TARGET" == "dialog:no" ]]; then 43 | pglet_send "set dialog open=false" 44 | fi 45 | done 46 | } 47 | 48 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/dropdown.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=30" 6 | pglet_send "add 7 | stack 8 | text value='Basic dropdown' size=xLarge 9 | dropdown 10 | option key=Red 11 | option key=Green 12 | option key=Blue 13 | 14 | stack 15 | text value='Dropdown with label and placeholder' size=xLarge 16 | dropdown label=Color placeholder='What\'s your favourite color?' 17 | option key=Red 18 | option key=Green 19 | option key=Blue 20 | " 21 | } 22 | 23 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/grid.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send " 7 | add 8 | stack gap=30 9 | 10 | stack width='50%' 11 | text value='Basic grid' size=large 12 | grid 13 | columns 14 | column name='First name' fieldName='first_name' 15 | column name='Last name' fieldName='last_name' 16 | column name='Age' fieldName='age' 17 | items 18 | item first_name='John' last_name='Smith' age=30 19 | item first_name='Samantha' last_name='Fox' age=43 20 | item first_name='Alice' last_name='Brown' age=25 21 | 22 | stack 23 | text value='Sortable grid with resizable columns and selectable rows' size=large 24 | grid selection=single preserveSelection 25 | columns 26 | column resizable sortable name='First name' fieldName='first_name' 27 | column resizable sortable sorted=asc name='Last name' fieldName='last_name' 28 | column resizable sortable=number name='Age' fieldName='age' 29 | items 30 | item first_name='Alice' last_name='Brown' age=25 31 | item first_name='Samantha' last_name='Fox' age=43 32 | item first_name='John' last_name='Smith' age=30 33 | 34 | stack 35 | text value='Compact grid with no header and multiple selection' size=large 36 | grid compact headerVisible=false selection=multiple 37 | columns 38 | column maxWidth=100 fieldName='first_name' 39 | column maxWidth=100 fieldName='last_name' 40 | column maxWidth=100 fieldName='age' 41 | items 42 | item first_name='John' last_name='Smith' age=30 43 | item first_name='Samantha' last_name='Fox' age=43 44 | item first_name='Alice' last_name='Brown' age=25 45 | 46 | stack 47 | text value='Grid with template columns and auto-generated items' size=large 48 | grid id=grid1 shimmerLines=5 selection=single preserveSelection 49 | columns 50 | column onClick name='File Type' icon=Page iconOnly fieldName='iconName' minWidth=20 maxWidth=20 51 | icon name=Package size=16 52 | column resizable sortable name='Name' fieldName='name' 53 | text value='{name}' 54 | column resizable name='Write' fieldName='write' 55 | stack horizontal height='100%' verticalAlign=center 56 | checkbox value='{write}' 57 | column resizable name='Color' fieldName='read' 58 | dropdown value='{color}' data='{key}' placeholder=select 59 | option key=red text='Red' 60 | option key=green text='Green' 61 | option key=blue text='Blue' 62 | column resizable sortable name='Description' fieldName='description' 63 | textbox value='{description}' 64 | column sortable=number name='Action' fieldName='key' minWidth=150 65 | stack horizontal height='100%' verticalAlign=center 66 | link url='{key}' value='{iconName}' visible=false 67 | link url='{key}' value='{name}' visible=false 68 | button icon='Edit' title='Edit todo' width=16 height=16 visible=true data='{key}' 69 | button icon='Delete' iconColor=red title='Delete todo' width=16 height=16 visible=true data='{key}' 70 | items id=items 71 | " 72 | 73 | # small delay before adding grid items, so you can see a shimmer 74 | sleep 5 75 | 76 | total_items=10 77 | cmd="replace to=grid1:items" 78 | for ((i=1;i<=$total_items;i++)); do 79 | cmd="$cmd 80 | item key=item$i name='Item $i' iconName='ItemIcon$i'" 81 | done 82 | pglet_send "$cmd" 83 | } 84 | 85 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/icon.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | stack horizontal 8 | icon name=ChangeEntitlements color=SlateGray 9 | icon name=shop color=Khaki 10 | icon name=TrainSolid 11 | stack horizontal verticalAlign=center 12 | icon name=BlockedSite color=Maroon size=25px 13 | icon name=settings color=SlateBlue size=50px 14 | icon name=save size=100px 15 | " 16 | } 17 | 18 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/iframe.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | iframe src='https://pglet.io' width='100%' height=300 border='2px solid #eee' 7 | " 8 | } 9 | 10 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/image.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | text value='No image fit' size=xlarge 8 | text size=medium value='With no imageFit property set, the width and height props control the size of the frame. Depending on which of those props is used, the image may scale to fit the frame.' 9 | 10 | text size=small value='Without a width or height specified, the frame remains at its natural size and the image will not be scaled.' 11 | image src='https://via.placeholder.com/350x150' title='sample image' alt='Example with no image fit value and no height or width is specified.' 12 | image width=600 src='https://via.placeholder.com/350x150' alt='Example with no image fit value and only width is specified.' 13 | image height=100 src='https://via.placeholder.com/350x150' alt='Example with no image fit value and only height is specified.' 14 | image width=100 height=100 src='https://via.placeholder.com/350x150' alt='Example with no image fit value and height or width is specified' 15 | 16 | text value='fit: center' size=xlarge 17 | image fit=center width=350 height=150 src='https://via.placeholder.com/800x300' alt='Example of the image fit value \'center\' on an image larger than the frame.' 18 | " 19 | } 20 | 21 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/linechart.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | text value='Line chart' size=xlarge 7 | lineChart legend tooltips xtype=date yticks=10 ymax=100 yformat='{y}%' width='100%' height=300 8 | data legend='Line A' 9 | p x='2020-03-03T00:00:00.000Z' y=10 10 | p x='2020-03-03T10:00:00.000Z' y=50 11 | p x='2020-03-03T11:00:00.000Z' y=70 12 | data legend='Line B' 13 | p x='2020-03-03T00:00:00.000Z' y=30 14 | p x='2020-03-04T00:00:00.000Z' y=20 15 | p x='2020-03-05T00:00:00.000Z' y=90 16 | " 17 | } 18 | 19 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/link.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | link url='http://google.com' value='Visit Google' newWindow 8 | link value='Link without URL' size=large 9 | link url='http://google.com' value='Cannot visit this link' disabled 10 | " 11 | } 12 | 13 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/message.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send "add 7 | message value='This is just a message.' 8 | message type=success value='All files have been successfully copied.' dismiss 9 | message type=error value='User with specified email was not found.' dismiss 10 | message type=blocked truncated value='Blocked MessageBar - single line, with dismiss button and truncated text. Truncation is not available if you use action buttons or multiline and should be used sparingly. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris. You\'ve been warned!' dismiss 11 | message type=warning dismiss value='Watch out! You\'ve been warned!' 12 | button text=Yes action=yes 13 | button text=No action=no 14 | message type=warning multiline value='Warning defaults to multiline. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.' 15 | button text=OK 16 | button text=Cancel 17 | " 18 | } 19 | 20 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/nav.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send " 6 | add 7 | stack gap=30 8 | 9 | stack 10 | text value='Nav with groups' size=large 11 | nav 12 | item text='Actions' 13 | item expanded text='New' 14 | item key='email' text='Email message' icon='Mail' 15 | item key='calendar' text='Calendar event' icon='Calendar' iconColor=salmon 16 | item text='Share' collapsed 17 | item disabled key=share text='Share to Facebook' icon='Share' 18 | item key=twitter text='Share to Twitter' 19 | item text='Links' collapsed 20 | item text='Pglet website' icon='NavigateExternalInline' url='https://pglet.io' newWindow 21 | item text='Google website' icon='NavigateExternalInline' url='https://google.com' newWindow 22 | 23 | stack 24 | text value='Nav without groups' size=large 25 | nav 26 | item 27 | item expanded text='New' 28 | item key='email' text='Email message' icon='Mail' 29 | item key='calendar' text='Calendar event' icon='Calendar' 30 | item text='More options' 31 | item key='option' text='Web component' icon='WebComponents' 32 | item expanded text=Share 33 | item key=facebook text='Share on Facebook' icon='Share' 34 | item key=twitter text='Share to Twitter' icon='Share' 35 | " 36 | } 37 | 38 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/panel.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | button id=open text='Open panel' 8 | panel blocking lightDismiss autodismiss=false id=panel title='Missing Subject' type=small 9 | choicegroup 10 | option key=Red 11 | option key=Green 12 | option key=Blue 13 | footer 14 | stack horizontal 15 | button id=yes primary text=Yes 16 | button id=no text=No 17 | " 18 | 19 | while true 20 | do 21 | pglet_wait_event 22 | echo "Event: $PGLET_EVENT_TARGET $PGLET_EVENT_NAME $PGLET_EVENT_DATA" 23 | 24 | if [[ "$PGLET_EVENT_TARGET" == "open" ]]; then 25 | pglet_send "set panel open=true" 26 | elif [[ "$PGLET_EVENT_TARGET" == "panel" && "$PGLET_EVENT_NAME" == "dismiss" ]] ; then 27 | pglet_send "set panel open=false" 28 | elif [[ "$PGLET_EVENT_TARGET" == "panel:yes" ]] || [[ "$PGLET_EVENT_TARGET" == "panel:no" ]]; then 29 | pglet_send "set panel open=false" 30 | fi 31 | done 32 | } 33 | 34 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/piechart.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | text value='Pie chart' size=xlarge 7 | 8 | pieChart width='100%' innerRadius=40 innerValue=42 9 | data 10 | p color='yellow' legend='' value=20 11 | p color='green' legend='' value=30 12 | 13 | pieChart legend tooltips width='100%' innerRadius=40 innerValue=42 14 | data 15 | p legend='Free space' value=20 tooltip='20%' 16 | p legend='Total space' value=50 tooltip='50%' 17 | p legend='Reserved space' value=30 tooltip='30%' 18 | p legend='A' value=1 tooltip='20%' 19 | p legend='B' value=2 tooltip='50%' 20 | p legend='C' value=3 tooltip='30%'" 21 | } 22 | 23 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/searchbox.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send "add 7 | stack gap=30 8 | 9 | stack 10 | text value='Default SearchBox' size=large 11 | searchbox 12 | 13 | stack 14 | text value='Underlined SearchBox' size=large 15 | searchbox underlined placeholder='Search files and folders' 16 | 17 | stack 18 | text value='Disable SearchBox' size=large 19 | searchbox disabled placeholder='Search something...' 20 | searchbox underlined disabled placeholder='Search something...' 21 | 22 | stack 23 | text value='SearchBox with custom icon' size=large 24 | searchbox placeholder='Filter something by' icon=Filter iconColor=red 25 | " 26 | } 27 | 28 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/slider.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | stack width='50%' 7 | slider label='Default slider' 8 | slider label='Default disabled slider' disabled 9 | slider label='Slider with value' showValue value=4 10 | slider label='Slider with formatted value' showValue valueFormat='{value}%' 11 | slider showValue label='Origin from zero' min='-5' max=15 step=1 value=-2 12 | stack horizontal height=200px 13 | slider vertical label='Default slider' 14 | slider vertical label='Default disabled slider' disabled 15 | slider vertical label='Slider with value' showValue value=4 16 | slider vertical label='Slider with formatted value' showValue valueFormat='{value}%' 17 | slider vertical showValue label='Origin from zero' min='-5' max=15 step=1 value=-2 18 | " 19 | } 20 | 21 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/spinbutton.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=20" 6 | pglet_send "add 7 | spinButton label='Basic SpinButton:' min=0 max=100 step=1 value=0 8 | spinButton disabled label='Disabled SpinButton:' min=0 max=100 step=1 value=0 9 | spinButton icon=IncreaseIndentLegacy label='SpinButton with icon:' min=0 max=100 step=1 value=0 10 | " 11 | } 12 | 13 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/tabs.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send "add 7 | stack gap=30 8 | 9 | stack 10 | text value='Link tabs' size=large 11 | tabs id=t1 margin=10 12 | tab key=10 text='Regular tab' 13 | stack horizontal 14 | text value='This is tab1' 15 | text value='This is tab1 - line2' 16 | tab id=tab2 key=20 icon=Globe text='Tab with icon' 17 | stack gap=10 18 | text value='This is tab2' 19 | text value='This is tab2 - line2' 20 | tab key=30 text='Tab with icon and count' icon=Ringer count=30 21 | stack gap=10 22 | text value='This is tab3' 23 | text value='This is tab3 - line2' 24 | 25 | stack 26 | text value='Solid tabs' size=large 27 | tabs solid margin=10px 28 | tab text=JavaScript icon=Code count=10 29 | textbox label='Some textbox' 30 | tab text='C#' count=30 31 | button text='Hello button!' 32 | tab text=Python count=0 33 | text value='Just text...' 34 | " 35 | } 36 | 37 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/text.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function text() { 5 | pglet_send " 6 | add 7 | text value=Squares size=large 8 | stack horizontal 9 | text value='left top' align=left verticalAlign=top width=100 height=100 bgColor=Salmon color=white padding=5 10 | text value='center top' size=large align=center verticalAlign=top width=100 height=100 bgColor=Salmon color=white padding=5 border='1px solid #555' 11 | text value='right top' align=right verticalAlign=top width=100 height=100 bgColor=Salmon color=white padding=5 border='2px solid #555' 12 | stack horizontal 13 | text value='left center' align=left verticalAlign=center width=100 height=100 bgColor=PaleGoldenrod padding=5 14 | text value='center center' size=large align=center verticalAlign=center width=100 height=100 bgColor=PaleGoldenrod padding=5 padding=5 border='1px solid #555' 15 | text value='right center' align=right verticalAlign=center width=100 height=100 bgColor=PaleGoldenrod padding=5 border='2px solid #555' 16 | stack horizontal 17 | text value='left bottom' align=left verticalAlign=bottom width=6rem height=6rem bgColor=PaleGreen padding=5 18 | text value='center bottom' size=large align=center verticalAlign=bottom width=6rem height=6rem bgColor=PaleGreen padding=5 padding=5 border='1px solid #555' 19 | text value='right bottom' align=right verticalAlign=bottom width=6rem height=6rem bgColor=PaleGreen padding=5 border='2px solid #555' 20 | text value=Circles size=large 21 | stack horizontal 22 | text value='regular' align=center verticalAlign=center width=100px height=100px bgColor=Salmon color=white borderRadius=50 23 | text bold italic value='bold italic' align=center verticalAlign=center width=100 height=100 bgColor=PaleGoldenrod borderRadius=50 border='1px solid #555' 24 | text bold value='bold' align=center verticalAlign=center width=100 height=100 bgColor=PaleGreen color='#555' borderRadius=50 border='2px solid #555' 25 | text value=Markdown size=large 26 | stack 27 | text value='Code sample' size=xlarge 28 | text markdown value='\`\`\`powershell\n\$i = 0\nInvoke-Pglet ""clean page""\n\`\`\`' 29 | text value=Quotes size=large 30 | stack 31 | text value='""line 1""' 32 | text value='\'line 2\'' 33 | text value=""'line 3'"" 34 | 35 | " 36 | 37 | echo ' 38 | text value='"line 1"' 39 | text value='\'line 2\'' 40 | ' 41 | 42 | } 43 | 44 | pglet_app "index" "text" -------------------------------------------------------------------------------- /bash/controls/theme_example.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function theme() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send " 7 | add 8 | stack gap=30 9 | 10 | toggle id=theme label='Theme' inline offText=Light onText=Dark 11 | 12 | stack 13 | text value='Context menu buttons example' size=large 14 | stack horizontal 15 | button icon='Add' text='New item' 16 | item text='Email message' icon='Mail' 17 | item text='Calendar event' icon='Calendar' 18 | button split primary icon='Add' text='New item' 19 | item text='Email message' icon='Mail' 20 | item text='Calendar event' icon='Calendar' 21 | 22 | stack 23 | text value='Regular buttons example' size=large 24 | stack horizontal 25 | button text='Standard' 26 | button disabled text='Standard disabled' 27 | stack horizontal 28 | button primary text='Primary' 29 | button primary disabled text='Primary disabled' 30 | " 31 | 32 | while true 33 | do 34 | pglet_wait_event 35 | if [[ "$PGLET_EVENT_TARGET" == "theme" && "$PGLET_EVENT_DATA" == "true" ]]; then 36 | # Dark theme 37 | pglet_send "set page themePrimaryColor='#3ee66d' themeTextColor='#edd2b7' themeBackgroundColor='#262626'" 38 | elif [[ "$PGLET_EVENT_TARGET" == "theme" && "$PGLET_EVENT_DATA" == "false" ]]; then 39 | # Light theme 40 | pglet_send "set page themePrimaryColor='' themeTextColor='' themeBackgroundColor=''" 41 | fi 42 | done 43 | } 44 | 45 | pglet_app "index" "theme" -------------------------------------------------------------------------------- /bash/controls/toggle.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "add 6 | toggle label='Enabled and checked' value='true' 7 | toggle label='Enabled and unchecked' 8 | toggle disabled label='Disabled and checked' value='true' 9 | toggle disabled label='Disabled and unchecked' 10 | toggle inline label='With inline label' onText=On offText=Off 11 | toggle disabled inline label='Disabled with inline label' onText=On offText=Off 12 | toggle inline label='With inline label and without onText and offText' 13 | toggle disabled inline label='Disabled with inline label and without onText and offText' 14 | " 15 | } 16 | 17 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/toolbar.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page horizontalAlign='stretch'" 6 | pglet_send "add 7 | toolbar 8 | item text='New' icon='Add' 9 | item text='Email message' icon='Mail' 10 | item text='Calendar event' icon='Calendar' 11 | item id=share text='Share' icon='Share' split 12 | item text='Share to Twitter' data='sharetotwitter' 13 | item text='Share to Facebook' data='sharetofacebook' 14 | item text='Share to Somewhere' disabled 15 | item text='Share to Email' data='sharetoemail' 16 | item text='Share to Outlook' 17 | item text='Share to Gmail' 18 | item text='To to Google' icon='Globe' url='https://google.com' newWindow secondaryText='New window' 19 | overflow 20 | item text='Item 1' icon=Shop 21 | item text='Item 2' icon=Airplane 22 | far 23 | item text='Grid view' icon=Tiles iconOnly 24 | item text=Info icon=Info iconColor=green iconOnly 25 | " 26 | } 27 | 28 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/controls/vertical_barchart.sh: -------------------------------------------------------------------------------- 1 | # include Pglet helper 2 | source <(curl -s https://pglet.io/pglet.sh) 3 | 4 | function main() { 5 | pglet_send "set page gap=30" 6 | pglet_send "add 7 | text value='Vertical chart with textual x axis' size=xlarge 8 | verticalBarChart tooltips legend=false width='50%' height=300 yticks=5 barWidth1=20 yFormat='{y}%' 9 | data 10 | p id=rdp x=Red y=20 color=MediumOrchid legend=Red ytooltip='20%' 11 | p x=Green y=50 color=LimeGreen legend=Green ytooltip='50%' 12 | p x=Blue y=20 color=LightSkyBlue legend=Blue ytooltip='30%' 13 | 14 | text value='Vertical chart with numeric x axis' size=xlarge 15 | verticalBarChart tooltips legend=false width='100%' xtype=number1 height=400 ymin=50 ymax=100 yticks=5 barWidth=20 16 | data id=d1 17 | " 18 | 19 | for ((i=21;i<=40;i++)); do 20 | pglet_send "setf rdp y=$i" 21 | sleep 0.01 22 | done 23 | 24 | for ((i=0;i<=100;i++)); do 25 | y=$RANDOM 26 | let "y %= 100" 27 | pglet_send "addf p to=d1 trim=30 x=$i y=$y" 28 | sleep 0.05 29 | done 30 | } 31 | 32 | pglet_app "index" "main" -------------------------------------------------------------------------------- /bash/greeter/greeter-app.sh: -------------------------------------------------------------------------------- 1 | . pglet.sh 2 | 3 | function main() { 4 | pglet_send "clean" 5 | txt_name=`pglet_send "add textbox label='Your name' description='Please provide your full name'"` 6 | btn_hello=`pglet_send "add button primary text='Say hello'"` 7 | 8 | while true 9 | do 10 | pglet_wait_event 11 | if [[ "$PGLET_EVENT_TARGET" == $btn_hello && "$PGLET_EVENT_NAME" == "click" ]]; then 12 | name=`pglet_send "get $txt_name value"` 13 | pglet_send "clean page" 14 | pglet_send "add text value='Hello, $name!'" 15 | break 16 | fi 17 | done 18 | } 19 | 20 | pglet_app "greeter-app" main -------------------------------------------------------------------------------- /bash/greeter/greeter.sh: -------------------------------------------------------------------------------- 1 | . pglet.sh 2 | 3 | pglet_page "index" 4 | 5 | pglet_send "clean" 6 | txt_name=`pglet_send "add textbox label='Your name' description='Please provide your full name'"` 7 | btn_hello=`pglet_send "add button primary text='Say hello'"` 8 | 9 | while true 10 | do 11 | pglet_wait_event 12 | if [[ "$PGLET_EVENT_TARGET" == $btn_hello && "$PGLET_EVENT_NAME" == "click" ]]; then 13 | name=`pglet_send "get $txt_name value"` 14 | pglet_send "clean page" 15 | pglet_send "add text value='Hello, $name!'" 16 | pglet_send "add text value='Close browser window to exit the program...'" 17 | break 18 | fi 19 | done 20 | 21 | echo "Press [ENTER] to exit the program..." 22 | read -------------------------------------------------------------------------------- /bash/hello-world/hello-app.sh: -------------------------------------------------------------------------------- 1 | . pglet.sh 2 | 3 | function main() { 4 | pglet_send "clean" 5 | pglet_send "add text value='Hello, world!'" 6 | } 7 | 8 | pglet_app "hello-app" main -------------------------------------------------------------------------------- /bash/hello-world/hello.sh: -------------------------------------------------------------------------------- 1 | . pglet.sh 2 | 3 | pglet_page 4 | pglet_send "clean" 5 | pglet_send "add text value='Hello, world!'" -------------------------------------------------------------------------------- /csharp/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore file for Visual Studio 2008 2 | 3 | # use glob syntax 4 | syntax: glob 5 | 6 | # Ignore Visual Studio 2008 files 7 | *.obj 8 | *.exe 9 | *.pdb 10 | *.user 11 | *.aps 12 | *.pch 13 | *.vspscc 14 | *_i.c 15 | *_p.c 16 | *.ncb 17 | *.suo 18 | *.tlb 19 | *.tlh 20 | *.bak 21 | *.cache 22 | *.ilk 23 | *.log 24 | *.lib 25 | *.sbr 26 | *.scc 27 | _out*/ 28 | _web*/ 29 | _publish 30 | [Bb]in 31 | [Dd]ebug*/ 32 | obj/ 33 | [Rr]elease*/ 34 | _ReSharper*/ 35 | [Tt]est[Rr]esult*/ 36 | [Bb]uild[Ll]og.* 37 | *.[Pp]ublish.xml 38 | packages/ 39 | [Ll]ogs/ 40 | 41 | node_modules/ 42 | package-lock.json 43 | .vs/ 44 | *.env 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /csharp/Buttons/Buttons.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /csharp/Buttons/Program.cs: -------------------------------------------------------------------------------- 1 | using Pglet; 2 | using Pglet.Controls; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace ButtonsExample 7 | { 8 | class Program 9 | { 10 | static async Task Main() 11 | { 12 | await PgletClient.ServeApp(async (page) => 13 | { 14 | await page.AddAsync( 15 | new Text { Value = "Standard button", Size = TextSize.Large }, 16 | new Stack 17 | { 18 | Horizontal = true, 19 | Controls = { 20 | new Button { Text = "Standard", OnClick = (e) => 21 | { 22 | Console.WriteLine("Button clicked!"); 23 | }}, 24 | new Button { Text = "Standard disabled", Disabled = true } 25 | } 26 | }, 27 | new Text { Value = "Primary button", Size = TextSize.Large }, 28 | new Stack 29 | { 30 | Horizontal = true, 31 | Controls = { 32 | new Button { Primary = true, Text = "Primary" }, 33 | new Button { Primary = true, Text = "Primary disabled", Disabled = true } 34 | } 35 | }, 36 | new Text { Value = "Compound button", Size = TextSize.Large }, 37 | new Stack 38 | { 39 | Horizontal = true, 40 | Controls = { 41 | new Button { Compound = true, Text = "Compound", SecondaryText = "This is a secondary text"}, 42 | new Button { Compound = true, Primary = true, Text = "Primary Compound", SecondaryText = "This is a secondary text" } 43 | } 44 | }); 45 | 46 | 47 | }, "csharp-buttons"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /csharp/PgletExamples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31129.286 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Buttons", "Buttons\Buttons.csproj", "{D0617C96-FF35-45BA-AC61-1B373FEA7CE4}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stack", "Stack\Stack.csproj", "{DFA8B884-DEA7-4235-A2BC-07095FB91380}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D0617C96-FF35-45BA-AC61-1B373FEA7CE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {D0617C96-FF35-45BA-AC61-1B373FEA7CE4}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {D0617C96-FF35-45BA-AC61-1B373FEA7CE4}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {D0617C96-FF35-45BA-AC61-1B373FEA7CE4}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {DFA8B884-DEA7-4235-A2BC-07095FB91380}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {DFA8B884-DEA7-4235-A2BC-07095FB91380}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {DFA8B884-DEA7-4235-A2BC-07095FB91380}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {DFA8B884-DEA7-4235-A2BC-07095FB91380}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {8BA1DCD2-FED2-4BBA-9191-AB84D9AD4811} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /csharp/Stack/Program.cs: -------------------------------------------------------------------------------- 1 | using Pglet; 2 | using Pglet.Controls; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace StackExample 7 | { 8 | class Program 9 | { 10 | static async Task Main() 11 | { 12 | await PgletClient.ServeApp(async (page) => 13 | { 14 | await page.AddAsync( 15 | new Text { Value = "Vertical stack", Size = TextSize.Large }, 16 | new Stack 17 | { 18 | Controls = { 19 | new Text { Value = "Text 1" }, 20 | new Text { Value = "Text 2" } 21 | } 22 | }, 23 | new Text { Value = "Horizontal stack", Size = TextSize.Large }, 24 | new Stack 25 | { 26 | Horizontal = true, 27 | Controls = { 28 | new Text { Value = "Text 1" }, 29 | new Text { Value = "Text 2" } 30 | } 31 | }); 32 | 33 | 34 | }, "csharp-stack"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /csharp/Stack/Stack.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /node/greeter/greeter-app.js: -------------------------------------------------------------------------------- 1 | const pglet = require("pglet"); 2 | 3 | (async () => { 4 | 5 | // start a new session for every user visit 6 | await pglet.app("greeter-app", async (p) => { 7 | 8 | // add textbox and a button 9 | let txt_name = await p.send("add textbox label='Your name' description='Please provide your full name'"); 10 | let btn_hello = await p.send("add button primary text='Say hello'"); 11 | 12 | while(true) { 13 | // wait until button is clicked 14 | const e = await p.waitEvent(); 15 | if (e.target === btn_hello && e.name === 'click') { 16 | 17 | // get the entered value of a textbox 18 | let name = await p.send(`get ${txt_name} value`); 19 | 20 | // clean the page and output the greeting 21 | await p.send("clean page"); 22 | await p.send(`add text value='Hello, ${name}!'`); 23 | } 24 | } 25 | }); 26 | 27 | process.stdin.resume(); 28 | })(); 29 | -------------------------------------------------------------------------------- /node/greeter/greeter.js: -------------------------------------------------------------------------------- 1 | const pglet = require("pglet"); 2 | 3 | (async () => { 4 | let p = await pglet.page("greeter"); 5 | 6 | let txt_name = await p.send("add textbox label='Your name' description='Please provide your full name'"); 7 | let btn_hello = await p.send("add button primary text='Say hello'"); 8 | 9 | while(true) { 10 | const e = await p.waitEvent(); 11 | if (e.target === btn_hello && e.name === 'click') { 12 | let name = await p.send(`get ${txt_name} value`); 13 | await p.send("clean page"); 14 | await p.send(`add text value='Hello, ${name}!'`); 15 | } 16 | } 17 | })(); 18 | 19 | -------------------------------------------------------------------------------- /node/hello-world/hello-app.js: -------------------------------------------------------------------------------- 1 | const pglet = require("pglet"); 2 | 3 | (async () => { 4 | await pglet.app("hello-app", async (p) => { 5 | 6 | await p.send("clean"); 7 | await p.send("add text value='Hello, world!'"); 8 | }); 9 | 10 | process.stdin.resume(); 11 | })(); -------------------------------------------------------------------------------- /node/hello-world/hello.js: -------------------------------------------------------------------------------- 1 | const pglet = require("pglet"); 2 | 3 | (async () => { 4 | let p = await pglet.page(); 5 | await p.add(new pglet.Text({value: "Hello, world!"})); 6 | })(); -------------------------------------------------------------------------------- /node/hello-world/hello.ts: -------------------------------------------------------------------------------- 1 | import pglet from "pglet"; 2 | 3 | (async () => { 4 | let p = await pglet.page(); 5 | await p.add(new pglet.Text({value: "Hello, world!"})); 6 | })(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "pglet": "^0.4.6" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /powershell/controls/buttons.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Name "pglet-buttons" -ScriptBlock { 4 | $page = $PGLET_PAGE 5 | 6 | $dialog = Dialog -Title "Hello" -SubText "Button clicked!" 7 | 8 | $view = @( 9 | Text "Standard button" -Size Large 10 | Stack -Horizontal -Controls @( 11 | Button -Text "Standard - click me to see dialog" -OnClick { 12 | $dialog.Open = $true 13 | $page.update() 14 | } 15 | Button -Disabled -Text "Standard disabled" 16 | ) 17 | 18 | Text "Primary button" -Size Large 19 | Stack -Horizontal -Controls @( 20 | Button -Primary -Text "Primary" 21 | Button -Primary -Disabled -Text "Primary disabled" 22 | ) 23 | 24 | Text "Compound button" -Size Large 25 | Stack -Horizontal -Controls @( 26 | Button -Compound -Text "Compound" -SecondaryText "This is a secondary text" 27 | Button -Compound -Primary -Text "Primary compound" -SecondaryText "This is a secondary text" 28 | ) 29 | 30 | Text "Buttons with icon" -Size Large 31 | Stack -Horizontal -Controls @( 32 | Button -Text "Create account" -Icon "AddFriend" -Primary 33 | Button -Text "New item" -Icon "Add" 34 | Button -Text "Delete" -Icon "Delete" 35 | ) 36 | 37 | Text "Toolbar buttons" -Size Large 38 | Stack -Horizontal -Controls @( 39 | Button -Toolbar -Text "Send" -Icon "Mail" 40 | Button -Toolbar -Text "Show example" -Icon "ChevronDown" 41 | Button -Toolbar -Text "Delete" -Icon "Delete" -IconColor 'Red' 42 | ) 43 | 44 | Text "Icon-only buttons" -Size Large 45 | Stack -Horizontal -Controls @( 46 | Button -Icon "Emoji2" -Title 'Emoji!' 47 | Button -Icon "Calendar" -Title 'Calendar!' 48 | ) 49 | 50 | Text "Link buttons" -Size Large 51 | Stack -Horizontal -Controls @( 52 | Button -action -icon 'Globe' -text 'Pglet website' -url 'https://pglet.io' -newwindow 53 | Button -icon 'MyMoviesTV' -text 'Go to Disney' -url 'https://disney.com' -newwindow 54 | ) 55 | 56 | Text "Context menu buttons" -Size Large 57 | Button -Icon "Add" -Text "New item" -MenuItems @( 58 | MenuItem -Text "Email message" -Icon "Mail" 59 | MenuItem -Text "Calendar event" -Icon "Calendar" 60 | ) 61 | 62 | Text "Button with sub-menus" -Size Large 63 | Button -Text 'Button with sub-menus' -MenuItems @( 64 | MenuItem -Icon "Add" -Text "New" -SubMenuItems @( 65 | MenuItem -Text "Email message" -Icon "Mail" 66 | MenuItem -Text "Calendar event" -Icon "Calendar" 67 | ) 68 | MenuItem -Icon "Share" -Text "Share" -Split -SubMenuItems @( 69 | MenuItem -Text "Share to Twitter" 70 | MenuItem -Text "Share to Facebook" 71 | MenuItem "Share to Somewhere" 72 | MenuItem "Share to Email" -SubMenuItems @( 73 | MenuItem "Share to Outlook" 74 | MenuItem "Share to Gmail" 75 | ) 76 | MenuItem -Divider 77 | MenuItem "To Pglet" -Icon "Globe" -IconColor "green" -Url "https://pglet.io" -NewWindow -SecondaryText "New Window" 78 | ) 79 | ) 80 | 81 | Text "Split buttons" -Size Large 82 | Button -Split -Text "Standard" -MenuItems @( 83 | MenuItem -Text "Email message" -Icon "Mail" -OnClick { Write-Trace "Email message clicked!" } 84 | MenuItem -Text "Calendar event" -Icon "Calendar" -OnClick { Write-Trace "Calendar clicked!" } 85 | ) 86 | Button -Split -Primary -Text "Primary" -MenuItems @( 87 | MenuItem -Text "Email message" -Icon "Mail" 88 | MenuItem -Text "Calendar event" -Icon "Calendar" 89 | ) 90 | 91 | $dialog 92 | ) 93 | 94 | $page.add($view) 95 | } -------------------------------------------------------------------------------- /powershell/controls/html.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $page = Connect-PgletPage -Name "html-test" 4 | $page.clean() 5 | 6 | $h = Html '

Hello, world!

' 7 | $page.add($h) -------------------------------------------------------------------------------- /powershell/controls/iframe.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -ScriptBlock { 4 | $pglet_page.title = "IFrame example" 5 | $pglet_page.add( 6 | (IFrame -Src 'https://pglet.io' -Width '100%' -Height 300 -Border '2px solid red') 7 | ) 8 | } -------------------------------------------------------------------------------- /powershell/controls/progress.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Name "pglet-progress" -ScriptBlock { 4 | $ErrorActionPreference = 'stop' 5 | 6 | $page = $pglet_page 7 | 8 | $controls = @( 9 | Text "Indeterminate Progress" -Size xLarge 10 | Progress -Label "Operation progress" -Description "Doing something indefinite..." -Width "30%" 11 | ) 12 | 13 | $page.add($controls) 14 | 15 | $prog1 = Progress -Label "Copying file1.txt to file2.txt" -Width "30%" -BarHeight 4 16 | $page.add($prog1) 17 | 18 | for($i = 0; $i -lt 101; $i=$i+10) { 19 | $prog1.value = $i 20 | $prog1.update() 21 | Start-Sleep -Milliseconds 500 22 | } 23 | 24 | $prog2 = Progress -Label "Provisioning your account" -Value 0 -Width "30%" 25 | $page.add($prog2) 26 | 27 | $prog2.description = "Preparing environment..." 28 | $prog2.value = 50 29 | $prog2.update() 30 | Start-Sleep -Seconds 2 31 | 32 | $prog2.description = "Collecting information..." 33 | $prog2.value = 100 34 | $prog2.update() 35 | Start-Sleep -Seconds 2 36 | 37 | $prog2.value = $null 38 | $prog2.update() 39 | } -------------------------------------------------------------------------------- /powershell/controls/signin-entire-app.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Permissions "*" -ScriptBlock { 4 | $page = $PGLET_PAGE 5 | $page.theme = 'dark' 6 | 7 | $loggedUser = Text "Welcome, $($page.userLogin)" 8 | 9 | $page.onSignin = { 10 | Write-Trace "Sign in event" 11 | $loggedUser.value = $page.userLogin 12 | $page.update() 13 | } 14 | 15 | $page.onSignout = { 16 | Write-Trace "Sign out event" 17 | $loggedUser.value = "Not signed in" 18 | $page.update() 19 | } 20 | 21 | $signoutButton = Button -Primary -Text "Sign out" -OnClick { 22 | $page.signout() 23 | } 24 | 25 | $page.add($loggedUser, $signoutButton) 26 | } -------------------------------------------------------------------------------- /powershell/controls/signin-on-demand.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Web -ScriptBlock { 4 | $page = $PGLET_PAGE 5 | $page.theme = 'dark' 6 | 7 | $page.onDismissSignin = { 8 | Write-Trace "Signin cancelled" 9 | } 10 | 11 | $currentUser = Text 12 | 13 | $signinButton = Button -Primary -Text "Sign in" -OnClick { 14 | Write-Trace "Display signin dialog" 15 | 16 | try { 17 | $success = Show-PgletSignin -AuthProviders "azure,github,google" -AuthGroups -AllowDismiss 18 | if ($success) { 19 | Write-Trace "Signed in!" 20 | updateCurrentUser 21 | $page.update() 22 | } 23 | } catch { 24 | Write-Trace "$_" 25 | } 26 | } 27 | 28 | $signoutButton = Button -Primary -Text "Sign out" -OnClick { 29 | $page.signout() 30 | } 31 | 32 | $page.onSignout = { 33 | Write-Trace "Signed out!" 34 | updateCurrentUser 35 | $page.update() 36 | } 37 | 38 | $checkAnon = Button -Text "Check anonymous access" -OnClick { 39 | $result = $page.canAccess("") 40 | Write-Trace $result 41 | } 42 | 43 | $checkAnyAuth = Button -Text "Check any login" -OnClick { 44 | $result = $page.canAccess("*") 45 | Write-Trace $result 46 | } 47 | 48 | $checkGitHubTeams = Button -Text "Check GitHub permissions" -OnClick { 49 | $result = $page.canAccess("github:pglet/core developers") 50 | Write-Trace $result 51 | } 52 | 53 | $checkGoogleLogin = Button -Text "Check Google login" -OnClick { 54 | $result = $page.canAccess("google:*@appveyor.com") 55 | Write-Trace $result 56 | } 57 | 58 | function updateCurrentUser() { 59 | if ($page.userName) { 60 | # signed in 61 | $currentUser.value = "Welcome back, $($page.userName)" 62 | $signoutButton.Visible = $true 63 | $signinButton.Visible = $false 64 | } else { 65 | # anonymous 66 | $currentUser.value = "Not logged in" 67 | $signinButton.Visible = $true 68 | $signoutButton.Visible = $false` 69 | } 70 | } 71 | 72 | updateCurrentUser 73 | 74 | $page.add($currentUser, $signinButton, $signoutButton, $checkAnon, $checkAnyAuth, $checkGitHubTeams, $checkGoogleLogin) 75 | } -------------------------------------------------------------------------------- /powershell/controls/stack.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Name "pglet-stack" -ScriptBlock { 4 | $ErrorActionPreference = 'stop' 5 | 6 | $pglet_page.horizontalAlign = 'Stretch' 7 | $pglet_page.update() 8 | 9 | $bgColor = '#ddddee' 10 | 11 | function items($count) { 12 | $items = @() 13 | for($i = 1; $i -le $count; $i++) { 14 | $items += (Text -Value "$i" -Align Center -VerticalAlign Center -Width 30 -Height 30 -BgColor CyanBlue10 -Color White -Padding 5) 15 | } 16 | return $items 17 | } 18 | 19 | function createHorizontalStack($horizAlign) { 20 | Stack -Controls @( 21 | Text -Value $horizAlign 22 | Stack -Horizontal -HorizontalAlign $horizAlign -VerticalAlign Center -Gap 20 -BgColor $bgColor -Controls (items 3) 23 | ) 24 | } 25 | 26 | function createVerticalStack($vertAlign, $horizAlign) { 27 | Stack -Width '20%' -Controls @( 28 | Text -Value $vertAlign 29 | Stack -VerticalAlign $vertAlign -HorizontalAlign Center -Height 300 -Gap 20 -BgColor $bgColor -Controls (items 3) 30 | ) 31 | } 32 | 33 | # Gap, padding 34 | $spacingStack = Stack -Horizontal -BgColor $bgColor -Gap 0 -Controls (items 5) 35 | $gapSlider = Slider "Gap between items" -Min 0 -Max 50 -Step 1 -Value 0 -ShowValue -OnChange { 36 | $spacingStack.gap = $gapSlider.value 37 | $spacingStack.update() 38 | } 39 | $paddingSlider = Slider "Stack padding" -Min 0 -Max 50 -Step 1 -Value 0 -ShowValue -OnChange { 40 | $spacingStack.padding = $paddingSlider.value 41 | $spacingStack.update() 42 | } 43 | 44 | $pglet_page.add( 45 | (Text "Horizontal stack - Gap and Padding" -Size xLarge), 46 | $gapSlider, 47 | $paddingSlider, 48 | $spacingStack 49 | ) 50 | 51 | # Wrapping 52 | $wrapStack = Stack -Horizontal -Wrap -BgColor $bgColor -Gap 20 -Controls (items 10) 53 | $wrapSlider = Slider "Change the stack width to see how child items wrap onto multiple rows:" ` 54 | -Min 0 -Max 100 -Step 10 -Value 100 -Width '100%' -ShowValue -ValueFormat '{value}%' -OnChange { 55 | $wrapStack.width = "$($wrapSlider.value)%" 56 | $wrapStack.update() 57 | } 58 | 59 | $pglet_page.add( 60 | (Text "Horizontal stack - Wrapping" -Size xLarge), 61 | $wrapSlider, 62 | $wrapStack, 63 | 64 | (Text "Horizontal stack - Horizontal Alignments" -Size xLarge), 65 | (createHorizontalStack 'Start'), 66 | (createHorizontalStack 'Center'), 67 | (createHorizontalStack 'End'), 68 | (createHorizontalStack 'SpaceBetween'), 69 | (createHorizontalStack 'SpaceAround'), 70 | (createHorizontalStack 'SpaceEvenly'), 71 | 72 | (Text "Horizontal stack - Vertical Alignments" -Size xLarge), 73 | (Text "Start"), 74 | (Stack -Horizontal -VerticalAlign 'Start' -Height 100 -BgColor $bgColor -Gap 20 -Controls (items 3)), 75 | (Text "Center"), 76 | (Stack -Horizontal -VerticalAlign 'Center' -Height 100 -BgColor $bgColor -Gap 20 -Controls (items 3)), 77 | (Text "End"), 78 | (Stack -Horizontal -VerticalAlign 'End' -Height 100 -BgColor $bgColor -Gap 20 -Controls (items 3)) 79 | ) 80 | 81 | # Vertical stack 82 | $vertStacks = Stack -Horizontal -HorizontalAlign SpaceBetween -Width '100%' -Controls @( 83 | (createVerticalStack 'Start'), 84 | (createVerticalStack 'Center'), 85 | (createVerticalStack 'End'), 86 | (createVerticalStack 'SpaceBetween'), 87 | (createVerticalStack 'SpaceAround'), 88 | (createVerticalStack 'SpaceEvenly') 89 | ) 90 | 91 | $pglet_page.add( 92 | (Text "Vertical stack - Vertical Alignments" -Size xLarge), 93 | $vertStacks 94 | ) 95 | 96 | # Stack submit 97 | $form1 = Stack -Padding 10 -width '50%' -Border '2px solid #eee' -BorderRadius 5 -Controls @( 98 | Text "Pressing ENTER inside the stack will fire 'submit' event." 99 | TextBox "First name" 100 | TextBox "Last name" 101 | ) -OnSubmit { 102 | $form1.controls.insert(0, (Message "Form has been submitted!" -Type Success -Dismiss)) 103 | $form1.update() 104 | } 105 | $pglet_page.add( 106 | (Text "Stack with Submit event" -Size xLarge), 107 | $form1 108 | ) 109 | } -------------------------------------------------------------------------------- /powershell/controls/textbox.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | Connect-PgletApp -Name "pglet-textbox" -ScriptBlock { 4 | 5 | $controls = @( 6 | TextBox -Multiline -AutoAdjustHeight -Label "Multiline textbox with auto-adjust height" 7 | TextBox -Underlined -Label "Underlined textbox:" 8 | TextBox -Borderless -Label "Borderless textbox" 9 | TextBox -Prefix 'https://' -Label "Textbox with prefix" 10 | TextBox -Suffix 'px' -Label "Textbox with sufix" 11 | TextBox -Prefix 'https://' -Suffix '.com' -Label "Textbox with prefix and suffix" 12 | ) 13 | 14 | $pglet_page.add($controls) 15 | } -------------------------------------------------------------------------------- /powershell/greeter/greeter-app.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $main = { 4 | 5 | $page = $PGLET_PAGE 6 | 7 | $txt_name = TextBox -Label 'Your name' -Description 'Please provide your full name' 8 | $btn_hello = Button -Primary -Text 'Say hello' -OnClick { 9 | $page.controls.clear() 10 | $page.controls.add(((Text -Value "Hello, $($txt_name.value)!"))) 11 | $page.update() 12 | } 13 | 14 | $page.add($txt_name, $btn_hello) 15 | } 16 | 17 | Connect-PgletApp -Name 'greeter-app' -ScriptBlock $main -------------------------------------------------------------------------------- /powershell/greeter/greeter.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $page = Connect-PgletPage "greeter" 4 | $page.clean() 5 | 6 | $txt_name = TextBox -Label 'Your name' -Description 'Please provide your full name' 7 | $btn_hello = Button -Primary -Text 'Say hello' -OnClick { 8 | $page.controls.clear() 9 | $page.controls.add(((Text -Value "Hello, $($txt_name.value)!"))) 10 | $page.update() 11 | } 12 | 13 | $page.add($txt_name, $btn_hello) 14 | 15 | Switch-PgletEvents -------------------------------------------------------------------------------- /powershell/hello-world/hello-app.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $main = { 4 | $PGLET_PAGE.add((Text -Value "Hello to connection $($PGLET_PAGE.connection.pipeID)!")) 5 | } 6 | 7 | Connect-PgletApp -Name 'hello-app' -ScriptBlock $main -------------------------------------------------------------------------------- /powershell/hello-world/hello.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $p = Connect-PgletPage "hello" 4 | $p.clean($true) 5 | $p.add((Text -Value 'Hello, world!')) -------------------------------------------------------------------------------- /powershell/monitor/monitor.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | function getTopProcesses($maxCount) { 4 | $procIDs = @{} 5 | (Get-Counter "\Process(*)\ID Process" -ErrorAction SilentlyContinue).CounterSamples | 6 | ForEach-Object { $procIDs[($_.Path -replace "\\id process$","\% Processor Time")] = $_.CookedValue } 7 | 8 | $CpuCores = (Get-CimInstance -ClassName Win32_ComputerSystem).NumberOfLogicalProcessors 9 | return (Get-Counter "\Process(*)\% Processor Time" -ErrorAction SilentlyContinue).CounterSamples | 10 | Where-Object {$_.InstanceName -notmatch "^(idle|_total|system)$"} | 11 | Sort-Object "CookedValue" -descending | 12 | Select-Object -first $maxCount ` 13 | @{Name="PID";Expression={$procIDs[$_.Path]}}, 14 | @{Name="Path";Expression={(Get-Process -id $procIDs[$_.Path]).Path}}, 15 | InstanceName, 16 | @{Name="CPU";Expression={[Decimal]::Round(($_.CookedValue / $CpuCores), 2)}} 17 | } 18 | 19 | function getEmptyData() { 20 | # Generate 30 empty values for the last minute to initially fill charts 21 | $points=@() 22 | for($i = -30; $i -lt 0; $i++) { 23 | $d=(Get-Date).AddSeconds($i*2) 24 | $points += LineChartDataPoint -X $d -Y 0 25 | } 26 | return $points 27 | } 28 | 29 | $userName = $env:UserName 30 | $compName = $env:ComputerName 31 | $totalRam = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).Sum / 1024 / 1024 32 | 33 | $page = Connect-PgletPage -Name "ps-monitor" 34 | $page.title = 'Task Manager' 35 | $page.padding = '10px' 36 | $page.update() 37 | 38 | $tab = Tab -Id $compName -Text $compName 39 | 40 | $page.add( 41 | (Text -Id 'title' -Value 'Task Manager' -Size xLarge), 42 | (Tabs -Id 'computers' -Width '100%' -TabItems @( 43 | $tab 44 | ))) 45 | 46 | $tab.clean() 47 | 48 | $proc_grid = Grid -ShimmerLines 5 -SelectionMode Single -PreserveSelection -HeaderVisible -KeyFieldName 'PID' -Columns @( 49 | GridColumn -Resizable -Sortable 'string' -FieldName 'name' -Name 'Process name' -MaxWidth 100 50 | GridColumn -Resizable -Sortable 'number' -FieldName 'pid' -Name 'PID' -MaxWidth 100 51 | GridColumn -Resizable -Sortable 'string' -FieldName 'cpu_display' -SortField 'cpu' -Name 'CPU %' -MaxWidth 100 52 | GridColumn -Resizable -Sortable 'string' -FieldName 'path' -Name 'Path' 53 | ) 54 | 55 | $cpu_chart = LineChartData -Legend 'CPU' -Points (getEmptyData) 56 | $ram_chart = LineChartData -Legend 'RAM' -Points (getEmptyData) 57 | 58 | $stack = Stack -Horizontal -Controls @( 59 | Stack -Width '50%' -Controls @( 60 | $proc_grid 61 | ) 62 | Stack -Width '40%' -Controls @( 63 | Text -Value 'CPU, %' -Size Large 64 | LineChart -Tooltips -XType Date -YTicks 5 -YMax 100 -YFormat '{y}%' -Height 250 -Lines @( 65 | $cpu_chart 66 | ) 67 | Text -Value 'RAM, MB' -Size Large 68 | LineChart -Tooltips -XType Date -YTicks 5 -YMax $totalRam -Height 250 -Lines @( 69 | $ram_chart 70 | ) 71 | ) 72 | ) 73 | 74 | $tab.controls.add($stack) 75 | $tab.update() 76 | 77 | # Main update loop 78 | while($true) { 79 | 80 | $proc_grid.items = getTopProcesses 10 | ForEach-Object { 81 | @{ 82 | pid = $_.PID 83 | name = $_.InstanceName 84 | cpu = $_.CPU 85 | cpu_display = "$($_.CPU)%" 86 | path = $_.Path 87 | } 88 | } 89 | 90 | $d=(Get-Date) 91 | 92 | # Update CPU load 93 | $cpuLoad = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue.ToString("#,0.00") 94 | $cpu_chart.points.removeAt(0) 95 | $cpu_chart.points.add((LineChartDataPoint -X $d -Y $cpuLoad)) 96 | 97 | # Update RAM load 98 | $availRam = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue 99 | $usedRam = $totalRam - $availRam 100 | $usedRamGB = ($usedRam/1024).ToString("#,0.00") 101 | $ram_chart.points.removeAt(0) 102 | $ram_chart.points.add((LineChartDataPoint -X $d -Y $usedRam -YTooltip "$usedRamGB GB")) 103 | 104 | $page.update() 105 | 106 | Start-Sleep -s 2 107 | } 108 | -------------------------------------------------------------------------------- /powershell/remote-console/remote-console.ps1: -------------------------------------------------------------------------------- 1 | Import-Module pglet 2 | 3 | $ErrorActionPreference = "stop" 4 | 5 | $pageName = "ps-shell-$(hostname)" 6 | if ($env:PGLET_PAGE) { 7 | $pageName = $env:PGLET_PAGE 8 | } 9 | 10 | if (-not $env:PGLET_PERMISSIONS) { 11 | throw "'PGLET_PERMISSIONS' environment variable is not set. Specify the list of GitHub usernames, teams or email addresses being able to access this app, for example PGLET_PERMISSIONS=`"User1, user2@somemail.com`"." 12 | } 13 | 14 | Connect-PgletApp -Name $pageName -Permissions $env:PGLET_PERMISSIONS -ScriptBlock { 15 | $ErrorActionPreference = 'stop' 16 | 17 | $page = $PGLET_PAGE 18 | $page.Title = "PowerShell Remote Console" 19 | $page.HorizontalAlign = 'stretch' 20 | 21 | # Textbox with a command entered 22 | $cmd = TextBox -Placeholder "Type PowerShell command and click Run or press ENTER..." -Width '100%' 23 | 24 | # Event handler to call when "Run" button is clicked or Enter pressed 25 | $run_on_click = { 26 | $cmd_text = $cmd.value 27 | if ([string]::IsNullOrWhitespace($cmd_text)) { 28 | return 29 | } 30 | 31 | # disable textbox and Run button, add spinner while the command is evaluating 32 | $cmd.value = '' 33 | $command_panel.disabled = $true 34 | $results.controls.insert(0, (Text $cmd_text -BgColor 'neutralLight' -Padding 10)) 35 | $results.controls.insert(1, (Spinner)) 36 | $page.update() 37 | 38 | try { 39 | 40 | # run the command 41 | $result = Invoke-Expression $cmd_text 42 | 43 | # if result is Array present it as Grid; otherwise Text 44 | if ($result -is [System.Array]) { 45 | $result_control = Grid -Compact -Items $result 46 | } else { 47 | $result_control = Text -Value ($result | Out-String) -Pre -Padding 10 48 | } 49 | } catch { 50 | $result_control = Text -Value "$_" -Pre -Padding 10 -Color 'red' 51 | } 52 | 53 | # re-enable controls and replace spinner with the results 54 | $command_panel.disabled = $false 55 | $results.controls.removeAt(1) 56 | $results.controls.insert(1, $result_control) 57 | $page.update() 58 | } 59 | 60 | # container for command textbox and Run button 61 | $command_panel = Stack -Horizontal -OnSubmit $run_on_click -Controls @( 62 | $cmd 63 | Button -Text "Run" -Primary -Icon 'Play' -OnClick $run_on_click 64 | ) 65 | 66 | # results container 67 | $results = Stack 68 | 69 | # "main" view combining all controls together 70 | $view = @( 71 | $command_panel 72 | Stack -Controls @( 73 | Stack -Horizontal -VerticalAlign Center -Controls @( 74 | Text 'Results' -Size large 75 | Button -Icon 'Clear' -Title 'Clear results' -OnClick { 76 | $results.controls.clear() 77 | $results.update() 78 | } 79 | ) 80 | $results 81 | ) 82 | ) 83 | 84 | # display the "main" view onto the page 85 | $page.add($view) 86 | } -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # Pglet Python examples 2 | 3 | This directory contains sample Python applications using Pglet: 4 | 5 | * [Controls](controls) - Demo apps for [Pglet controls reference](https://pglet.io/docs/controls). 6 | * [Hello, world!](hello-world) - Very basic Pglet application. 7 | * [Greeter](greeter) - A minimal form application. 8 | * [Icon browser](icon-browser) - A browser for Fluent UI icons. 9 | * [ToDo](todo) - ToDo application for [Python tutorial](https://pglet.io/docs/tutorials/python). 10 | 11 | Examples require Python 3.7+ with `pglet` module installed: 12 | 13 | pip install pglet -------------------------------------------------------------------------------- /python/controls/barchart_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, BarChart 3 | from pglet.barchart import Point 4 | 5 | 6 | def main(page): 7 | 8 | # Fractions BarChart 9 | chart1 = BarChart( 10 | data_mode="fraction", 11 | width="50%", 12 | tooltips=True, 13 | points=[ 14 | Point( 15 | legend="C:", x=20, y=250, x_tooltip="20%", y_tooltip="20 of 250 GB used" 16 | ), 17 | Point(legend="D:", x=50, y=250, x_tooltip="50%"), 18 | Point(legend="E:", x=30, y=250, x_tooltip="30%"), 19 | ], 20 | ) 21 | 22 | # Percentage BarChart 23 | chart2 = BarChart( 24 | data_mode="percentage", 25 | width="30%", 26 | tooltips=True, 27 | points=[ 28 | Point(legend="/disk1", x=20, y=100, color="green"), 29 | Point(legend="/disk2", x=50, y=100, color="yellow"), 30 | Point(legend="/disk3", x=90, y=100, color="red"), 31 | ], 32 | ) 33 | 34 | page.add( 35 | Text("Fractions BarChart", size="xLarge"), 36 | chart1, 37 | Text("Percentage BarChart", size="xLarge"), 38 | chart2, 39 | ) 40 | 41 | 42 | pglet.app("python-barchart", target=main) 43 | -------------------------------------------------------------------------------- /python/controls/button/action_button.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Stack 3 | with pglet.page("action-button") as page: 4 | page.add(Stack(horizontal=True, controls=[ 5 | Button(action=True, icon='AddFriend', text='Create account') 6 | ])) -------------------------------------------------------------------------------- /python/controls/button/basic_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button 3 | with pglet.page("basic-buttons") as page: 4 | page.add( 5 | Button("Standard"), 6 | Button("Standard disabled", disabled=True), 7 | Button("Primary", primary=True), 8 | Button("Primary disabled", primary=True, disabled=True)) -------------------------------------------------------------------------------- /python/controls/button/button_with_click_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Text 3 | 4 | with pglet.page("button-with-click-event") as page: 5 | 6 | def button_clicked(e): 7 | b.data += 1 8 | t.value = f"Button clicked {b.data} time(s)" 9 | page.update() 10 | 11 | b = Button("Button with 'click' event", on_click=button_clicked, title='Click me!', data=0) 12 | t = Text() 13 | 14 | page.add(b, t) 15 | 16 | input() -------------------------------------------------------------------------------- /python/controls/button/buttons_with_icons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button 3 | with pglet.page("buttons-with-icons") as page: 4 | page.add( 5 | Button("Create account", icon='AddFriend', primary=True), 6 | Button("New item", icon='Add'), 7 | Button("Delete", icon='Delete')) -------------------------------------------------------------------------------- /python/controls/button/compound_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button 3 | with pglet.page("compound-buttons") as page: 4 | page.add( 5 | Button("Compound", secondary_text='This is a secondary text', compound=True), 6 | Button("Primary compound", secondary_text='This is a secondary text', compound=True, primary=True)) -------------------------------------------------------------------------------- /python/controls/button/context_menu_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Stack, button 3 | with pglet.page("context-menu-buttons") as page: 4 | page.add(Stack(horizontal=True, controls=[ 5 | Button(icon='Add', text='New item', menu_items=[ 6 | button.MenuItem(text='Email message', icon='Mail'), 7 | button.MenuItem(text='Calendar event', icon='Calendar') 8 | ]), 9 | Button(text='Button with sub-menus', menu_items=[ 10 | button.MenuItem(text='New', icon='Add', sub_menu_items=[ 11 | button.MenuItem(text='Email message', icon='Mail'), 12 | button.MenuItem(text='Calendar event', icon='Calendar') 13 | ]), 14 | button.MenuItem(text='Share', icon='Share', split=True, sub_menu_items=[ 15 | button.MenuItem(text='Share to Twitter'), 16 | button.MenuItem(text='Share to Facebook'), 17 | button.MenuItem('Share to Somewhere'), 18 | button.MenuItem('Share to email', sub_menu_items=[ 19 | button.MenuItem('Share to Outlook'), 20 | button.MenuItem('Share to Gmail') 21 | ]) 22 | ]), 23 | button.MenuItem(divider=True), 24 | button.MenuItem(text='To Pglet', icon='Globe', icon_color='green', url='https://pglet.io', new_window=True, secondary_text='New Window') 25 | ]), 26 | ])) -------------------------------------------------------------------------------- /python/controls/button/icon_only_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button 3 | with pglet.page("icon-only-buttons") as page: 4 | page.add( 5 | Button(icon='Emoji2', title='Emoji!'), 6 | Button(icon='Calendar', title='Calendar!')) -------------------------------------------------------------------------------- /python/controls/button/link_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button 3 | with pglet.page("link-buttons") as page: 4 | page.add( 5 | Button(action=True, icon='Globe', text='Pglet website',url='https://pglet.io', new_window=True), 6 | Button(icon='MyMoviesTV', text='Go to Disney', url='https://disney.com', new_window=True)) -------------------------------------------------------------------------------- /python/controls/button/split_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Stack, button 3 | with pglet.page("split-buttons") as page: 4 | page.add(Stack(horizontal=True, controls=[ 5 | Button(split=True, text='Standard', menu_items=[ 6 | button.MenuItem('Email message', icon='Mail'), 7 | button.MenuItem('Calendar event', icon='Calendar') 8 | ]), 9 | Button(split=True, primary=True, text='Primary', menu_items=[ 10 | button.MenuItem('Email message', icon='Mail'), 11 | button.MenuItem('Calendar event', icon='Calendar') 12 | ]) 13 | ])) -------------------------------------------------------------------------------- /python/controls/button/toolbar_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Stack 3 | with pglet.page("toolbar-buttons") as page: 4 | page.add(Stack(horizontal=True, controls=[ 5 | Button(text="New item", toolbar=True, icon='Add'), 6 | Button(text="Send", toolbar=True, icon='Mail'), 7 | Button(text="Show example", toolbar=True, icon='ChevronDown'), 8 | Button(text="Delete", toolbar=True, icon_color='red', icon='Delete') 9 | ])) -------------------------------------------------------------------------------- /python/controls/callout/basic_callout.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Callout, Button, Text, Stack 3 | with pglet.page("basic-callout") as page: 4 | 5 | def button_clicked(e): 6 | c.visible = True 7 | page.update() 8 | 9 | 10 | b = Button(text='Show callout', on_click=button_clicked) 11 | page.add(b) 12 | 13 | c = Callout(target=b.uid, width=200, height=100, visible = False, controls=[ 14 | Stack(controls=[ 15 | Text(size='large', align='center', value='Callout title'), 16 | Text(size='small', align='center', value='This is a basic callout') 17 | ]) 18 | ]) 19 | 20 | page.add(c) 21 | 22 | input() 23 | 24 | 25 | -------------------------------------------------------------------------------- /python/controls/callout/callout_cover_target.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Callout, Button, Text, Stack 3 | with pglet.page("callout-cover-target") as page: 4 | 5 | def button_clicked(e): 6 | c.visible = True 7 | page.update() 8 | 9 | 10 | b = Button(text='Show callout', on_click=button_clicked) 11 | page.add(b) 12 | 13 | c = Callout(target=b.uid, width=200, height=100, visible = False, cover=True, controls=[ 14 | Stack(controls=[ 15 | Text(size='large', align='center', value='Callout title'), 16 | Text(size='small', align='center', value='This callout covers target') 17 | ]) 18 | ]) 19 | 20 | page.add(c) 21 | 22 | input() 23 | 24 | 25 | -------------------------------------------------------------------------------- /python/controls/callout/callout_with_directional_hint.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Callout, Button, Text, Stack, Toggle, Slider, Dropdown, dropdown 3 | with pglet.page("callout-with-directional-hint") as page: 4 | 5 | def button_clicked(e): 6 | c.beak = beak.value 7 | c.gap = int(gap_space.value) 8 | c.beak_width = int(beak_width.value) 9 | c.position = position.value 10 | c.visible = True 11 | page.update() 12 | 13 | 14 | beak = Toggle(label='Show beak', value=True) 15 | gap_space = Slider(width='50%', label='Gap space', show_value=True, min=0, max=30, step=1, value=0) 16 | beak_width = Slider(width='50%', label='Beak width', show_value=True, min=10, max=50, step=1, value=16) 17 | show_callout = Button(text='Show callout', on_click=button_clicked) 18 | position = Dropdown(width=100, label='Position', value='bottomLeft', options=[ 19 | dropdown.Option('topLeft'), 20 | dropdown.Option('topCenter'), 21 | dropdown.Option('topRight'), 22 | dropdown.Option('bottomLeft'), 23 | dropdown.Option('bottomCenter'), 24 | dropdown.Option('bottomRight') 25 | ]) 26 | 27 | stack = Stack(horizontal_align='center', width='50%', controls=[show_callout]) 28 | 29 | page.add(beak, gap_space, beak_width, position, stack) 30 | 31 | c = Callout(target=show_callout.uid, width=200, height=100, visible = False, controls=[ 32 | Stack(controls=[ 33 | Text(size='large', align='center', value='Callout title'), 34 | Text(size='small', align='center', value='This is a basic callout') 35 | ]) 36 | ]) 37 | 38 | page.add(c) 39 | 40 | input() 41 | 42 | 43 | -------------------------------------------------------------------------------- /python/controls/checkbox/basic_checkboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Checkbox, Button, Text 3 | with pglet.page("basic-checkboxes") as page: 4 | def button_clicked(e): 5 | t.value = f"Checkboxes values are: {c1.value}, {c2.value}, {c3.value}, {c4.value}." 6 | page.update() 7 | 8 | t = Text() 9 | c1 = Checkbox(label='Unchecked by default checkbox', value=False) 10 | c2 = Checkbox(label='Checked by default checkbox', value=True) 11 | c3 = Checkbox(label='Disabled checkbox', disabled=True) 12 | c4 = Checkbox(label="Checkbox with rendered box_side='end'", box_side='end') 13 | b = Button(text='Submit', on_click=button_clicked) 14 | page.add(c1, c2, c3, c4, b, t) 15 | 16 | input() 17 | 18 | 19 | -------------------------------------------------------------------------------- /python/controls/checkbox/checkbox_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Checkbox, Stack, Text 3 | 4 | 5 | def checkboxes(): 6 | return Stack( 7 | gap=20, 8 | controls=[ 9 | Text("Checkboxes", size="xLarge"), 10 | Checkbox(label="Unchecked checkbox", value=False), 11 | Checkbox(label="Checked checkbox", value=True), 12 | Checkbox(label="Disabled checkbox", disabled=True), 13 | Checkbox(label="Checkbox with rendered box_side='end'", box_side="end"), 14 | checkbox_with_on_change(), 15 | ], 16 | ) 17 | 18 | 19 | def checkbox_with_on_change(): 20 | def checkbox_changed(e): 21 | t.value = f"Checkbox value changed to {c.value}" 22 | stack.update() 23 | 24 | c = Checkbox("Checkbox with on_change event", on_change=checkbox_changed) 25 | t = Text() 26 | stack = Stack(controls=[c, t]) 27 | return stack 28 | 29 | 30 | def main(page): 31 | 32 | page.title = "Checkbox control samples" 33 | page.update() 34 | page.add(checkboxes()) 35 | 36 | 37 | pglet.app("python-checkbox", target=main) 38 | -------------------------------------------------------------------------------- /python/controls/checkbox/checkbox_with_change_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Checkbox, Text 3 | 4 | with pglet.page("checkbox-with-change-event") as page: 5 | def checkbox_changed(e): 6 | t.value = f"Checkbox value changed to {c.value}" 7 | t.update() 8 | 9 | c = Checkbox("Checkbox with 'change' event", on_change=checkbox_changed) 10 | t = Text() 11 | 12 | page.add(c, t) 13 | input() -------------------------------------------------------------------------------- /python/controls/choicegroup/basic_choicegroup.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import ChoiceGroup, choicegroup, Button, Text 3 | with pglet.page("basic-choicegroup") as page: 4 | def button_clicked(e): 5 | t.value = f"ChoiceGroup value is: {cg.value}" 6 | page.update() 7 | 8 | t = Text() 9 | b = Button(text='Submit', on_click=button_clicked) 10 | cg = ChoiceGroup(label='Select color', options=[ 11 | choicegroup.Option('Red'), 12 | choicegroup.Option('Green'), 13 | choicegroup.Option('Blue')]) 14 | 15 | page.add(cg, b, t) 16 | input() -------------------------------------------------------------------------------- /python/controls/choicegroup/change_choicegroup_options.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import ChoiceGroup, choicegroup, Textbox, Button, Stack 3 | with pglet.page("change-choicegroup-options") as page: 4 | 5 | def find_option(option_name): 6 | for option in cg.options: 7 | if option.key == option_name: 8 | return option 9 | return None 10 | 11 | def add_clicked(e): 12 | cg.options.append(choicegroup.Option(option_textbox.value)) 13 | option_textbox.value = '' 14 | page.update() 15 | 16 | def delete_clicked(e): 17 | option = find_option(cg.value) 18 | if option !=None: 19 | cg.options.remove(option) 20 | page.update() 21 | 22 | cg = ChoiceGroup() 23 | option_textbox = Textbox(placeholder='Enter new item name') 24 | 25 | add = Button("Add", on_click=add_clicked) 26 | delete = Button("Delete selected", on_click=delete_clicked) 27 | stack = Stack(controls = [cg, Stack(horizontal=True, controls=[option_textbox, add, delete])]) 28 | 29 | page.add(stack) 30 | 31 | input() -------------------------------------------------------------------------------- /python/controls/choicegroup/choicegroup_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, ChoiceGroup, Textbox, Button 3 | from pglet import choicegroup 4 | 5 | 6 | def choicegroups(): 7 | return Stack( 8 | gap=20, 9 | controls=[ 10 | Stack( 11 | controls=[Text("Basic ChoiceGroup", size="xLarge"), basic_choicegroup()] 12 | ), 13 | Stack( 14 | controls=[ 15 | Text("ChoiceGroup with icons", size="xLarge"), 16 | choicegroup_with_icons(), 17 | ] 18 | ), 19 | Stack( 20 | controls=[ 21 | Text("ChoiceGroup with on_change event", size="xLarge"), 22 | choicegroup_with_on_change(), 23 | ] 24 | ), 25 | Stack( 26 | controls=[ 27 | Text("Change items in choicegroup options", size="xLarge"), 28 | change_items_in_choicegroup(), 29 | ] 30 | ), 31 | ], 32 | ) 33 | 34 | 35 | def basic_choicegroup(): 36 | return ChoiceGroup( 37 | label="Select color", 38 | options=[ 39 | choicegroup.Option("Red"), 40 | choicegroup.Option("Green"), 41 | choicegroup.Option("Blue"), 42 | ], 43 | ) 44 | 45 | 46 | def choicegroup_with_icons(): 47 | return ChoiceGroup( 48 | label="Pick one icon", 49 | options=[ 50 | choicegroup.Option(key="day", text="Day", icon="CalendarDay"), 51 | choicegroup.Option(key="week", text="Week", icon="CalendarWeek"), 52 | choicegroup.Option(key="month", text="Month", icon="Calendar"), 53 | ], 54 | ) 55 | 56 | 57 | def choicegroup_with_on_change(): 58 | def choicegroup_changed(e): 59 | t.value = f"ChoiceGroup value changed to {cg.value}" 60 | stack.update() 61 | 62 | cg = ChoiceGroup( 63 | label="Select color", 64 | on_change=choicegroup_changed, 65 | options=[ 66 | choicegroup.Option("Red"), 67 | choicegroup.Option("Green"), 68 | choicegroup.Option("Blue"), 69 | ], 70 | ) 71 | 72 | t = Text() 73 | stack = Stack(controls=[cg, t]) 74 | return stack 75 | 76 | 77 | def change_items_in_choicegroup(): 78 | def add_clicked(e): 79 | cg.options.append(choicegroup.Option(new_option.value)) 80 | new_option.value = "" 81 | stack.update() 82 | 83 | cg = ChoiceGroup() 84 | new_option = Textbox(placeholder="Enter new item name") 85 | add = Button("Add", on_click=add_clicked) 86 | stack = Stack(controls=[cg, Stack(horizontal=True, controls=[new_option, add])]) 87 | return stack 88 | 89 | 90 | def main(page): 91 | 92 | page.title = "ChoiceGroup control samples" 93 | page.update() 94 | 95 | page.add(choicegroups()) 96 | 97 | 98 | pglet.app("python-choicegroup", target=main) 99 | -------------------------------------------------------------------------------- /python/controls/choicegroup/choicegroup_with_change_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import ChoiceGroup, choicegroup, Text 3 | with pglet.page("choicegroup-with-change-event") as page: 4 | 5 | def choicegroup_changed(e): 6 | t.value = f"ChoiceGroup value changed to {cg.value}" 7 | t.update() 8 | 9 | cg = ChoiceGroup(label='Select color', on_change=choicegroup_changed, options=[ 10 | choicegroup.Option('Red'), 11 | choicegroup.Option('Green'), 12 | choicegroup.Option('Blue') 13 | ]) 14 | 15 | t = Text() 16 | 17 | page.add(cg, t) 18 | 19 | input() -------------------------------------------------------------------------------- /python/controls/choicegroup/choicegroup_with_icons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import ChoiceGroup, choicegroup 3 | with pglet.page("choicegroup-with-icons") as page: 4 | page.add(ChoiceGroup(label='Pick one icon', options=[ 5 | choicegroup.Option(key='day', text='Day', icon='CalendarDay'), 6 | choicegroup.Option(key='week', text='Week', icon='CalendarWeek'), 7 | choicegroup.Option(key='month', text='Month', icon='Calendar') 8 | ])) -------------------------------------------------------------------------------- /python/controls/datepicker/basic_datepicker.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import pglet 3 | from pglet import DatePicker, Button, Text 4 | with pglet.page("basic-datepicker") as page: 5 | def button_clicked(e): 6 | t.value = f"DatePickers values are: {dp1.value}, {dp2.value}." 7 | page.update() 8 | 9 | now = datetime.now() 10 | t = Text() 11 | b = Button(text='Submit', on_click=button_clicked) 12 | dp1 = DatePicker(label="Start date", value=now, width=150) 13 | dp2 = DatePicker(label="End date", width=150) 14 | 15 | page.add(dp1, dp2, b, t) 16 | input() -------------------------------------------------------------------------------- /python/controls/datepicker/datepicker_allow_text_input.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import pglet 3 | from pglet import DatePicker 4 | with pglet.page("datepicker-allow-text-input") as page: 5 | now = datetime.now() 6 | page.add( 7 | DatePicker(width=150, label="Allow text input", allow_text_input=True), 8 | DatePicker(label="Allow text input with placeholder", placeholder='Select date...', allow_text_input=True, width='25%'), 9 | DatePicker(value=now, label="Required", required=True, allow_text_input=True)) -------------------------------------------------------------------------------- /python/controls/datepicker/datepicker_control.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import pglet 3 | from pglet import DatePicker, Stack, Button 4 | 5 | 6 | def main(page): 7 | def on_change(e): 8 | print(e.control.value) 9 | 10 | now = datetime.now() 11 | 12 | picker = DatePicker(label="Allow text input", allow_text_input=True) 13 | 14 | page.add( 15 | DatePicker("Start date", value=now, on_change=on_change), 16 | DatePicker(label="End date"), 17 | picker, 18 | Button("Check value", on_click=lambda e: print("Selected date:", picker.value)), 19 | DatePicker( 20 | label="Allow text input with placeholder", 21 | placeholder="Select date...", 22 | allow_text_input=True, 23 | width="50%", 24 | ), 25 | DatePicker(value=now, label="Required", required=True, allow_text_input=True), 26 | ) 27 | 28 | 29 | pglet.app("python-datepicker", target=main) 30 | -------------------------------------------------------------------------------- /python/controls/datepicker/datepicker_with_change_event.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import pglet 3 | from pglet import DatePicker, Text 4 | with pglet.page("datepicker-with-change-event") as page: 5 | def datepicker_changed(e): 6 | t.value = f"DatePicker value changed to {dp.value}" 7 | t.update() 8 | 9 | now = datetime.now() 10 | t = Text() 11 | dp = DatePicker(label="Start date", value=now, width=150, on_change=datepicker_changed) 12 | 13 | page.add(dp, t) 14 | input() -------------------------------------------------------------------------------- /python/controls/dialog/basic_dialog.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Checkbox, Dialog, Text 3 | 4 | with pglet.page("basic-dialog") as page: 5 | 6 | def button_clicked(e): 7 | d.open = True 8 | page.update() 9 | 10 | b = Button(text="Open dialog", on_click=button_clicked) 11 | page.add(b) 12 | 13 | d = Dialog( 14 | title="Welcome!", 15 | width=200, 16 | height=100, 17 | controls=[Text(size="small", align="center", value="This is a basic dialog")], 18 | footer=[Button("OK"), Button("Cancel")], 19 | ) 20 | 21 | page.add(d) 22 | 23 | input() 24 | -------------------------------------------------------------------------------- /python/controls/dropdown/basic_dropdown.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Dropdown, dropdown, Button, Text 3 | with pglet.page("basic-dropdown") as page: 4 | 5 | def button_clicked(e): 6 | t.value = f"Dropdown value is: {dd.value}" 7 | page.update() 8 | 9 | t = Text() 10 | b = Button(text='Submit', on_click=button_clicked) 11 | dd = Dropdown(width=100, options=[ 12 | dropdown.Option('Red'), 13 | dropdown.Option('Green'), 14 | dropdown.Option('Blue') 15 | ]) 16 | page.add(dd, b, t) 17 | 18 | input() 19 | 20 | -------------------------------------------------------------------------------- /python/controls/dropdown/change_dropdown_options.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Dropdown, dropdown, Textbox, Button, Stack 3 | with pglet.page("change-dropdown-options") as page: 4 | 5 | def find_option(option_name): 6 | for option in d.options: 7 | if option_name == option.key: 8 | return option 9 | return None 10 | 11 | def add_clicked(e): 12 | d.options.append(dropdown.Option(option_textbox.value)) 13 | d.value = option_textbox.value 14 | option_textbox.value = '' 15 | page.update() 16 | 17 | def delete_clicked(e): 18 | option = find_option(d.value) 19 | if option !=None: 20 | d.options.remove(option) 21 | page.update() 22 | 23 | d = Dropdown() 24 | option_textbox = Textbox(placeholder='Enter item name') 25 | add = Button("Add", on_click=add_clicked) 26 | delete = Button("Delete selected", on_click=delete_clicked) 27 | stack = Stack(controls = [d, Stack(horizontal=True, controls=[option_textbox, add, delete])]) 28 | 29 | page.add(stack) 30 | 31 | input() 32 | 33 | -------------------------------------------------------------------------------- /python/controls/dropdown/dropdown_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Dropdown, Textbox, Button 3 | from pglet import dropdown 4 | 5 | 6 | def dropdowns(): 7 | return Stack( 8 | gap=20, 9 | controls=[ 10 | Stack(controls=[Text("Basic dropdown", size="xLarge"), basic_dropdown()]), 11 | Stack( 12 | controls=[ 13 | Text("Dropdown with label and placeholder", size="xLarge"), 14 | dropdown_with_label_and_placeholder(), 15 | ] 16 | ), 17 | Stack( 18 | controls=[ 19 | Text("Dropdown with on_change event", size="xLarge"), 20 | dropdown_with_on_change(), 21 | ] 22 | ), 23 | Stack( 24 | controls=[ 25 | Text("Change items in dropdown options", size="xLarge"), 26 | change_items_in_dropdown(), 27 | ] 28 | ), 29 | ], 30 | ) 31 | 32 | 33 | def basic_dropdown(): 34 | return Dropdown( 35 | options=[ 36 | dropdown.Option("Red"), 37 | dropdown.Option("Green"), 38 | dropdown.Option("Blue"), 39 | ] 40 | ) 41 | 42 | 43 | def dropdown_with_label_and_placeholder(): 44 | return Dropdown( 45 | label="Color", 46 | placeholder="What's your favourite color?", 47 | options=[ 48 | dropdown.Option("Red"), 49 | dropdown.Option("Green"), 50 | dropdown.Option("Blue"), 51 | ], 52 | ) 53 | 54 | 55 | def dropdown_with_on_change(): 56 | def dropdown_changed(e): 57 | t.value = f"Dropdown changed to {d.value}" 58 | stack.update() 59 | 60 | d = Dropdown( 61 | on_change=dropdown_changed, 62 | options=[ 63 | dropdown.Option("Red"), 64 | dropdown.Option("Green"), 65 | dropdown.Option("Blue"), 66 | ], 67 | ) 68 | 69 | t = Text() 70 | stack = Stack(controls=[d, t]) 71 | return stack 72 | 73 | 74 | def change_items_in_dropdown(): 75 | def add_clicked(e): 76 | d.options.append(dropdown.Option(new_option.value)) 77 | d.value = new_option.value 78 | new_option.value = "" 79 | stack.update() 80 | 81 | d = Dropdown() 82 | new_option = Textbox(placeholder="Enter new item name") 83 | add = Button("Add", on_click=add_clicked) 84 | stack = Stack(controls=[d, Stack(horizontal=True, controls=[new_option, add])]) 85 | return stack 86 | 87 | 88 | def main(page): 89 | 90 | page.title = "Dropdown control samples" 91 | page.update() 92 | 93 | page.add(dropdowns()) 94 | 95 | 96 | pglet.app("python-dropdown", target=main) 97 | -------------------------------------------------------------------------------- /python/controls/dropdown/dropdown_with_change_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Dropdown, dropdown, Text 3 | with pglet.page("dropdown-with-change-event") as page: 4 | 5 | def dropdown_changed(e): 6 | t.value = f"Dropdown changed to {d.value}" 7 | page.update() 8 | 9 | d = Dropdown(width=100, on_change=dropdown_changed, options=[ 10 | dropdown.Option('Red'), 11 | dropdown.Option('Green'), 12 | dropdown.Option('Blue') 13 | ]) 14 | 15 | t = Text() 16 | 17 | page.add(d, t) 18 | 19 | input() 20 | 21 | -------------------------------------------------------------------------------- /python/controls/dropdown/dropdown_with_label_and_placeholder.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Dropdown, dropdown 3 | with pglet.page("dropdown-with-label-and-placeholder") as page: 4 | page.add(Dropdown(label='Color', placeholder='What\'s your favourite color?', options=[ 5 | dropdown.Option('Red'), 6 | dropdown.Option('Green'), 7 | dropdown.Option('Blue') 8 | ])) 9 | 10 | -------------------------------------------------------------------------------- /python/controls/form_control/README.md: -------------------------------------------------------------------------------- 1 | Form control example 2 | -------------------- 3 | 4 | This directory contains a example of using the Form control. The example is a "manual" app that 5 | contains several pages, each demonstrating different aspects of using the Form control. 6 | 7 | - `main.py` contains the code to run the manual, and can itself be considered an example of this 8 | type of multi-page app. It has no other dependencies than pglet, and does not use the Form 9 | control. 10 | 11 | - `manual_content.py` contains the manual pages as methods of the class Content. Method docstrings 12 | become the text on the page, method code is displayed under the text (by default), and the UI 13 | created by the running code is visible beside the text. 14 | 15 | If you run the manual app with this manual content, you should have these dependencies installed: 16 | 17 | - `pydantic` for the pydantic examples 18 | - `pydantic[email]` for the email validator in pydantic 19 | - `typing_extensions` if you are running Python <3.8 20 | -------------------------------------------------------------------------------- /python/controls/grid/basic_grid.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Column, Grid, Stack, Text 3 | 4 | 5 | class Person: 6 | def __init__( 7 | self, first_name: str, last_name: str, age: int = None, employee: bool = False 8 | ): 9 | self.first_name = first_name 10 | self.last_name = last_name 11 | self.age = age 12 | self.employee = employee 13 | 14 | 15 | with pglet.page("basic-grid") as page: 16 | 17 | page.add( 18 | Text("Basic grid", size="large"), 19 | Stack( 20 | width="50%", 21 | controls=[ 22 | Grid( 23 | columns=[ 24 | Column(name="First name", field_name="first_name"), 25 | Column(name="Last name", field_name="last_name"), 26 | Column(name="Age", field_name="age"), 27 | ], 28 | items=[ 29 | Person(first_name="John", last_name="Smith", age=30), 30 | Person(first_name="Samantha", last_name="Fox", age=43), 31 | Person(first_name="Alice", last_name="Brown", age=25), 32 | ], 33 | ) 34 | ], 35 | ), 36 | ) 37 | -------------------------------------------------------------------------------- /python/controls/grid/compact_grid.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Column, Grid, Text 3 | 4 | 5 | class Person: 6 | def __init__( 7 | self, first_name: str, last_name: str, age: int = None, employee: bool = False 8 | ): 9 | self.first_name = first_name 10 | self.last_name = last_name 11 | self.age = age 12 | self.employee = employee 13 | 14 | 15 | with pglet.page("compact-grid") as page: 16 | 17 | page.add( 18 | page.add( 19 | Text("Compact grid with no header and multiple selection", size="large"), 20 | Grid( 21 | compact=True, 22 | header_visible=False, 23 | selection_mode="multiple", 24 | preserve_selection=True, 25 | columns=[ 26 | Column(max_width=100, field_name="first_name"), 27 | Column(max_width=100, field_name="last_name"), 28 | Column(max_width=100, field_name="age"), 29 | ], 30 | items=[ 31 | Person(first_name="John", last_name="Smith", age=30), 32 | Person(first_name="Samantha", last_name="Fox", age=43), 33 | Person(first_name="Alice", last_name="Brown", age=25), 34 | ], 35 | ), 36 | ) 37 | ) 38 | -------------------------------------------------------------------------------- /python/controls/grid/dynamic_grid.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Checkbox, Column, Grid, Stack, Text, Textbox, Toolbar, toolbar 3 | 4 | 5 | class Person: 6 | def __init__( 7 | self, first_name: str, last_name: str, age: int = None, employee: bool = False 8 | ): 9 | self.first_name = first_name 10 | self.last_name = last_name 11 | self.age = age 12 | self.employee = employee 13 | 14 | 15 | with pglet.page("dynamic-grid") as page: 16 | 17 | grid = None 18 | 19 | def delete_records(e): 20 | for r in grid.selected_items: 21 | grid.items.remove(r) 22 | page.update() 23 | 24 | delete_records = toolbar.Item( 25 | text="Delete records", icon="Delete", disabled=True, on_click=delete_records 26 | ) 27 | grid_toolbar = Toolbar(items=[delete_records]) 28 | 29 | def grid_items_selected(e): 30 | delete_records.disabled = len(e.control.selected_items) == 0 31 | delete_records.update() 32 | 33 | grid = Grid( 34 | selection_mode="multiple", 35 | compact=True, 36 | header_visible=True, 37 | columns=[ 38 | Column( 39 | name="First name", template_controls=[Textbox(value="{first_name}")] 40 | ), 41 | Column(name="Last name", template_controls=[Textbox(value="{last_name}")]), 42 | Column(name="Age", template_controls=[Text(value="{age}")]), 43 | Column( 44 | name="Is employee", template_controls=[Checkbox(value_field="employee")] 45 | ), 46 | ], 47 | items=[ 48 | Person(first_name="John", last_name="Smith", age=30, employee=False), 49 | Person(first_name="Jack", last_name="Brown", age=43, employee=True), 50 | Person(first_name="Alice", last_name="Fox", age=25, employee=False), 51 | ], 52 | margin=0, 53 | on_select=grid_items_selected, 54 | ) 55 | 56 | first_name = Textbox("First name") 57 | last_name = Textbox("Last name") 58 | age = Textbox("Age") 59 | 60 | def add_record(e): 61 | grid.items.append( 62 | Person( 63 | first_name=first_name.value, 64 | last_name=last_name.value, 65 | age=age.value, 66 | employee=True, 67 | ) 68 | ) 69 | first_name.value = "" 70 | last_name.value = "" 71 | age.value = "" 72 | page.update() 73 | 74 | page.add( 75 | Text("Dynamic grid with template columns", size="large"), 76 | grid_toolbar, 77 | grid, 78 | Text("Add new employee record", size="medium"), 79 | Stack(horizontal=True, controls=[first_name, last_name, age]), 80 | Button("Add record", on_click=add_record), 81 | ) 82 | 83 | input() 84 | -------------------------------------------------------------------------------- /python/controls/grid/sortable_grid.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Column, Grid, Text 3 | 4 | 5 | class Person: 6 | def __init__( 7 | self, first_name: str, last_name: str, age: int = None, employee: bool = False 8 | ): 9 | self.first_name = first_name 10 | self.last_name = last_name 11 | self.age = age 12 | self.employee = employee 13 | 14 | 15 | with pglet.page("sortable-grid") as page: 16 | 17 | page.add( 18 | Text("Sortable grid with resizable columns and selectable rows", size="large"), 19 | Grid( 20 | selection_mode="single", 21 | preserve_selection=True, 22 | columns=[ 23 | Column( 24 | resizable=True, 25 | sortable="string", 26 | name="First name", 27 | field_name="first_name", 28 | ), 29 | Column( 30 | resizable=True, 31 | sortable="string", 32 | sorted="asc", 33 | name="Last name", 34 | field_name="last_name", 35 | ), 36 | Column(resizable=True, sortable="number", name="Age", field_name="age"), 37 | ], 38 | items=[ 39 | Person(first_name="John", last_name="Smith", age=30), 40 | Person(first_name="Samantha", last_name="Fox", age=43), 41 | Person(first_name="Alice", last_name="Brown", age=25), 42 | ], 43 | ), 44 | ) 45 | -------------------------------------------------------------------------------- /python/controls/icon/icon_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Icon 3 | 4 | 5 | def main(page): 6 | page.title = "Icons example" 7 | page.gap = 20 8 | page.update() 9 | 10 | page.add( 11 | Stack( 12 | horizontal=True, 13 | controls=[ 14 | Icon("ChangeEntitlements", color="Magenta20"), 15 | Icon("shop", color="CyanBlue10"), 16 | Icon("TrainSolid"), 17 | ], 18 | ), 19 | Stack( 20 | horizontal=True, 21 | vertical_align="center", 22 | controls=[ 23 | Icon("BlockedSite", color="Orange20", size=25), 24 | Icon("settings", color="Gray20", size=50), 25 | Icon("save", color="Blue10", size=100), 26 | ], 27 | ), 28 | ) 29 | 30 | 31 | pglet.app("python-icon", target=main) 32 | -------------------------------------------------------------------------------- /python/controls/icon/icons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Icon, Stack 3 | with pglet.page("icons") as page: 4 | page.add( 5 | Stack(horizontal=True, controls=[ 6 | Icon("ChangeEntitlements", color='Magenta20'), 7 | Icon("shop", color='CyanBlue10'), 8 | Icon("TrainSolid") 9 | ]), 10 | Stack(horizontal=True, vertical_align='center', controls=[ 11 | Icon("BlockedSite", color='Orange20', size=25), 12 | Icon("settings", color='Gray20', size=50), 13 | Icon("save", color='Blue10', size=100) 14 | ]) 15 | ) -------------------------------------------------------------------------------- /python/controls/image_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Image 3 | 4 | 5 | def main(page): 6 | page.title = "Images example" 7 | page.gap = 20 8 | page.update() 9 | 10 | page.add( 11 | Image( 12 | src="https://via.placeholder.com/350x150", 13 | title="sample image", 14 | alt="Example with no image fit value and no height or width is specified.", 15 | ), 16 | Image( 17 | src="https://via.placeholder.com/350x150", 18 | width=600, 19 | title="sample image", 20 | alt="Example with no image fit value and only width is specified.", 21 | ), 22 | Image( 23 | src="https://via.placeholder.com/350x150", 24 | height=100, 25 | title="sample image", 26 | alt="Example with no image fit value and only height is specified.", 27 | ), 28 | Image( 29 | src="https://via.placeholder.com/350x150", 30 | width=100, 31 | height=100, 32 | title="sample image", 33 | alt="Example with no image fit value and height or width is specified.", 34 | ), 35 | ) 36 | page.add( 37 | Image(src='https://via.placeholder.com/350x150', title='sample image', fit='cover') 38 | ) 39 | 40 | 41 | 42 | pglet.app("python-image", target=main) 43 | -------------------------------------------------------------------------------- /python/controls/linechart_control.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import random 3 | import time 4 | 5 | import pglet 6 | from pglet import LineChart, Text 7 | from pglet.linechart import Data, Point 8 | 9 | 10 | def main(page): 11 | 12 | # simple line chart with numbers on X axis 13 | simple_chart = LineChart( 14 | legend=True, 15 | tooltips=True, 16 | stroke_width=4, 17 | y_min=0, 18 | y_max=100, 19 | y_format="{y}%", 20 | x_type="number", 21 | width="500", 22 | height="300px", 23 | lines=[ 24 | Data( 25 | legend="Line 1", 26 | points=[ 27 | Point(x=0, y=0), 28 | Point(x=1, y=10), 29 | Point(x=2, y=20), 30 | Point(x=3, y=50), 31 | Point(x=4, y=100), 32 | Point(x=5, y=90), 33 | Point(x=6, y=50), 34 | Point(x=7, y=30), 35 | Point(x=8, y=20), 36 | Point(x=9, y=5), 37 | ], 38 | ) 39 | ], 40 | ) 41 | 42 | # two lines on the same chart 43 | multi_chart = LineChart( 44 | legend=True, 45 | tooltips=True, 46 | stroke_width=4, 47 | y_ticks=5, 48 | y_min=0, 49 | y_max=100, 50 | y_format="{y}%", 51 | x_type="number", 52 | width="500", 53 | height="300px", 54 | lines=[], 55 | ) 56 | 57 | line1 = Data(legend="Line 1", color="Orange") 58 | line2 = Data(legend="Line 2", color="Magenta") 59 | for i in range(0, 21): 60 | line1.points.append(Point(x=i, y=random.random() * 100)) 61 | line2.points.append(Point(x=i, y=random.random() * 100)) 62 | multi_chart.lines.append(line1) 63 | multi_chart.lines.append(line2) 64 | 65 | # negative values with time on X axis 66 | temp_chart = LineChart( 67 | legend=True, 68 | tooltips=True, 69 | y_ticks=4, 70 | y_min=-20, 71 | y_max=20, 72 | y_format="{y} °C", 73 | x_type="date", 74 | width="500px", 75 | height="300px", 76 | lines=[Data(color="green", legend="t, °C")], 77 | ) 78 | start_date = datetime.datetime(2021, 4, 1, 10, 5) 79 | m = 0 80 | for i in range(0, 60): 81 | d = start_date + datetime.timedelta(minutes=m) 82 | v = round((random.random() - 0.5) * 40) 83 | temp_chart.lines[0].points.append(Point(x=d, y=v)) 84 | m += 1 85 | 86 | page.add( 87 | Text("Simple line chart with numbers on X axis", size="xLarge"), 88 | simple_chart, 89 | Text("Line chart with two lines", size="xLarge"), 90 | multi_chart, 91 | Text("Negative values with time on X axis", size="xLarge"), 92 | temp_chart, 93 | ) 94 | 95 | # simulate "running" chart 96 | while True: 97 | d = start_date + datetime.timedelta(minutes=m) 98 | v = round((random.random() - 0.5) * 40) 99 | temp_chart.lines[0].points.pop(0) 100 | temp_chart.lines[0].points.append(Point(x=d, y=v)) 101 | m += 1 102 | page.update() 103 | time.sleep(1) 104 | 105 | 106 | pglet.app("python-linechart", target=main) 107 | -------------------------------------------------------------------------------- /python/controls/link/basic_links.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Link 3 | with pglet.page("basic-links") as page: 4 | page.add( 5 | Link(url='http://google.com', value='Visit Google', new_window=True), 6 | Link(value='Link without URL', size='large'), 7 | Link(url='http://google.com', value='Disabled link', disabled=True)) -------------------------------------------------------------------------------- /python/controls/link/link_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Link, Icon 3 | 4 | 5 | def links(): 6 | return Stack( 7 | gap=20, 8 | controls=[ 9 | Text("Links", size="xLarge"), 10 | Link(url="http://google.com", value="Visit Google", new_window=True), 11 | Link(value="Link without URL", size="large"), 12 | Link(url="http://google.com", value="Disabled link", disabled=True), 13 | Link( 14 | url="http://google.com", 15 | controls=[Icon("Globe"), Text(" Link with child controls")], 16 | ), 17 | link_with_on_click(), 18 | ], 19 | ) 20 | 21 | 22 | def link_with_on_click(): 23 | def link_clicked(e): 24 | l.data += 1 25 | t.value = f"Link clicked {l.data} time(s)" 26 | stack.update() 27 | 28 | # l = Link('Link with on_click event', on_click=link_clicked, title='Click me!', data=0) 29 | 30 | l = Link( 31 | value="Link with on_click event", 32 | on_click=link_clicked, 33 | title="Click me!", 34 | data=0, 35 | ) 36 | t = Text() 37 | stack = Stack(controls=[l, t]) 38 | return stack 39 | 40 | 41 | def main(page): 42 | 43 | page.title = "Link control samples" 44 | page.update() 45 | page.add(links()) 46 | 47 | 48 | pglet.app("python-link", target=main) 49 | -------------------------------------------------------------------------------- /python/controls/link/link_with_child_controls.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Link, Text, Icon, Button 3 | with pglet.page("link-with-child-controls") as page: 4 | 5 | page.add( 6 | Link(url='http://google.com', controls=[ 7 | Icon('Globe'), 8 | Button('Action Button', action = True), 9 | Text(' Link with child controls') 10 | ])) -------------------------------------------------------------------------------- /python/controls/link/link_with_click_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Link, Text 3 | 4 | with pglet.page("link-with-click-event") as page: 5 | 6 | def link_clicked(e): 7 | l.data += 1 8 | t.value = f"Link clicked {l.data} time(s)" 9 | page.update() 10 | 11 | l = Link( 12 | value="Link with 'click' event", 13 | on_click=link_clicked, 14 | title="Click me!", 15 | data=0, 16 | ) 17 | t = Text() 18 | 19 | page.add(l, t) 20 | input() 21 | -------------------------------------------------------------------------------- /python/controls/message/basic_messages.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message 3 | with pglet.page("basic-messages") as page: 4 | page.add( 5 | Message(value='This is just a message.'), 6 | Message(value='Success message with dismiss button', dismiss=True, type='success'), 7 | Message(value='Error message with dismiss button', dismiss=True, type='error')) -------------------------------------------------------------------------------- /python/controls/message/message_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Message, MessageButton, Stack, Text 3 | 4 | 5 | def messages(): 6 | return Stack( 7 | width="70%", 8 | gap=20, 9 | controls=[ 10 | Text("Messages", size="xLarge"), 11 | Message(value="This is just a message."), 12 | Message( 13 | value="Success message with dismiss button", 14 | dismiss=True, 15 | type="success", 16 | ), 17 | Message( 18 | value="Error message with dismiss button", dismiss=True, type="error" 19 | ), 20 | Message( 21 | type="blocked", 22 | truncated=True, 23 | dismiss=True, 24 | value="Blocked Message - single line, with dismiss button and truncated text. Truncation is not available if you use action buttons or multiline and should be used sparingly. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris. You've been warned!", 25 | ), 26 | Message( 27 | type="warning", 28 | dismiss=True, 29 | value="Warning message with buttons", 30 | buttons=[ 31 | MessageButton(text="Yes", action="yes"), 32 | MessageButton(text="No", action="no"), 33 | ], 34 | ), 35 | Message( 36 | type="severeWarning", 37 | multiline=True, 38 | value="SevereWarning defaults to multiline. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.", 39 | buttons=[MessageButton("OK"), MessageButton("Cancel")], 40 | ), 41 | message_with_on_dismiss(), 42 | message_with_on_dismiss_and_buttons(), 43 | ], 44 | ) 45 | 46 | 47 | def message_with_on_dismiss(): 48 | def message_dismissed(e): 49 | t.value = "Message dismissed!" 50 | stack.update() 51 | 52 | m = Message( 53 | value="Message with on_dismiss event", 54 | dismiss=True, 55 | on_dismiss=message_dismissed, 56 | ) 57 | t = Text() 58 | stack = Stack(controls=[m, t]) 59 | return stack 60 | 61 | 62 | def message_with_on_dismiss_and_buttons(): 63 | def message_dismissed(e): 64 | t.value = f"Message dismissed with {e.data} action" 65 | stack.update() 66 | 67 | m = Message( 68 | value="Message with dismiss event and buttons", 69 | dismiss=True, 70 | on_dismiss=message_dismissed, 71 | buttons=[MessageButton("OK"), MessageButton("Cancel")], 72 | ) 73 | t = Text() 74 | stack = Stack(controls=[m, t]) 75 | return stack 76 | 77 | 78 | def main(page): 79 | 80 | page.title = "Message control samples" 81 | page.horizontal_align = "stretch" 82 | page.update() 83 | page.add(messages()) 84 | 85 | 86 | pglet.app("python-message", target=main) 87 | -------------------------------------------------------------------------------- /python/controls/message/message_with_dismiss_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message, Text 3 | with pglet.page("message-with-dismiss-event") as page: 4 | 5 | def message_dismissed(e): 6 | t.value = "Message dismissed!" 7 | page.update() 8 | 9 | m = Message(value="Message with 'dismiss' event", dismiss=True, on_dismiss=message_dismissed) 10 | t = Text() 11 | 12 | page.add(m, t) 13 | input() -------------------------------------------------------------------------------- /python/controls/message/message_with_dismiss_event_and_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message, MessageButton, Text 3 | with pglet.page("message-with-dismiss-event-and-buttons") as page: 4 | 5 | def message_dismissed(e): 6 | t.value = f"Message dismissed with {e.data} action" 7 | page.update() 8 | 9 | m = Message(value="Message with 'dismiss' event and buttons", dismiss=True, on_dismiss=message_dismissed, buttons=[ 10 | MessageButton('OK'), 11 | MessageButton('Cancel') 12 | ]) 13 | t = Text() 14 | 15 | page.add(m, t) 16 | input() -------------------------------------------------------------------------------- /python/controls/message/messages_with_buttons.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message, MessageButton 3 | with pglet.page("myapp") as page: 4 | 5 | page.add( 6 | Message(type='warning', dismiss=True, value='Warning message with buttons', buttons=[ 7 | MessageButton(text='Yes', action='yes'), 8 | MessageButton(text='No', action='no') 9 | ]), 10 | Message(type='severeWarning', multiline=True, value='SevereWarning defaults to multiline. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris.', buttons=[ 11 | MessageButton('OK'), 12 | MessageButton('Cancel') 13 | ])) -------------------------------------------------------------------------------- /python/controls/message/truncated_message.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message 3 | with pglet.page("truncated-message") as page: 4 | page.add( 5 | Message(type='blocked', truncated=True, dismiss=True, value='Blocked Message - single line, with dismiss button and truncated text. Truncation is not available if you use action buttons or multiline and should be used sparingly. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus, purus a lobortis tristique, odio augue pharetra metus, ac placerat nunc mi nec dui. Vestibulum aliquam et nunc semper scelerisque. Curabitur vitae orci nec quam condimentum porttitor et sed lacus. Vivamus ac efficitur leo. Cras faucibus mauris libero, ac placerat erat euismod et. Donec pulvinar commodo odio sit amet faucibus. In hac habitasse platea dictumst. Duis eu ante commodo, condimentum nibh pellentesque, laoreet enim. Fusce massa lorem, ultrices eu mi a, fermentum suscipit magna. Integer porta purus pulvinar, hendrerit felis eget, condimentum mauris. You\'ve been warned!')) -------------------------------------------------------------------------------- /python/controls/nav_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Message, Nav, Stack, Text, nav 3 | 4 | 5 | 6 | def navs(page): 7 | 8 | nav1 = None 9 | 10 | def menu_item_expanded(e): 11 | page.controls.insert( 12 | 0, Message(value=f'Menu item "{e.data}" was expanded', dismiss=True) 13 | ) 14 | page.update() 15 | 16 | def menu_item_collapsed(e): 17 | page.controls.insert( 18 | 0, Message(value=f'Menu item "{e.data}" was collapsed', dismiss=True) 19 | ) 20 | page.update() 21 | 22 | def menu_item_changed(e): 23 | page.controls.insert( 24 | 0, Message(value=f'Menu item was changed to "{nav1.value}"', dismiss=True) 25 | ) 26 | page.update() 27 | 28 | nav1 = Nav( 29 | on_collapse=menu_item_collapsed, 30 | on_expand=menu_item_expanded, 31 | on_change=menu_item_changed, 32 | items=[ 33 | nav.Item( 34 | text="Actions", 35 | items=[ 36 | nav.Item( 37 | expanded=True, 38 | text="New", 39 | items=[ 40 | nav.Item(key="email", text="Email message", icon="Mail"), 41 | nav.Item( 42 | key="calendar", 43 | text="Calendar event", 44 | icon="Calendar", 45 | icon_color="salmon", 46 | ), 47 | ], 48 | ), 49 | nav.Item( 50 | text="Share", 51 | items=[ 52 | nav.Item( 53 | disabled=True, 54 | key="share", 55 | text="Share to Facebook", 56 | icon="Share", 57 | ), 58 | nav.Item(key="twitter", text="Share to Twitter"), 59 | ], 60 | ), 61 | nav.Item( 62 | text="Links", 63 | items=[ 64 | nav.Item( 65 | text="Pglet website", 66 | icon="NavigateExternalInline", 67 | url="https://pglet.io", 68 | new_window=True, 69 | ), 70 | nav.Item( 71 | text="Google website", 72 | icon="NavigateExternalInline", 73 | url="https://google.com", 74 | new_window=True, 75 | ), 76 | ], 77 | ), 78 | ], 79 | ) 80 | ], 81 | ) 82 | 83 | nav2 = Nav( 84 | items=[ 85 | nav.Item( 86 | items=[ 87 | nav.Item( 88 | expanded=True, 89 | text="New", 90 | items=[ 91 | nav.Item(key="email", text="Email message", icon="Mail"), 92 | nav.Item( 93 | key="calendar", text="Calendar event", icon="Calendar" 94 | ), 95 | nav.Item( 96 | text="More options", 97 | items=[ 98 | nav.Item( 99 | key="option", 100 | text="Web component", 101 | icon="WebComponents", 102 | ) 103 | ], 104 | ), 105 | ], 106 | ), 107 | nav.Item( 108 | expanded=True, 109 | text="Share", 110 | items=[ 111 | nav.Item( 112 | key="facebook", text="Share on Facebook", icon="Share" 113 | ), 114 | nav.Item( 115 | key="twitter", text="Share to Twitter", icon="Share" 116 | ), 117 | ], 118 | ), 119 | ] 120 | ) 121 | ] 122 | ) 123 | 124 | return Stack( 125 | gap=30, 126 | controls=[ 127 | Stack( 128 | controls=[ 129 | Text( 130 | "Nav with groups and Expand, Collapse and Change events", 131 | size="xLarge", 132 | ), 133 | nav1, 134 | ] 135 | ), 136 | Stack(controls=[Text("Nav without groups", size="xLarge"), nav2]), 137 | ], 138 | ) 139 | 140 | 141 | def main(page): 142 | 143 | page.title = "Nav control samples" 144 | page.update() 145 | page.add(navs(page)) 146 | 147 | 148 | pglet.app("python-nav", target=main) 149 | -------------------------------------------------------------------------------- /python/controls/panel/basic_panel.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Panel, Text 3 | 4 | with pglet.page("basic-panel") as page: 5 | 6 | def button_clicked(e): 7 | p.open = True 8 | page.update() 9 | 10 | b = Button(text="Open panel", on_click=button_clicked) 11 | page.add(b) 12 | 13 | p = Panel(title="Basic panel", controls=[Text(value="Content goes here")]) 14 | 15 | page.add(p) 16 | 17 | input() 18 | -------------------------------------------------------------------------------- /python/controls/panel/panel-autodismiss.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Panel, Text 3 | 4 | with pglet.page("panel-custom") as page: 5 | 6 | def button_clicked(e): 7 | p.open = True 8 | page.update() 9 | 10 | b = Button(text="Open panel", on_click=button_clicked) 11 | page.add(b) 12 | 13 | p = Panel( 14 | title="Panel with autoDimiss = True", 15 | auto_dismiss=False, 16 | controls=[Text(value="Click anywhere outside the panel to close it")], 17 | ) 18 | 19 | page.add(p) 20 | 21 | input() 22 | -------------------------------------------------------------------------------- /python/controls/panel/panel-custom.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Dropdown, Panel, Text, Textbox, dropdown 3 | 4 | with pglet.page("panel-custom") as page: 5 | 6 | def button_clicked(e): 7 | p.type = dd.value 8 | p.width = tb.value 9 | tb.value = "" 10 | p.open = True 11 | page.update() 12 | 13 | dd = Dropdown( 14 | width=100, 15 | value="custom", 16 | options=[ 17 | dropdown.Option("custom"), 18 | dropdown.Option("customLeft"), 19 | ], 20 | ) 21 | b = Button(text="Open panel", on_click=button_clicked) 22 | tb = Textbox(label="Width", placeholder="For example, 888px, 888 or 50%", width=500) 23 | page.add(dd, tb, b) 24 | 25 | p = Panel(title="Basic panel", controls=[Text(value="Content goes here")]) 26 | 27 | page.add(p) 28 | 29 | input() 30 | -------------------------------------------------------------------------------- /python/controls/panel/panel-dismiss-options.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Checkbox, Panel, Text 3 | 4 | with pglet.page("panel-custom") as page: 5 | 6 | def button_clicked(e): 7 | 8 | p.light_dismiss = light_dismiss.value 9 | p.auto_dismiss = auto_dismiss.value 10 | p.blocking = blocking.value 11 | values.value = ( 12 | f"Panel properties are: {p.light_dismiss}, {p.auto_dismiss}, {p.blocking}." 13 | ) 14 | p.open = True 15 | page.update() 16 | 17 | values = Text() 18 | light_dismiss = Checkbox(label="Light dismiss", value=False) 19 | auto_dismiss = Checkbox(label="Auto-dismiss", value=True) 20 | blocking = Checkbox(label="Blocking", value=True) 21 | b = Button(text="Open panel", on_click=button_clicked) 22 | page.add(light_dismiss, auto_dismiss, blocking, b, values) 23 | 24 | t = Text("Content goes here") 25 | 26 | p = Panel( 27 | title="Panel with dismiss options", 28 | controls=[t], 29 | ) 30 | 31 | page.add(p) 32 | 33 | input() 34 | -------------------------------------------------------------------------------- /python/controls/panel/panel-size.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Button, Dropdown, Panel, Text, dropdown 3 | 4 | with pglet.page("panel-size") as page: 5 | 6 | def button_clicked(e): 7 | p.type = dd.value 8 | p.open = True 9 | page.update() 10 | 11 | dd = Dropdown( 12 | width=100, 13 | value="small", 14 | options=[ 15 | dropdown.Option("small"), 16 | dropdown.Option("smallLeft"), 17 | dropdown.Option("medium"), 18 | dropdown.Option("large"), 19 | dropdown.Option("largeFixed"), 20 | dropdown.Option("extraLarge"), 21 | dropdown.Option("fluid"), 22 | ], 23 | ) 24 | b = Button(text="Open panel", on_click=button_clicked) 25 | page.add(dd, b) 26 | 27 | p = Panel(title="Basic panel", controls=[Text(value="Content goes here")]) 28 | 29 | page.add(p) 30 | 31 | input() 32 | -------------------------------------------------------------------------------- /python/controls/piechart_control.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import random 3 | import time 4 | 5 | import pglet 6 | from pglet import Text, PieChart 7 | from pglet.piechart import Point 8 | 9 | 10 | def main(page): 11 | 12 | # simple donut-like pie chart 13 | chart1 = PieChart( 14 | width="50%", 15 | inner_radius=40, 16 | inner_value=42, 17 | points=[Point(color="yellow", value=10), Point(color="green", value=32)], 18 | ) 19 | 20 | # pie chart with legent 21 | chart2 = PieChart( 22 | width="50%", 23 | legend=True, 24 | tooltips=True, 25 | points=[ 26 | Point(legend="Free space", value=10, tooltip="10%"), 27 | Point(legend="Total space", value=20, tooltip="20%"), 28 | Point(legend="Reserved space", value=30, tooltip="30%"), 29 | Point(legend="A:", value=20, tooltip="20%"), 30 | Point(legend="B:", value=20, tooltip="20%"), 31 | Point(legend="C:", value=20, tooltip="20%"), 32 | ], 33 | ) 34 | 35 | page.add( 36 | Text("Donut-like PieChart", size="xLarge"), 37 | chart1, 38 | Text("PieChart with legend and tooltips", size="xLarge"), 39 | chart2, 40 | ) 41 | 42 | 43 | pglet.app("python-piechart", target=main) 44 | -------------------------------------------------------------------------------- /python/controls/progress/basic_progress.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import pglet 4 | from pglet import Progress, Text 5 | 6 | with pglet.page("basic-progress") as page: 7 | 8 | prog1 = Progress("Copying file1.txt to file2.txt", value=0, width="50%") 9 | page.add(Text("Default Progress", size="xLarge"), prog1) 10 | 11 | for i in range(0, 101): 12 | prog1.value = i 13 | prog1.update() 14 | time.sleep(0.005) 15 | 16 | prog2 = Progress("Provisioning your account", value=0, width="50%") 17 | page.add(prog2) 18 | 19 | prog2.description = "Preparing environment..." 20 | prog2.value = 0 21 | prog2.update() 22 | time.sleep(2) 23 | 24 | prog2.description = "Collecting information..." 25 | prog2.value = 20 26 | prog2.update() 27 | time.sleep(2) 28 | 29 | prog2.description = "Creatring database entities..." 30 | prog2.value = 40 31 | prog2.update() 32 | time.sleep(2) 33 | 34 | prog2.description = "Verifying the data..." 35 | prog2.value = 60 36 | prog2.update() 37 | time.sleep(2) 38 | 39 | prog2.description = "Finishing the process, almost done..." 40 | prog2.value = 80 41 | prog2.update() 42 | time.sleep(2) 43 | 44 | prog2.description = "Your account has been created!" 45 | prog2.value = 100 46 | prog2.update() 47 | -------------------------------------------------------------------------------- /python/controls/progress/indeterminate_progress.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Progress, Text 3 | 4 | with pglet.page("basic-progress") as page: 5 | 6 | page.add( 7 | Text("Indeterminate Progress", size='xLarge'), 8 | Progress("Operation progress", description="Doing something indefinite...", width='50%') 9 | ) 10 | -------------------------------------------------------------------------------- /python/controls/progress/progress_control.py: -------------------------------------------------------------------------------- 1 | import time 2 | import pglet 3 | from pglet import Text, Progress 4 | 5 | page = pglet.page("python-progress") 6 | page.clean() 7 | 8 | page.add( 9 | Text("Indeterminate Progress", size="xLarge"), 10 | Progress( 11 | "Operation progress", description="Doing something indefinite...", width="50%" 12 | ), 13 | ) 14 | 15 | prog1 = Progress("Copying file1.txt to file2.txt", value=0, width="50%") 16 | page.add(Text("Default Progress", size="xLarge"), prog1) 17 | 18 | for i in range(0, 101): 19 | prog1.value = i 20 | prog1.update() 21 | time.sleep(0.005) 22 | 23 | prog2 = Progress("Provisioning your account", value=0, width="50%") 24 | page.add(prog2) 25 | 26 | prog2.description = "Preparing environment..." 27 | prog2.value = 0 28 | prog2.update() 29 | time.sleep(2) 30 | 31 | prog2.description = "Collecting information..." 32 | prog2.value = 20 33 | prog2.update() 34 | time.sleep(2) 35 | 36 | prog2.description = "Creatring database entities..." 37 | prog2.value = 40 38 | prog2.update() 39 | time.sleep(2) 40 | 41 | prog2.description = "Verifying the data..." 42 | prog2.value = 60 43 | prog2.update() 44 | time.sleep(2) 45 | 46 | prog2.description = "Finishing the process, almost done..." 47 | prog2.value = 80 48 | prog2.update() 49 | time.sleep(2) 50 | 51 | prog2.description = "Your account has been created!" 52 | prog2.value = 100 53 | prog2.update() 54 | -------------------------------------------------------------------------------- /python/controls/resize_stacks.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text 3 | 4 | 5 | def main(page): 6 | 7 | left_column = Stack( 8 | width="33%", 9 | height=40, 10 | bgcolor="Orange10", 11 | horizontal_align="center", 12 | vertical_align="center", 13 | controls=[Text("Column 1")], 14 | ) 15 | center_column = Stack( 16 | width="33%", 17 | height=40, 18 | bgcolor="CyanBlue10", 19 | horizontal_align="center", 20 | vertical_align="center", 21 | controls=[Text("Column 2")], 22 | ) 23 | right_column = Stack( 24 | width="33%", 25 | height=40, 26 | bgcolor="YellowGreen10", 27 | horizontal_align="center", 28 | vertical_align="center", 29 | controls=[Text("Column 3")], 30 | ) 31 | 32 | page.add( 33 | Stack( 34 | horizontal=True, 35 | wrap=True, 36 | gap=0, 37 | width="100%", 38 | bgcolor="#ddddee", 39 | horizontal_align="space-between", 40 | controls=[left_column, center_column, right_column], 41 | ) 42 | ) 43 | 44 | def page_resize(e): 45 | print("page_resize:", page.win_width, page.win_height) 46 | if page.win_width < 576: 47 | # small device 48 | left_column.width = center_column.width = right_column.width = "100%" 49 | elif page.win_width > 576 and page.win_width < 768: 50 | # medium device 51 | left_column.width = center_column.width = right_column.width = "50%" 52 | right_column.width = "100%" 53 | else: 54 | # device with a large screen 55 | left_column.width = center_column.width = right_column.width = "33.3%" 56 | page.update() 57 | 58 | page.on_resize = page_resize 59 | page_resize(None) 60 | 61 | 62 | pglet.app("page-resize", target=main) 63 | -------------------------------------------------------------------------------- /python/controls/searchbox/basic_searchboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SearchBox 3 | with pglet.page("basic-searchboxes") as page: 4 | page.add( 5 | SearchBox(), 6 | SearchBox(underlined=True, placeholder='Underlined SearchBox'), 7 | SearchBox(disabled=True, placeholder='Disabled SearchBox'), 8 | SearchBox(placeholder='SearchBox with icon', icon='Filter', icon_color='red')) -------------------------------------------------------------------------------- /python/controls/searchbox/searchbox-with-change-event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SearchBox, Text 3 | 4 | with pglet.page("searchbox-with-change-event") as page: 5 | 6 | def searchbox_changed(e): 7 | t.value = f'You have searched for {sb.value}.' 8 | page.update() 9 | 10 | sb = SearchBox(placeholder='Search something...', on_change=searchbox_changed) 11 | t = Text() 12 | 13 | page.add(sb, t) 14 | 15 | input() -------------------------------------------------------------------------------- /python/controls/searchbox/searchbox-with-search-clear-escape-events.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SearchBox, Stack, Text 3 | 4 | with pglet.page("searchbox-with-search-clear-and-escape-events") as page: 5 | 6 | def enter_clicked(e): 7 | messages.controls.append(Text(f'You have searched for {sb.value}.')) 8 | sb.value = '' 9 | page.update() 10 | 11 | def clear_or_esc_clicked(e): 12 | sb.value = '' 13 | messages.controls.append(Text('You have cleared the box.')) 14 | page.update() 15 | 16 | sb = SearchBox(width=300, placeholder='Search something and click Enter, X or Esc', on_search=enter_clicked, on_clear=clear_or_esc_clicked) 17 | messages = Stack() 18 | 19 | page.add(sb, messages) 20 | 21 | input() -------------------------------------------------------------------------------- /python/controls/searchbox/searchbox_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, SearchBox 3 | 4 | 5 | def searchboxes(): 6 | return Stack( 7 | gap=20, 8 | controls=[ 9 | Stack( 10 | horizontal=True, 11 | gap=25, 12 | controls=[ 13 | Stack( 14 | controls=[ 15 | Text("Default searchbox", size="xLarge"), 16 | SearchBox(), 17 | ] 18 | ), 19 | Stack( 20 | controls=[ 21 | Text("Underlined SearchBox", size="xLarge"), 22 | SearchBox( 23 | underlined=True, placeholder="Search files and folders" 24 | ), 25 | ] 26 | ), 27 | ], 28 | ), 29 | Stack( 30 | horizontal=True, 31 | gap=25, 32 | controls=[ 33 | Stack( 34 | controls=[ 35 | Text("Disabled SearchBox", size="xLarge"), 36 | SearchBox(disabled=True, placeholder="Search something..."), 37 | SearchBox( 38 | underlined=True, 39 | disabled=True, 40 | placeholder="Search something...", 41 | ), 42 | ] 43 | ), 44 | Stack( 45 | controls=[ 46 | Text("SearchBox with custom icon", size="xLarge"), 47 | SearchBox( 48 | placeholder="Filter something by", 49 | icon="Filter", 50 | icon_color="red", 51 | ), 52 | ] 53 | ), 54 | ], 55 | ), 56 | Text("SearchBox with Search, Clear and Escape events", size="xLarge"), 57 | searchbox_with_search_clear_escape(), 58 | Text("SearchBox with Change event", size="xLarge"), 59 | searchbox_with_change(), 60 | ], 61 | ) 62 | 63 | 64 | def searchbox_with_search_clear_escape(): 65 | def enter_clicked(e): 66 | messages.controls.append(Text(f"You have searched for {sb.value}.")) 67 | sb.value = "" 68 | stack.update() 69 | 70 | def clear_or_esc_clicked(e): 71 | messages.controls.append(Text("You have cleared the box.")) 72 | stack.update() 73 | 74 | sb = SearchBox( 75 | placeholder="Search something and click Enter, X or Esc", 76 | on_search=enter_clicked, 77 | on_clear=clear_or_esc_clicked, 78 | ) 79 | messages = Stack() 80 | stack = Stack(controls=[sb, messages]) 81 | return stack 82 | 83 | 84 | def searchbox_with_change(): 85 | def searchbox_changed(e): 86 | t.value = f"You have searched for {sb.value}." 87 | stack.update() 88 | 89 | sb = SearchBox(placeholder="Search something...", on_change=searchbox_changed) 90 | t = Text() 91 | stack = Stack(controls=[sb, t]) 92 | return stack 93 | 94 | 95 | def main(page): 96 | 97 | page.title = "Searchbox control samples" 98 | page.update() 99 | page.add(searchboxes()) 100 | 101 | 102 | pglet.app("python-searchbox", target=main) 103 | -------------------------------------------------------------------------------- /python/controls/signin_app.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Textbox, Button, Checkbox 3 | 4 | 5 | def main(page): 6 | 7 | logged_user = Text(f"Welcome, {page.user_login}!") 8 | 9 | def signout_clicked(e): 10 | page.signout() 11 | 12 | def page_signin(e): 13 | print("Sign in event") 14 | logged_user.value = page.user_login 15 | page.update() 16 | 17 | def page_signout(e): 18 | print("Sign out event") 19 | logged_user.value = "Not logged in" 20 | page.update() 21 | 22 | page.on_signin = page_signin 23 | page.on_signout = page_signout 24 | 25 | page.add(logged_user, Button("Sign out", on_click=signout_clicked)) 26 | 27 | 28 | pglet.app("pglet-signin-test", target=main, web=False, permissions="*") 29 | -------------------------------------------------------------------------------- /python/controls/slider/basic_sliders.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Slider 3 | with pglet.page("basic-sliders") as page: 4 | page.add( 5 | Slider(width='50%', label='Default slider'), 6 | Slider(width='50%', label='Default disabled slider', disabled=True)) -------------------------------------------------------------------------------- /python/controls/slider/slider-with-change-event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Slider, Text 3 | with pglet.page("slider-with-change-event") as page: 4 | 5 | def slider_changed(e): 6 | t.value = f"Slider changed to {int(s.value)}" 7 | page.update() 8 | 9 | t = Text() 10 | s = Slider(width='50%', label="Slider with 'change' event", on_change=slider_changed, data=0) 11 | 12 | page.add(s, t) 13 | 14 | input() -------------------------------------------------------------------------------- /python/controls/slider/slider_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Slider 3 | 4 | 5 | def sliders(): 6 | return Stack( 7 | width="50%", 8 | controls=[ 9 | Stack( 10 | controls=[ 11 | Text("Horizontal sliders", size="xLarge"), 12 | Slider(label="Default slider"), 13 | Slider(label="Default disabled slider", disabled=True), 14 | Slider(label="Slider with value", show_value=True, value=4), 15 | Slider( 16 | label="Slider with formatted value", 17 | show_value=True, 18 | min=0, 19 | max=100, 20 | value=40, 21 | value_format="{value}%", 22 | ), 23 | Slider( 24 | show_value=True, 25 | label="Origin from zero", 26 | min=-5, 27 | max=15, 28 | step=1, 29 | value=-2, 30 | ), 31 | slider_with_on_change(), 32 | ] 33 | ), 34 | Text("Vertical sliders", size="xLarge"), 35 | Stack( 36 | horizontal=True, 37 | height="200px", 38 | controls=[ 39 | Slider(vertical=True, label="Default slider"), 40 | Slider( 41 | vertical=True, label="Default disabled slider", disabled=True 42 | ), 43 | Slider( 44 | vertical=True, 45 | label="Slider with value", 46 | show_value=True, 47 | value=4, 48 | ), 49 | Slider( 50 | vertical=True, 51 | label="Slider with formatted value", 52 | show_value=True, 53 | min=0, 54 | max=100, 55 | value=40, 56 | value_format="{value}%", 57 | ), 58 | Slider( 59 | vertical=True, 60 | show_value=True, 61 | label="Origin from zero", 62 | min=-5, 63 | max=15, 64 | step=1, 65 | value=-2, 66 | ), 67 | ], 68 | ), 69 | ], 70 | ) 71 | 72 | 73 | def slider_with_on_change(): 74 | def slider_changed(e): 75 | s.data += 1 76 | t.value = f"Slider changed to {int(s.value)}" 77 | stack.update() 78 | 79 | s = Slider("Slider with Change event", on_change=slider_changed, data=0) 80 | t = Text() 81 | stack = Stack(controls=[s, t]) 82 | return stack 83 | 84 | 85 | def main(page): 86 | 87 | page.title = "Slider control samples" 88 | page.update() 89 | page.add(sliders()) 90 | 91 | 92 | pglet.app("python-slider", target=main) 93 | -------------------------------------------------------------------------------- /python/controls/slider/sliders-with-values.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Slider, Button, Text 3 | with pglet.page("sliders-with-values") as page: 4 | 5 | def button_clicked(e): 6 | t.value = f"Sliders values are: {s1.value}, {s2.value}, {s3.value}." 7 | page.update() 8 | 9 | t = Text() 10 | s1 = Slider(width='50%', label='Slider with value', show_value=True, value=4) 11 | s2 = Slider(width='50%', label='Slider with formatted value', show_value=True, min=0, max=100, value=40, value_format='{value}%') 12 | s3 = Slider(width='50%', show_value=True, label='Origin from zero', min=-5, max=15, step=1, value=-2) 13 | 14 | b = Button(text='Submit', on_click=button_clicked) 15 | page.add(s1, s2, s3, b, t) 16 | 17 | input() -------------------------------------------------------------------------------- /python/controls/spinbutton/basic_spinbutton.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SpinButton, Button, Text 3 | with pglet.page("basic-spinbutton") as page: 4 | def button_clicked(e): 5 | t.value = f"Spinbutton value is: {sb.value}." 6 | page.update() 7 | 8 | t = Text() 9 | sb = SpinButton(width='50%', label='Default SpinButton') 10 | b = Button(text='Submit', on_click=button_clicked) 11 | page.add(sb, b, t) 12 | 13 | input() 14 | 15 | -------------------------------------------------------------------------------- /python/controls/spinbutton/spinbutton_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, SpinButton 3 | 4 | 5 | def spinbuttons(): 6 | return Stack( 7 | width="50%", 8 | controls=[ 9 | Text("SpinButons", size="xLarge"), 10 | SpinButton(label="Default slider"), 11 | ], 12 | ) 13 | 14 | 15 | def main(page): 16 | 17 | page.title = "Spinbutton control samples" 18 | page.update() 19 | page.add(spinbuttons()) 20 | 21 | 22 | pglet.app("python-spinbutton", target=main) 23 | -------------------------------------------------------------------------------- /python/controls/spinbutton/spinbutton_with_change_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SpinButton, Text 3 | with pglet.page("spinbutton-with-change-event") as page: 4 | def spinbutton_changed(e): 5 | t.value = f"SpinButton value changed to {sb.value}" 6 | page.update() 7 | 8 | t = Text() 9 | sb = SpinButton(width='50%', label='Default SpinButton', on_change=spinbutton_changed) 10 | page.add(sb, t) 11 | 12 | input() 13 | 14 | -------------------------------------------------------------------------------- /python/controls/spinner/spinner_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Spinner, Text 3 | 4 | 5 | def main(page): 6 | page.add( 7 | Text("Spinner sizes", size="xLarge"), 8 | Spinner("Extra small spinner", size="xSmall", label_position="left"), 9 | Spinner("Small spinner", size="small", label_position="left"), 10 | Spinner("Medium spinner", size="medium", label_position="left"), 11 | Spinner("Large spinner", size="large", label_position="left"), 12 | Text("Spinner label positioning", size="xLarge"), 13 | Text("Spinner with label positioned below"), 14 | Spinner("I am definitely loading...", label_position="bottom"), 15 | Text("Spinner with label positioned above"), 16 | Spinner("Seriously, still loading...", label_position="top"), 17 | Text("Spinner with label positioned to right"), 18 | Spinner("Wait, wait...", label_position="right"), 19 | Text("Spinner with label positioned to left"), 20 | Spinner("Nope, still loading...", label_position="left"), 21 | ) 22 | 23 | 24 | pglet.app("python-spinner", target=main) 25 | -------------------------------------------------------------------------------- /python/controls/spinner/spinner_label_positioning.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Spinner, Text 3 | 4 | with pglet.page("spinner-label-positioning") as page: 5 | 6 | page.add( 7 | Text("Spinner label positioning", size="xLarge"), 8 | Text("Spinner with label positioned below"), 9 | Spinner("I am definitely loading...", label_position="bottom"), 10 | Text("Spinner with label positioned above"), 11 | Spinner("Seriously, still loading...", label_position="top"), 12 | Text("Spinner with label positioned to right"), 13 | Spinner("Wait, wait...", label_position="right"), 14 | Text("Spinner with label positioned to left"), 15 | Spinner("Nope, still loading...", label_position="left"), 16 | ) 17 | -------------------------------------------------------------------------------- /python/controls/spinner/spinner_size.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Spinner, Text 3 | 4 | with pglet.page("spinner-size") as page: 5 | 6 | page.add( 7 | Text("Spinner sizes", size="xLarge"), 8 | Spinner("Extra small spinner", size="xSmall", label_position="left"), 9 | Spinner("Small spinner", size="small", label_position="left"), 10 | Spinner("Medium spinner", size="medium", label_position="left"), 11 | Spinner("Large spinner", size="large", label_position="left"), 12 | ) 13 | -------------------------------------------------------------------------------- /python/controls/split.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import SplitStack, Stack, Text 3 | from pglet.button import Button 4 | 5 | def split_resize(e): 6 | for c in e.control.controls: 7 | print("size", c.width if e.control.horizontal else c.height) 8 | 9 | 10 | page = pglet.page("split1") 11 | page.title = "Split test" 12 | page.horizontal_align = "stretch" 13 | page.vertical_fill = True 14 | st = SplitStack( 15 | height="100%", 16 | horizontal=True, 17 | # gutter_color="#eee", 18 | gutter_size=10, 19 | on_resize=split_resize, 20 | controls=[ 21 | Stack(width="200", min_width="200", height="100%", controls=[Text("Column A")]), 22 | Stack(height="100%", controls=[Text("Column B")]), 23 | Stack( 24 | height="100%", 25 | width="30%", 26 | controls=[ 27 | SplitStack( 28 | height="100%", 29 | gutter_color="yellow", 30 | gutter_hover_color="orange", 31 | gutter_drag_color="blue", 32 | on_resize=split_resize, 33 | controls=[ 34 | Stack( 35 | width="100%", 36 | bgcolor="lightGreen", 37 | controls=[Text("Row A")], 38 | ), 39 | Stack( 40 | width="100%", 41 | height="200", 42 | max_height="400", 43 | bgcolor="lightGreen", 44 | controls=[Text("Row B")], 45 | ), 46 | ], 47 | ) 48 | ], 49 | ), 50 | ], 51 | ) 52 | page.add(st) 53 | 54 | input() 55 | -------------------------------------------------------------------------------- /python/controls/stack/horizontal_stack_gap_padding.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Slider, Text 3 | with pglet.page("horizontal-stack-gap-padding") as page: 4 | 5 | bg_color = '#ddddee' 6 | page.horizontal_align = 'stretch' 7 | 8 | def items(count): 9 | items = [] 10 | for i in range(1, count + 1): 11 | items.append(Text(value=i, align='center', vertical_align='center', width=30, height=30, bgcolor='BlueMagenta10', color='white', padding=5)) 12 | return items 13 | 14 | def gap_slider_change(e): 15 | spacing_stack.gap = int(e.control.value) 16 | spacing_stack.update() 17 | 18 | def padding_slider_change(e): 19 | spacing_stack.padding = e.control.value 20 | spacing_stack.update() 21 | 22 | gap_slider = Slider("Gap between items", min=0, max=50, step=1, value=0, show_value=True, on_change=gap_slider_change) 23 | padding_slider = Slider("Stack padding", min=0, max=50, step=1, value=0, show_value=True, on_change=padding_slider_change) 24 | spacing_stack = Stack(horizontal=True, bgcolor=bg_color, gap=0, controls=items(5)) 25 | 26 | page.add(gap_slider, padding_slider, spacing_stack) 27 | 28 | input() 29 | 30 | 31 | -------------------------------------------------------------------------------- /python/controls/stack/horizontal_stack_horizontal_alignments.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text 3 | 4 | with pglet.page("horizontal-stack-horizontal-alignments") as page: 5 | 6 | bg_color = "#ddddee" 7 | page.horizontal_align = "stretch" 8 | 9 | def items(count): 10 | items = [] 11 | for i in range(1, count + 1): 12 | items.append( 13 | Text( 14 | value=i, 15 | align="center", 16 | vertical_align="center", 17 | width=30, 18 | height=30, 19 | bgcolor="BlueMagenta10", 20 | color="white", 21 | padding=5, 22 | ) 23 | ) 24 | return items 25 | 26 | def horizontal_stack(horiz_align): 27 | return Stack( 28 | controls=[ 29 | Text(value=horiz_align), 30 | Stack( 31 | horizontal=True, 32 | horizontal_align=horiz_align, 33 | vertical_align="center", 34 | gap=20, 35 | bgcolor=bg_color, 36 | controls=items(3), 37 | ), 38 | ] 39 | ) 40 | 41 | page.add( 42 | horizontal_stack("start"), 43 | horizontal_stack("center"), 44 | horizontal_stack("center"), 45 | horizontal_stack("space-between"), 46 | horizontal_stack("space-around"), 47 | horizontal_stack("space-evenly"), 48 | ) 49 | 50 | input() 51 | -------------------------------------------------------------------------------- /python/controls/stack/horizontal_stack_vertical_alignments.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text 3 | with pglet.page("horizontal-stack-vertical-alignments") as page: 4 | 5 | bg_color = '#ddddee' 6 | page.horizontal_align = 'stretch' 7 | 8 | def items(count): 9 | items = [] 10 | for i in range(1, count + 1): 11 | items.append(Text(value=i, align='center', vertical_align='center', width=30, height=30, bgcolor='BlueMagenta10', color='white', padding=5)) 12 | return items 13 | 14 | page.add( 15 | Text('start'), 16 | Stack(horizontal=True, vertical_align='start', height=100, bgcolor=bg_color, gap=20, controls=items(3)), 17 | Text('center'), 18 | Stack(horizontal=True, vertical_align='center', height=100, bgcolor=bg_color, gap=20, controls=items(3)), 19 | Text('end'), 20 | Stack(horizontal=True, vertical_align='end', height=100, bgcolor=bg_color, gap=20, controls=items(3))) 21 | 22 | input() 23 | 24 | 25 | -------------------------------------------------------------------------------- /python/controls/stack/horizontal_stack_wrapping.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Slider, Text 3 | with pglet.page("horizontal-stack-wrapping") as page: 4 | 5 | bg_color = '#ddddee' 6 | page.horizontal_align = 'stretch' 7 | 8 | def items(count): 9 | items = [] 10 | for i in range(1, count + 1): 11 | items.append(Text(value=i, align='center', vertical_align='center', width=30, height=30, bgcolor='BlueMagenta10', color='white', padding=5)) 12 | return items 13 | 14 | def wrap_slider_change(e): 15 | width = int(e.control.value) 16 | wrap_stack.width = f"{width}%" 17 | wrap_stack.update() 18 | 19 | wrap_slider = Slider("Change the stack width to see how child items wrap onto multiple rows:", 20 | min=0, max=100, step=10, value=100, show_value=True, value_format='{value}%', on_change=wrap_slider_change) 21 | 22 | wrap_stack = Stack(horizontal=True, wrap=True, bgcolor=bg_color, gap=20, controls=items(10)) 23 | 24 | page.add(wrap_slider, wrap_stack) 25 | 26 | input() 27 | 28 | 29 | -------------------------------------------------------------------------------- /python/controls/stack/stack_with_submit_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Textbox, Message 3 | with pglet.page("stack-with-submit-event") as page: 4 | 5 | bg_color = '#ddddee' 6 | page.horizontal_align = 'stretch' 7 | 8 | def stack_on_submit(e): 9 | stack = e.control 10 | stack.controls.insert(0, Message("Form has been submitted!", type='success', dismiss=True)) 11 | stack.update() 12 | 13 | form1 = Stack(padding=10, width='50%', border='2px solid #eee', border_radius=5, controls=[ 14 | Text("Pressing ENTER inside the stack will fire 'submit' event."), 15 | Textbox("First name"), 16 | Textbox("Last name") 17 | ], on_submit=stack_on_submit) 18 | 19 | page.add(form1) 20 | 21 | input() 22 | 23 | 24 | -------------------------------------------------------------------------------- /python/controls/stack/vertical_stack_vertical_alignments.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text 3 | with pglet.page("vertical-stack-vertical-alignments") as page: 4 | 5 | bg_color = '#ddddee' 6 | page.horizontal_align = 'stretch' 7 | 8 | def items(count): 9 | items = [] 10 | for i in range(1, count + 1): 11 | items.append(Text(value=i, align='center', vertical_align='center', width=30, height=30, bgcolor='BlueMagenta10', color='white', padding=5)) 12 | return items 13 | 14 | def vertical_stack(vert_align): 15 | return Stack(width='20%', controls=[ 16 | Text(value=vert_align), 17 | Stack(vertical_align=vert_align, horizontal_align='center', height=300, gap=20, bgcolor=bg_color, controls=items(3)) 18 | ]) 19 | 20 | page.add(Stack(horizontal=True, horizontal_align='space-between', width='100%', controls=[ 21 | vertical_stack('start'), 22 | vertical_stack('center'), 23 | vertical_stack('end'), 24 | vertical_stack('space-between'), 25 | vertical_stack('space-around'), 26 | vertical_stack('space-evenly') 27 | ])) 28 | 29 | input() 30 | 31 | 32 | -------------------------------------------------------------------------------- /python/controls/tabs_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Icon 3 | from pglet import Stack, Text, Tabs, Tab, Message, Textbox, Button 4 | 5 | 6 | def tabs(page): 7 | 8 | message = Message(dismiss=True, visible=False) 9 | 10 | def tabs_changed(e): 11 | message.visible = True 12 | message.value = f'Tabs changed to "{e.control.value}", count increased' 13 | e.control.tabs[2].count += 1 14 | page.update() 15 | 16 | link_tabs = Tabs( 17 | margin=10, 18 | on_change=tabs_changed, 19 | tabs=[ 20 | Tab( 21 | text="Regular tab", 22 | controls=[ 23 | Stack( 24 | horizontal=True, 25 | controls=[Text("This is tab1"), Text("This is tab1 - line2")], 26 | ) 27 | ], 28 | ), 29 | Tab( 30 | icon="Globe", 31 | text="Tab with icon", 32 | controls=[ 33 | Stack( 34 | gap=10, 35 | controls=[ 36 | Text(value="This is tab2"), 37 | Text(value="This is tab2 - line2"), 38 | ], 39 | ) 40 | ], 41 | ), 42 | Tab( 43 | text="Tab with icon and count", 44 | icon="Ringer", 45 | count=0, 46 | controls=[ 47 | Stack( 48 | gap=10, 49 | controls=[Text("This is tab3"), Text("This is tab3 - line2")], 50 | ) 51 | ], 52 | ), 53 | ], 54 | ) 55 | 56 | solid_tabs = Tabs( 57 | solid=True, 58 | margin="10px", 59 | tabs=[ 60 | Tab( 61 | text="JavaScript", 62 | icon="Code", 63 | count=10, 64 | controls=[Textbox(label="Some textbox")], 65 | ), 66 | Tab(text="C#", count=30, controls=[Button(text="Hello button!")]), 67 | Tab(text="Python", count=0, controls=[Text(value="Just text...")]), 68 | ], 69 | ) 70 | 71 | changeable = Tabs( 72 | margin=10, 73 | tabs=[ 74 | Tab( 75 | text="Left", 76 | key="left", 77 | controls=[ 78 | Stack( 79 | padding=10, 80 | horizontal_align="center", 81 | controls=[Icon("AlignLeft", size=25)], 82 | ) 83 | ], 84 | ), 85 | Tab( 86 | text="Center", 87 | key="center", 88 | controls=[ 89 | Stack( 90 | padding=10, 91 | horizontal_align="center", 92 | controls=[Icon("AlignCenter", size=25)], 93 | ) 94 | ], 95 | ), 96 | Tab( 97 | text="Right", 98 | key="right", 99 | controls=[ 100 | Stack( 101 | padding=10, 102 | horizontal_align="center", 103 | controls=[Icon("AlignRight", size=25)], 104 | ) 105 | ], 106 | ), 107 | ], 108 | ) 109 | 110 | def change_tab(direction): 111 | tabs = changeable.tabs 112 | keys = [tab.key for tab in tabs] 113 | current_key = ( 114 | changeable.value or keys[0] 115 | ) # Workaround for Tabs control initially having no value 116 | changeable.value = keys[(keys.index(current_key) + direction) % len(tabs)] 117 | changeable.update() 118 | 119 | tab_controls = Stack( 120 | horizontal=True, 121 | controls=[ 122 | Button(icon="ChevronLeftMed", on_click=lambda event: change_tab(-1)), 123 | Button(icon="ChevronRightMed", on_click=lambda event: change_tab(+1)), 124 | ], 125 | ) 126 | 127 | changeable_tabs_container = Stack( 128 | width=200, horizontal_align="center", controls=[changeable, tab_controls] 129 | ) 130 | 131 | return Stack( 132 | gap=30, 133 | width="50%", 134 | controls=[ 135 | message, 136 | Stack( 137 | controls=[Text("Link tabs with Change event", size="xLarge"), link_tabs] 138 | ), 139 | Stack(controls=[Text("Solid tabs", size="xLarge"), solid_tabs]), 140 | Stack( 141 | controls=[ 142 | Text("Change tabs with buttons", size="xLarge"), 143 | changeable_tabs_container, 144 | ] 145 | ), 146 | ], 147 | ) 148 | 149 | 150 | def main(page): 151 | 152 | page.title = "Tabs control samples" 153 | page.horizontal_align = "stretch" 154 | page.update() 155 | page.add(tabs(page)) 156 | 157 | 158 | pglet.app("python-tabs", target=main) 159 | -------------------------------------------------------------------------------- /python/controls/text/text_alignments.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Stack 3 | with pglet.page("text-alignments") as page: 4 | 5 | page.add( 6 | Stack(horizontal=True, controls=[ 7 | Text('left top', align='left', vertical_align='top', width=100, height=100, bgcolor='salmon', color='white', padding=5), 8 | Text('center top', align='center', vertical_align='top', width=100, height=100, bgcolor='salmon', color='white', padding=5, size='large', border='1px solid #555'), 9 | Text('right top', align='right', vertical_align='top', width=100, height=100, bgcolor='salmon', color='white', padding=5, border='2px solid #555') 10 | ]), 11 | Stack(horizontal=True, controls=[ 12 | Text('left center', align='left', vertical_align='center', width=100, height=100, bgcolor='PaleGoldenrod', padding=5), 13 | Text('center center', align='center', vertical_align='center', width=100, height=100, bgcolor='PaleGoldenrod', padding=5, size='large', border='1px solid #555'), 14 | Text('right center', align='right', vertical_align='center', width=100, height=100, bgcolor='PaleGoldenrod', padding=5, border='2px solid #555') 15 | ]), 16 | Stack(horizontal=True, controls=[ 17 | Text('left bottom', align='left', vertical_align='bottom', width=100, height=100, bgcolor='PaleGreen', padding=5), 18 | Text('center bottom', align='center', vertical_align='bottom', width=100, height=100, bgcolor='PaleGreen', padding=5, size='large', border='1px solid #555'), 19 | Text('right bottom', align='right', vertical_align='bottom', width=100, height=100, bgcolor='PaleGreen', padding=5, border='2px solid #555') 20 | ])) 21 | 22 | -------------------------------------------------------------------------------- /python/controls/text/text_font_styles.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text 3 | with pglet.page("text-with-different-font-styles") as page: 4 | 5 | page.add( 6 | Text('Bold', bold=True), 7 | Text('Italic', italic=True), 8 | Text('Preformatted text in monospace font', pre=True)) 9 | 10 | -------------------------------------------------------------------------------- /python/controls/text/text_markdown.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text 3 | with pglet.page("text-markdown") as page: 4 | 5 | page.add(Text(''' 6 | # Heading1 7 | 8 | ## Autolink literals 9 | 10 | www.example.com, https://example.com, and contact@example.com. 11 | 12 | ## Strikethrough 13 | 14 | ~one~ or ~~two~~ tildes. 15 | 16 | ### Code sample 17 | 18 | ``` 19 | import pglet 20 | page = page.page() 21 | ``` 22 | 23 | ## Table 24 | 25 | | a | b | c | d | 26 | | - | :- | -: | :-: | 27 | 28 | ''', markdown=True)) 29 | 30 | 31 | -------------------------------------------------------------------------------- /python/controls/text/text_rounded_corners.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Stack 3 | with pglet.page("text-rounded-corners") as page: 4 | 5 | page.add(Stack(horizontal=True, controls=[ 6 | Text('Border radius 10% of width/height', align='center', vertical_align='center', width=100, height=100, border_radius=10, bgcolor='salmon'), 7 | Text('Border radius 25% of width/height', align='center', vertical_align='center', width=100, height=100, border_radius=25, bgcolor='PaleGoldenrod', border='1px solid #555'), 8 | Text('Border radius 50% of width/height', align='center', vertical_align='center', width=100, height=100, border_radius=50, bgcolor='PaleGreen', border='2px solid #555') 9 | ]) 10 | ) 11 | 12 | 13 | -------------------------------------------------------------------------------- /python/controls/text/text_size.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text 3 | with pglet.page("text-size") as page: 4 | 5 | page.add( 6 | Text('tiny', size='tiny'), 7 | Text('xSmall', size='xSmall'), 8 | Text('small', size='small'), 9 | Text('smallPlus', size='smallPlus'), 10 | Text('medium', size='medium'), 11 | Text('mediumPlus', size='mediumPlus'), 12 | Text('large', size='large'), 13 | Text('xLarge', size='xLarge'), 14 | Text('xxLarge', size='xxLarge'), 15 | Text('superLarge', size='superLarge'), 16 | Text('mega', size='mega')) 17 | 18 | 19 | -------------------------------------------------------------------------------- /python/controls/textbox/basic_textboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox, Button, Text 3 | with pglet.page("basic-textboxes") as page: 4 | def button_clicked(e): 5 | t.value = f"Textboxes values are: '{tb1.value}', '{tb2.value}', '{tb3.value}', '{tb4.value}', '{tb5.value}'." 6 | page.update() 7 | 8 | t = Text() 9 | tb1 = Textbox(label='Standard') 10 | tb2 = Textbox(label='Disabled', disabled=True, value='First name') 11 | tb3 = Textbox(label='Read-only', read_only=True, value='Last name') 12 | tb4 = Textbox(label="With placeholder", placeholder='Please enter text here') 13 | tb5 = Textbox(label='With an icon', icon='Emoji2') 14 | b = Button(text='Submit', on_click=button_clicked) 15 | page.add(tb1, tb2, tb3, tb4, tb5, b, t) 16 | 17 | input() 18 | 19 | 20 | -------------------------------------------------------------------------------- /python/controls/textbox/multiline_textboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox 3 | with pglet.page("multiline-textboxes") as page: 4 | 5 | page.add( 6 | Textbox(label='standard', multiline=True), 7 | Textbox(label='disabled', multiline=True, disabled=True, value='line1\nline2\nline3\nline4\nline5\n'), 8 | Textbox(label='With auto adjusted height', multiline=True, auto_adjust_height=True)) 9 | 10 | 11 | -------------------------------------------------------------------------------- /python/controls/textbox/password_with_reveal_button.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox 3 | with pglet.page("password-with-reveal-button") as page: 4 | 5 | page.add(Textbox(label='Password with reveal button', password=True)) 6 | 7 | -------------------------------------------------------------------------------- /python/controls/textbox/required_textboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox, Button 3 | with pglet.page("required-textboxes-with-error-messages") as page: 4 | def button_clicked(e): 5 | if tb1.value =='': 6 | tb1.error_message = 'Field is required' 7 | else: 8 | tb1.error_message = '' 9 | if tb2.value =='': 10 | tb2.error_message = 'Field is required' 11 | else: 12 | tb2.error_message = '' 13 | page.update() 14 | 15 | b = Button(text='Validate', on_click=button_clicked) 16 | tb1 = Textbox(label='Required:', required=True) 17 | tb2 = Textbox(required=True) 18 | 19 | page.add(tb1, tb2, b) 20 | input() 21 | 22 | -------------------------------------------------------------------------------- /python/controls/textbox/suffix_prefix_textboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox 3 | with pglet.page("suffix-prefix-textboxes") as page: 4 | 5 | page.add( 6 | Textbox(label='With prefix', prefix='https://'), 7 | Textbox(label='With suffix', suffix='.com'), 8 | Textbox(label='With prefix and suffix', prefix='https://', suffix='.com')) 9 | 10 | 11 | -------------------------------------------------------------------------------- /python/controls/textbox/textbox-with-change-event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Textbox 3 | 4 | with pglet.page("textbox-with-change-event") as page: 5 | 6 | def textbox_changed(e): 7 | t.value = e.control.value 8 | page.update() 9 | 10 | t = Text() 11 | tb = Textbox( 12 | label="Textbox with 'change' event:", 13 | on_change=textbox_changed, 14 | ) 15 | 16 | page.add(tb, t) 17 | input() 18 | -------------------------------------------------------------------------------- /python/controls/textbox/textbox_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Textbox 3 | 4 | 5 | def textboxes(): 6 | return Stack( 7 | gap=20, 8 | controls=[ 9 | Text("Basic textboxes", size="xLarge"), 10 | basic_textboxes(), 11 | Text("Multiline textboxes", size="xLarge"), 12 | multiline_textboxes(), 13 | Text("Underlined and borderless Textboxes", size="xLarge"), 14 | underlined_borderless_textboxes(), 15 | Text("TextField with prefix and/or suffix", size="xLarge"), 16 | suffix_prefix_textboxes(), 17 | ], 18 | ) 19 | 20 | 21 | def basic_textboxes(): 22 | return Stack( 23 | controls=[ 24 | Stack( 25 | gap=25, 26 | horizontal=True, 27 | controls=[ 28 | Textbox(label="Standard"), 29 | Textbox(label="Disabled", disabled=True), 30 | ], 31 | ), 32 | Stack( 33 | gap=25, 34 | horizontal=True, 35 | controls=[ 36 | Textbox(label="Read-only", read_only=True), 37 | Textbox( 38 | label="With placeholder", placeholder="Please enter text here" 39 | ), 40 | ], 41 | ), 42 | Stack( 43 | gap=25, 44 | horizontal=True, 45 | controls=[ 46 | Stack( 47 | controls=[ 48 | Textbox(label="Required:", required=True), 49 | Textbox(required=True), 50 | ] 51 | ), 52 | Textbox(label="With error message", error_message="Error message"), 53 | ], 54 | ), 55 | Stack( 56 | gap=25, 57 | horizontal=True, 58 | controls=[ 59 | Textbox(label="With an icon", icon="Emoji2"), # need icon property 60 | Textbox(label="Password with reveal button", password=True), 61 | ], 62 | ), 63 | Stack(gap=25, horizontal=True, controls=[textbox_with_onchange()]), 64 | ] 65 | ) 66 | 67 | 68 | def textbox_with_onchange(): 69 | def textbox_changed(e): 70 | displayed_text.value = entered_text.value 71 | stack.update() 72 | 73 | entered_text = Textbox(label="With onchange event", on_change=textbox_changed) 74 | displayed_text = Text() 75 | stack = Stack(controls=[entered_text, displayed_text]) 76 | return stack 77 | 78 | 79 | def multiline_textboxes(): 80 | return Stack( 81 | controls=[ 82 | Stack( 83 | gap=25, 84 | horizontal=True, 85 | controls=[ 86 | Textbox(label="standard", multiline=True), 87 | Textbox(label="disabled", multiline=True, disabled=True), 88 | ], 89 | ), 90 | Stack( 91 | gap=25, 92 | horizontal=True, 93 | controls=[ 94 | Textbox( 95 | label="With auto adjusted height", 96 | multiline=True, 97 | auto_adjust_height=True, 98 | ) # need auto-adjusted height property 99 | ], 100 | ), 101 | ] 102 | ) 103 | 104 | 105 | def underlined_borderless_textboxes(): 106 | return Stack( 107 | controls=[ 108 | Stack( 109 | gap=25, 110 | controls=[ 111 | Textbox( 112 | label="Underlined", 113 | underlined=True, 114 | placeholder="Enter text here", 115 | ), 116 | Textbox( 117 | label="Borderless", 118 | borderless=True, 119 | placeholder="Enter text here", 120 | ), 121 | ], 122 | ) 123 | ] 124 | ) 125 | 126 | 127 | def suffix_prefix_textboxes(): 128 | return Stack( 129 | controls=[ 130 | Stack( 131 | gap=25, 132 | horizontal=True, 133 | controls=[ 134 | Textbox(label="With prefix", prefix="https://"), 135 | Textbox(label="With suffix", suffix=".com"), 136 | ], 137 | ), 138 | Stack( 139 | horizontal=True, 140 | controls=[ 141 | Textbox( 142 | label="With prefix and suffix", prefix="https://", suffix=".com" 143 | ) 144 | ], 145 | ), 146 | ] 147 | ) 148 | 149 | 150 | def main(page): 151 | 152 | page.title = "Textbox control samples" 153 | page.update() 154 | page.add(textboxes()) 155 | 156 | 157 | pglet.app("python-textbox", target=main) 158 | -------------------------------------------------------------------------------- /python/controls/textbox/underlined_and_borderless_textboxes.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox 3 | with pglet.page("underlined-and-borderless-textboxes") as page: 4 | 5 | page.add( 6 | Textbox(label='Underlined', underlined=True, placeholder='Enter text here'), 7 | Textbox(label='Borderless', borderless=True, placeholder='Enter text here')) 8 | 9 | 10 | -------------------------------------------------------------------------------- /python/controls/toggle/basic_toggles.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Toggle, Button, Text 3 | with pglet.page("basic-toggles") as page: 4 | def button_clicked(e): 5 | t.value = f"Toggles values are: {t1.value}, {t2.value}, {t3.value}, {t4.value}." 6 | page.update() 7 | 8 | t = Text() 9 | t1 = Toggle(label='Enabled and checked', value=True) 10 | t2 = Toggle(label='Enabled and unchecked') 11 | t3 = Toggle(disabled=True, label='Disabled and checked', value=True) 12 | t4 = Toggle(disabled=True, label='Disabled and unchecked') 13 | b = Button(text='Submit', on_click=button_clicked) 14 | page.add(t1, t2, t3, t4, b, t) 15 | 16 | input() -------------------------------------------------------------------------------- /python/controls/toggle/toggle_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Toggle 3 | 4 | 5 | def toggles(page): 6 | return Stack( 7 | controls=[ 8 | Text("Toggles", size="xLarge"), 9 | Toggle(label="Enabled and checked", value=True), 10 | Toggle(label="Enabled and unchecked"), 11 | Toggle(disabled=True, label="Disabled and checked", value=True), 12 | Toggle(disabled=True, label="Disabled and unchecked"), 13 | Toggle( 14 | inline=True, label="With inline label", on_text="On", off_text="Off" 15 | ), 16 | Toggle( 17 | disabled=True, 18 | inline=True, 19 | label="Disabled with inline label", 20 | on_text="On", 21 | off_text="Off", 22 | ), 23 | Toggle( 24 | inline=True, label="With inline label and without onText and offText" 25 | ), 26 | Toggle( 27 | disabled=True, 28 | inline=True, 29 | label="Disabled with inline label and without onText and offText", 30 | ), 31 | toggle_with_on_change(page=page), 32 | ] 33 | ) 34 | 35 | 36 | def toggle_with_on_change(page): 37 | def toggle_changed(e): 38 | if t.value: 39 | # Dark theme 40 | page.theme = "dark" 41 | else: 42 | page.theme = "light" 43 | 44 | page.update() 45 | 46 | t = Toggle( 47 | label="With Change event", 48 | on_text="Dark theme", 49 | off_text="Light theme", 50 | value=False, 51 | on_change=toggle_changed, 52 | ) 53 | return t 54 | 55 | 56 | def main(page): 57 | 58 | page.title = "Toggle control samples" 59 | page.update() 60 | page.add(toggles(page)) 61 | 62 | 63 | pglet.app("python-toggle", target=main) 64 | -------------------------------------------------------------------------------- /python/controls/toggle/toggle_with_change_event.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Toggle 3 | with pglet.page("toggle-with-change-event") as page: 4 | def toggle_changed(e): 5 | if t.value: 6 | page.theme = 'dark' 7 | else: 8 | page.theme = 'light' 9 | page.update() 10 | 11 | t = Toggle(label="With 'change' event", on_text="Dark theme", off_text="Light theme", value=False, on_change=toggle_changed) 12 | 13 | page.theme = 'light' 14 | page.add(t) 15 | 16 | input() -------------------------------------------------------------------------------- /python/controls/toggle/toggles_with_inline_labels.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Toggle 3 | 4 | with pglet.page("toggles-with-inline-labels") as page: 5 | 6 | page.add( 7 | Toggle(inline=True, label="With inline label", on_text="On", off_text="Off"), 8 | Toggle( 9 | disabled=True, 10 | inline=True, 11 | label="Disabled with inline label", 12 | on_text="On", 13 | off_text="Off", 14 | ), 15 | Toggle(inline=True, label="With inline label and without onText and offText"), 16 | Toggle( 17 | disabled=True, 18 | inline=True, 19 | label="Disabled with inline label and without onText and offText", 20 | ), 21 | ) 22 | -------------------------------------------------------------------------------- /python/controls/toolbar_control.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Text, Toolbar, Message 3 | from pglet import toolbar 4 | 5 | 6 | def toolbars(page): 7 | def item_clicked(e): 8 | page.controls.insert( 9 | 0, Message(value=f'Menu item "{e.control.text}" was clicked', dismiss=True) 10 | ) 11 | page.update() 12 | 13 | standard_toolbar = Toolbar( 14 | items=[ 15 | toolbar.Item( 16 | text="New", 17 | icon="Add", 18 | items=[ 19 | toolbar.Item( 20 | text="Email message", icon="Mail", on_click=item_clicked 21 | ), 22 | toolbar.Item( 23 | text="Calendar event", icon="Calendar", on_click=item_clicked 24 | ), 25 | ], 26 | ), 27 | toolbar.Item( 28 | text="Share", 29 | icon="Share", 30 | split=True, 31 | items=[ 32 | toolbar.Item(text="Share to Twitter", on_click=item_clicked), 33 | toolbar.Item(text="Share to Facebook", on_click=item_clicked), 34 | toolbar.Item( 35 | text="Share to Somewhere", disabled=True, on_click=item_clicked 36 | ), 37 | toolbar.Item( 38 | text="Share to Email", 39 | data="sharetoemail", 40 | items=[ 41 | toolbar.Item( 42 | text="Share to Outlook", on_click=item_clicked 43 | ), 44 | toolbar.Item(text="Share to Gmail", on_click=item_clicked), 45 | ], 46 | ), 47 | ], 48 | ), 49 | toolbar.Item( 50 | text="To to Google", 51 | icon="Globe", 52 | url="https://google.com", 53 | new_window=True, 54 | secondary_text="New window", 55 | ), 56 | ], 57 | overflow=[ 58 | toolbar.Item(text="Item 1", icon="Shop", on_click=item_clicked), 59 | toolbar.Item(text="Item 2", icon="Airplane", on_click=item_clicked), 60 | ], 61 | far=[ 62 | toolbar.Item( 63 | text="Grid view", icon="Tiles", icon_only=True, on_click=item_clicked 64 | ), 65 | toolbar.Item( 66 | text="Info", 67 | icon="Info", 68 | icon_color="green", 69 | icon_only=True, 70 | on_click=item_clicked, 71 | ), 72 | ], 73 | ) 74 | 75 | inverted_toolbar = Toolbar( 76 | inverted=True, 77 | items=[ 78 | toolbar.Item( 79 | text="New", 80 | icon="Add", 81 | items=[ 82 | toolbar.Item(text="Email message", icon="Mail"), 83 | toolbar.Item(text="Calendar event", icon="Calendar"), 84 | ], 85 | ), 86 | toolbar.Item( 87 | text="Share", 88 | icon="Share", 89 | split=True, 90 | items=[ 91 | toolbar.Item(text="Share to Twitter"), 92 | toolbar.Item(text="Share to Facebook"), 93 | toolbar.Item(text="Share to Somewhere", disabled=True), 94 | toolbar.Item( 95 | text="Share to Email", 96 | data="sharetoemail", 97 | items=[ 98 | toolbar.Item(text="Share to Outlook"), 99 | toolbar.Item(text="Share to Gmail"), 100 | ], 101 | ), 102 | ], 103 | ), 104 | toolbar.Item( 105 | text="To to Google", 106 | icon="Globe", 107 | url="https://google.com", 108 | new_window=True, 109 | secondary_text="New window", 110 | ), 111 | ], 112 | overflow=[ 113 | toolbar.Item(text="Item 1", icon="Shop"), 114 | toolbar.Item(text="Item 2", icon="Airplane"), 115 | ], 116 | far=[ 117 | toolbar.Item(text="Grid view", icon="Tiles", icon_only=True), 118 | toolbar.Item(text="Info", icon="Info", icon_color="green", icon_only=True), 119 | ], 120 | ) 121 | 122 | return Stack( 123 | gap=30, 124 | controls=[ 125 | Stack( 126 | controls=[ 127 | Text("Standard toolbar with Click events", size="xLarge"), 128 | standard_toolbar, 129 | ] 130 | ), 131 | Stack( 132 | controls=[ 133 | Text("Inverted toolbar (for top application menu)", size="xLarge"), 134 | Stack(bgcolor="magentaLight", controls=[inverted_toolbar]), 135 | ] 136 | ), 137 | ], 138 | ) 139 | 140 | 141 | def main(page): 142 | 143 | page.title = "Toolbar control samples" 144 | page.horizontal_align = "stretch" 145 | page.update() 146 | page.add(toolbars(page)) 147 | 148 | 149 | pglet.app("python-toolbar", target=main) 150 | -------------------------------------------------------------------------------- /python/controls/vertical_barchart_control.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | import pglet 5 | from pglet import Text, VerticalBarChart 6 | from pglet.verticalbarchart import Point 7 | 8 | 9 | def main(page): 10 | 11 | # Vertical chart with textual x axis 12 | red_point = Point( 13 | x="Red", y=20, color="MediumOrchid", legend="Red", y_tooltip="20%" 14 | ) 15 | simple_chart = VerticalBarChart( 16 | tooltips=True, 17 | legend=True, 18 | width="50%", 19 | height=300, 20 | y_ticks=5, 21 | bar_width=20, 22 | y_format="{y}%", 23 | points=[ 24 | red_point, 25 | Point(x="Green", y=50, color="LimeGreen", legend="Green", y_tooltip="50%"), 26 | Point(x="Blue", y=30, color="LightSkyBlue", legend="Blue", y_tooltip="30%"), 27 | ], 28 | ) 29 | 30 | # Vertical chart with numeric x axis 31 | num_chart = VerticalBarChart( 32 | y_ticks=5, 33 | y_min=0, 34 | y_max=100, 35 | y_format="{y}%", 36 | width="100%", 37 | height=400, 38 | bar_width=10, 39 | ) 40 | 41 | page.add( 42 | Text("Vertical chart with textual x axis", size="xLarge"), 43 | simple_chart, 44 | Text("Vertical chart with numeric x axis", size="xLarge"), 45 | num_chart, 46 | ) 47 | 48 | for v in range(21, 40): 49 | red_point.y = v 50 | page.update() 51 | time.sleep(0.01) 52 | 53 | for i in range(0, 100): 54 | num_chart.points.append(Point(x=i, y=round(random.random() * 100))) 55 | if len(num_chart.points) > 30: 56 | num_chart.points.pop(0) 57 | page.update() 58 | time.sleep(0.05) 59 | 60 | 61 | pglet.app("python-verticalbarchart", target=main) 62 | -------------------------------------------------------------------------------- /python/greeter/greeter.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Textbox, Button, Text 3 | 4 | 5 | def main(page): 6 | def btn_click(e): 7 | name = txt_name.value 8 | page.clean() 9 | page.add(Text(f"Hello, {name}!")) 10 | 11 | txt_name = Textbox("Your name") 12 | 13 | page.add(txt_name, Button("Say hello!", on_click=btn_click)) 14 | 15 | 16 | pglet.app(target=main) 17 | -------------------------------------------------------------------------------- /python/hello-world/hello-app.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text 3 | 4 | 5 | def main(page): 6 | page.title = "Hello!" 7 | page.add(Text(f"Hello to session {page.session_id}!")) 8 | 9 | 10 | pglet.app(target=main, web=False) 11 | -------------------------------------------------------------------------------- /python/hello-world/hello.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text 3 | 4 | page = pglet.page(web=True) 5 | page.title = "Hello, world!" 6 | page.add(Text("Hello, world!")) 7 | -------------------------------------------------------------------------------- /python/icon-browser/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pglet 3 | from pglet import Text, Stack, SearchBox, Icon 4 | 5 | 6 | def main(page): 7 | icon_names = load_icon_names() 8 | page.title = "Icon Browser" 9 | page.horizontalAlign = "stretch" 10 | page.update() 11 | 12 | def search_icons(search_name): 13 | found_icon_names = [] 14 | if search_name == None: 15 | found_icon_names = icon_names 16 | else: 17 | for icon_name in icon_names: 18 | if search_name.lower() in icon_name.lower(): 19 | found_icon_names.append(icon_name) 20 | return found_icon_names 21 | 22 | def enter_clicked(e): 23 | icons = get_icons(search_box.value) 24 | search_result.controls.clear() 25 | search_result.controls.extend(icons) 26 | page.update() 27 | 28 | # add stack controls each with Icon and Text 29 | def get_icons(search_name): 30 | icons = [] 31 | found_icon_names = search_icons(search_name) 32 | for icon_name in found_icon_names: 33 | s = Stack( 34 | horizontal_align="center", 35 | vertical_align="center", 36 | width=100, 37 | height=100, 38 | border="solid 1px #eee", 39 | border_radius="3", 40 | controls=[ 41 | Icon(name=icon_name, size="40", color="#555"), 42 | Text(value=icon_name, size="small"), 43 | ], 44 | ) 45 | icons.append(s) 46 | return icons 47 | 48 | icons = get_icons(None) 49 | 50 | search_result = Stack(horizontal=True, wrap=True, controls=icons) 51 | search_box = SearchBox( 52 | id="searchbox", 53 | width="100%", 54 | placeholder="Search icons", 55 | on_search=enter_clicked, 56 | ) 57 | page.add(search_box, search_result) 58 | 59 | 60 | # load list of icon names from file 61 | def load_icon_names(): 62 | dir_path = os.path.dirname(os.path.realpath(__file__)) 63 | file_path = os.path.join(dir_path, "fluent-icons.txt") 64 | input_file = open(file_path, "r") 65 | icon_names = [] 66 | for line in input_file: 67 | line = line.strip() 68 | icon_names.append(line) 69 | input_file.close() 70 | return icon_names 71 | 72 | 73 | pglet.app("index", target=main) 74 | -------------------------------------------------------------------------------- /python/todo/README.md: -------------------------------------------------------------------------------- 1 | # Todo app in Python using Pglet 2 | 3 | This directory contains ToDo app for [Python tutorial](https://pglet.io/docs/tutorials/python). 4 | 5 | The app requires Python 3.7+ with `pglet` module installed: 6 | 7 | pip install pglet 8 | 9 | To run the complete app: 10 | 11 | python todo-complete.py -------------------------------------------------------------------------------- /python/todo/todo-app-class.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Textbox, Button, Checkbox 3 | 4 | 5 | class TodoApp: 6 | def __init__(self): 7 | self.new_task = Textbox(placeholder="Whats needs to be done?", width="100%") 8 | self.tasks_view = Stack() 9 | 10 | # application's root control (i.e. "view") containing all other controls 11 | self.view = Stack( 12 | width="70%", 13 | controls=[ 14 | Stack( 15 | horizontal=True, 16 | on_submit=self.add_clicked, 17 | controls=[self.new_task, Button("Add", on_click=self.add_clicked)], 18 | ), 19 | self.tasks_view, 20 | ], 21 | ) 22 | 23 | def add_clicked(self, e): 24 | self.tasks_view.controls.append(Checkbox(label=self.new_task.value)) 25 | self.tasks_view.update() 26 | 27 | 28 | def main(page): 29 | page.title = "ToDo App" 30 | page.horizontal_align = "center" 31 | page.update() 32 | 33 | # create application instance 34 | app = TodoApp() 35 | 36 | # add application's root control to the page 37 | page.add(app.view) 38 | 39 | 40 | pglet.app("todo-app", target=main) 41 | -------------------------------------------------------------------------------- /python/todo/todo-complete.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Stack, Textbox, Button, Checkbox, Tabs, Tab 3 | 4 | 5 | class Task: 6 | def __init__(self, app, name): 7 | self.app = app 8 | self.display_task = Checkbox( 9 | value=False, label=name, on_change=self.status_changed 10 | ) 11 | self.edit_name = Textbox(width="100%") 12 | self.display_view = Stack( 13 | horizontal=True, 14 | horizontal_align="space-between", 15 | vertical_align="center", 16 | controls=[ 17 | self.display_task, 18 | Stack( 19 | horizontal=True, 20 | gap="0", 21 | controls=[ 22 | Button( 23 | icon="Edit", title="Edit todo", on_click=self.edit_clicked 24 | ), 25 | Button( 26 | icon="Delete", 27 | title="Delete todo", 28 | on_click=self.delete_clicked, 29 | ), 30 | ], 31 | ), 32 | ], 33 | ) 34 | self.edit_view = Stack( 35 | visible=False, 36 | horizontal=True, 37 | horizontal_align="space-between", 38 | vertical_align="center", 39 | controls=[self.edit_name, Button(text="Save", on_click=self.save_clicked)], 40 | ) 41 | self.view = Stack(controls=[self.display_view, self.edit_view]) 42 | 43 | def edit_clicked(self, e): 44 | self.edit_name.value = self.display_task.label 45 | self.display_view.visible = False 46 | self.edit_view.visible = True 47 | self.view.update() 48 | 49 | def save_clicked(self, e): 50 | self.display_task.label = self.edit_name.value 51 | self.display_view.visible = True 52 | self.edit_view.visible = False 53 | self.view.update() 54 | 55 | def delete_clicked(self, e): 56 | self.app.delete_task(self) 57 | 58 | def status_changed(self, e): 59 | self.app.update() 60 | 61 | 62 | class TodoApp: 63 | def __init__(self): 64 | self.tasks = [] 65 | self.new_task = Textbox(placeholder="Whats needs to be done?", width="100%") 66 | self.tasks_view = Stack() 67 | self.filter = Tabs( 68 | value="all", 69 | on_change=self.tabs_changed, 70 | tabs=[Tab(text="all"), Tab(text="active"), Tab(text="completed")], 71 | ) 72 | self.items_left = Text("0 items left") 73 | self.view = Stack( 74 | width="70%", 75 | controls=[ 76 | Text(value="Todos", size="large", align="center"), 77 | Stack( 78 | horizontal=True, 79 | on_submit=self.add_clicked, 80 | controls=[ 81 | self.new_task, 82 | Button(primary=True, text="Add", on_click=self.add_clicked), 83 | ], 84 | ), 85 | Stack( 86 | gap=25, 87 | controls=[ 88 | self.filter, 89 | self.tasks_view, 90 | Stack( 91 | horizontal=True, 92 | horizontal_align="space-between", 93 | vertical_align="center", 94 | controls=[ 95 | self.items_left, 96 | Button( 97 | text="Clear completed", on_click=self.clear_clicked 98 | ), 99 | ], 100 | ), 101 | ], 102 | ), 103 | ], 104 | ) 105 | 106 | def update(self): 107 | status = self.filter.value 108 | count = 0 109 | for task in self.tasks: 110 | task.view.visible = ( 111 | status == "all" 112 | or (status == "active" and task.display_task.value == False) 113 | or (status == "completed" and task.display_task.value) 114 | ) 115 | if task.display_task.value == False: 116 | count += 1 117 | self.items_left.value = f"{count} active item(s) left" 118 | self.view.update() 119 | 120 | def add_clicked(self, e): 121 | task = Task(self, self.new_task.value) 122 | self.tasks.append(task) 123 | self.tasks_view.controls.append(task.view) 124 | self.new_task.value = "" 125 | self.update() 126 | 127 | def delete_task(self, task): 128 | self.tasks.remove(task) 129 | self.tasks_view.controls.remove(task.view) 130 | self.update() 131 | 132 | def tabs_changed(self, e): 133 | self.update() 134 | 135 | def clear_clicked(self, e): 136 | for task in self.tasks[:]: 137 | if task.display_task.value == True: 138 | self.delete_task(task) 139 | 140 | 141 | def main(page): 142 | page.title = "ToDo App" 143 | page.horizontal_align = "center" 144 | page.update() 145 | app = TodoApp() 146 | page.add(app.view) 147 | 148 | 149 | pglet.app("todo-app", target=main) 150 | -------------------------------------------------------------------------------- /python/todo/todo-with-delete.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Stack, Textbox, Button, Checkbox 3 | 4 | 5 | class Task: 6 | def __init__(self, app, name): 7 | self.app = app 8 | self.display_task = Checkbox(value=False, label=name) 9 | self.edit_name = Textbox(width="100%") 10 | 11 | self.display_view = Stack( 12 | horizontal=True, 13 | horizontal_align="space-between", 14 | vertical_align="center", 15 | controls=[ 16 | self.display_task, 17 | Stack( 18 | horizontal=True, 19 | gap="0", 20 | controls=[ 21 | Button( 22 | icon="Edit", title="Edit todo", on_click=self.edit_clicked 23 | ), 24 | Button( 25 | icon="Delete", 26 | title="Delete todo", 27 | on_click=self.delete_clicked, 28 | ), 29 | ], 30 | ), 31 | ], 32 | ) 33 | 34 | self.edit_view = Stack( 35 | visible=False, 36 | horizontal=True, 37 | horizontal_align="space-between", 38 | vertical_align="center", 39 | controls=[self.edit_name, Button(text="Save", on_click=self.save_clicked)], 40 | ) 41 | self.view = Stack(controls=[self.display_view, self.edit_view]) 42 | 43 | def edit_clicked(self, e): 44 | self.edit_name.value = self.display_task.label 45 | self.display_view.visible = False 46 | self.edit_view.visible = True 47 | self.view.update() 48 | 49 | def save_clicked(self, e): 50 | self.display_task.label = self.edit_name.value 51 | self.display_view.visible = True 52 | self.edit_view.visible = False 53 | self.view.update() 54 | 55 | def delete_clicked(self, e): 56 | self.app.delete_task(self) 57 | 58 | 59 | class TodoApp: 60 | def __init__(self): 61 | self.tasks = [] 62 | self.new_task = Textbox(placeholder="Whats needs to be done?", width="100%") 63 | self.tasks_view = Stack() 64 | 65 | # application's root control (i.e. "view") containing all other controls 66 | self.view = Stack( 67 | width="70%", 68 | controls=[ 69 | Stack( 70 | horizontal=True, 71 | on_submit=self.add_clicked, 72 | controls=[self.new_task, Button("Add", on_click=self.add_clicked)], 73 | ), 74 | self.tasks_view, 75 | ], 76 | ) 77 | 78 | def add_clicked(self, e): 79 | task = Task(self, self.new_task.value) 80 | self.tasks.append(task) 81 | self.tasks_view.controls.append(task.view) 82 | self.new_task.value = "" 83 | self.view.update() 84 | 85 | def delete_task(self, task): 86 | self.tasks.remove(task) 87 | self.tasks_view.controls.remove(task.view) 88 | self.view.update() 89 | 90 | 91 | def main(page): 92 | page.title = "ToDo App" 93 | page.horizontal_align = "center" 94 | page.update() 95 | 96 | # create application instance 97 | app = TodoApp() 98 | 99 | # add application's root control to the page 100 | page.add(app.view) 101 | 102 | 103 | pglet.app("todo-app", target=main) 104 | -------------------------------------------------------------------------------- /python/todo/todo-with-filter.py: -------------------------------------------------------------------------------- 1 | import pglet 2 | from pglet import Text, Stack, Textbox, Button, Checkbox, Tabs, Tab 3 | 4 | 5 | class Task: 6 | def __init__(self, app, name): 7 | self.app = app 8 | self.display_task = Checkbox( 9 | value=False, label=name, on_change=self.status_changed 10 | ) 11 | self.edit_name = Textbox(width="100%") 12 | 13 | self.display_view = Stack( 14 | horizontal=True, 15 | horizontal_align="space-between", 16 | vertical_align="center", 17 | controls=[ 18 | self.display_task, 19 | Stack( 20 | horizontal=True, 21 | gap="0", 22 | controls=[ 23 | Button( 24 | icon="Edit", title="Edit todo", on_click=self.edit_clicked 25 | ), 26 | Button( 27 | icon="Delete", 28 | title="Delete todo", 29 | on_click=self.delete_clicked, 30 | ), 31 | ], 32 | ), 33 | ], 34 | ) 35 | 36 | self.edit_view = Stack( 37 | visible=False, 38 | horizontal=True, 39 | horizontal_align="space-between", 40 | vertical_align="center", 41 | controls=[self.edit_name, Button(text="Save", on_click=self.save_clicked)], 42 | ) 43 | self.view = Stack(controls=[self.display_view, self.edit_view]) 44 | 45 | def edit_clicked(self, e): 46 | self.edit_name.value = self.display_task.label 47 | self.display_view.visible = False 48 | self.edit_view.visible = True 49 | self.view.update() 50 | 51 | def save_clicked(self, e): 52 | self.display_task.label = self.edit_name.value 53 | self.display_view.visible = True 54 | self.edit_view.visible = False 55 | self.view.update() 56 | 57 | def delete_clicked(self, e): 58 | self.app.delete_task(self) 59 | 60 | def status_changed(self, e): 61 | self.app.update() 62 | 63 | 64 | class TodoApp: 65 | def __init__(self): 66 | self.tasks = [] 67 | self.new_task = Textbox(placeholder="Whats needs to be done?", width="100%") 68 | self.tasks_view = Stack() 69 | 70 | self.filter = Tabs( 71 | value="all", 72 | on_change=self.tabs_changed, 73 | tabs=[Tab(text="all"), Tab(text="active"), Tab(text="completed")], 74 | ) 75 | 76 | self.view = Stack( 77 | width="70%", 78 | controls=[ 79 | Text(value="Todos", size="large", align="center"), 80 | Stack( 81 | horizontal=True, 82 | on_submit=self.add_clicked, 83 | controls=[ 84 | self.new_task, 85 | Button(primary=True, text="Add", on_click=self.add_clicked), 86 | ], 87 | ), 88 | Stack(gap=25, controls=[self.filter, self.tasks_view]), 89 | ], 90 | ) 91 | 92 | def update(self): 93 | status = self.filter.value 94 | for task in self.tasks: 95 | task.view.visible = ( 96 | status == "all" 97 | or (status == "active" and task.display_task.value == False) 98 | or (status == "completed" and task.display_task.value) 99 | ) 100 | self.view.update() 101 | 102 | def add_clicked(self, e): 103 | task = Task(self, self.new_task.value) 104 | self.tasks.append(task) 105 | self.tasks_view.controls.append(task.view) 106 | self.new_task.value = "" 107 | self.update() 108 | 109 | def delete_task(self, task): 110 | self.tasks.remove(task) 111 | self.tasks_view.controls.remove(task.view) 112 | self.update() 113 | 114 | def tabs_changed(self, e): 115 | self.update() 116 | 117 | 118 | def main(page): 119 | page.title = "ToDo App" 120 | page.horizontal_align = "center" 121 | page.update() 122 | 123 | # create application instance 124 | app = TodoApp() 125 | 126 | # add application's root control to the page 127 | page.add(app.view) 128 | 129 | 130 | pglet.app("todo-app", target=main) 131 | -------------------------------------------------------------------------------- /python/wordle/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pglet 3 | from pglet import Text, Stack, SearchBox, Icon 4 | 5 | 6 | def main(page): 7 | icon_names = load_icon_names() 8 | page.title = "Icon Browser" 9 | page.horizontalAlign = "stretch" 10 | page.update() 11 | 12 | def search_icons(search_name): 13 | found_icon_names = [] 14 | if search_name == None: 15 | found_icon_names = icon_names 16 | else: 17 | for icon_name in icon_names: 18 | if search_name.lower() in icon_name.lower(): 19 | found_icon_names.append(icon_name) 20 | return found_icon_names 21 | 22 | def enter_clicked(e): 23 | icons = get_icons(search_box.value) 24 | search_result.controls.clear() 25 | search_result.controls.extend(icons) 26 | page.update() 27 | 28 | # add stack controls each with Icon and Text 29 | def get_icons(search_name): 30 | icons = [] 31 | found_icon_names = search_icons(search_name) 32 | for icon_name in found_icon_names: 33 | s = Stack( 34 | horizontal_align="center", 35 | vertical_align="center", 36 | width=100, 37 | height=100, 38 | border="solid 1px #eee", 39 | border_radius="3", 40 | controls=[ 41 | Icon(name=icon_name, size="40", color="#555"), 42 | Text(value=icon_name, size="small"), 43 | ], 44 | ) 45 | icons.append(s) 46 | return icons 47 | 48 | icons = get_icons(None) 49 | 50 | search_result = Stack(horizontal=True, wrap=True, controls=icons) 51 | search_box = SearchBox( 52 | id="searchbox", 53 | width="100%", 54 | placeholder="Search icons", 55 | on_search=enter_clicked, 56 | ) 57 | page.add(search_box, search_result) 58 | 59 | 60 | # load list of icon names from file 61 | def load_icon_names(): 62 | dir_path = os.path.dirname(os.path.realpath(__file__)) 63 | file_path = os.path.join(dir_path, "fluent-icons.txt") 64 | input_file = open(file_path, "r") 65 | icon_names = [] 66 | for line in input_file: 67 | line = line.strip() 68 | icon_names.append(line) 69 | input_file.close() 70 | return icon_names 71 | 72 | 73 | pglet.app("index", target=main) 74 | --------------------------------------------------------------------------------