adding-new-widgets

Adding New Widgets

Adding new widgets isn't difficult, but it does involve making changes in several places. This doc records the steps you'll need to take.

Fork the Terminal-Widgets Repo

Fork the repo to your own GitHub user account, and clone the fork to your local workspace.

Pick a Class Name

If your new widget will be part of a group of similar widgets, such as the form input widgets, your new class should be in that namespace, and not include the namespace in the shortname. In other words, prefer Terminal::Widgets::Input::Button over Terminal::Widgets::ButtonInput.

Choose a class name that seems to match the general pattern of existing widget class names and is unlikely to be confusing to readers.

Create a Feature Branch

Use git checkout -b <new-branch-name> to make sure you're not working in main. A decent default branch name pattern is <github username>-add-<namespaced new widget name>; for example, japhb-add-input-button.

Create the Widget Class

It's usually easiest to start by copying an existing similar widget's class module and making the necessary changes from there. Don't forget to change any use, does, or is lines as appropriate. You must inherit from Terminal::Widgets::Widget but you can do so via one of its subclasses or subroles, such as Terminal::Widgets::TopLevel or Terminal::Widgets::Input.

You'll need to provide multi method handle-event() implementations at least for KeyboardEvent and MouseEvent; see existing examples for ideas, or just leave them empty for now if you prefer to do TDD (Test-Driven Development).

Don't forget to git add the new class module so that tools that key off the Git index will notice it. You don't need to actually git commit yet, this is just making sure there's an index entry at all.

Add the New Module to t/00-use.rakutest

Add a line to use the new module in the appropriate order in t/00-use.rakutest; in particular, make sure that all its dependencies are earlier in the test file, and any modules likely to make use of it are later. If it has default exports (most widget modules won't), make sure to use Empty for the import list.

Run mi6 test to check for loading errors and to make sure the new module is added to META6.json.

Update a Layout Node

Add a (probably trivial) subclass to lib/Terminal/Widgets/Layout.rakumod that will perform layout for the new widget, assigning it an appropriate superclass, such as Leaf (for widgets that cannot have children) or Node (for widgets that can).

Also add a convenience method to the Builder class in that same file to make it easy to add that layout node to a widget layout tree.

Add a StandardWidgetBuilder Case

Add a case in the Terminal::Widgets::StandardWidgetBuilder class that will handle building your new widget type given the computed layout information. Don't forget that you will need to add your new widget class to the list of use statements at the top of the file.

Re-run mi6 test at this point to make sure your additions to Layout and StandardWidgetBuilder compile.

Add Example(s)

Add example scripts to the examples/ directory, or modify existing ones to use your new widget as appropriate. For example, if you create a new form input widget, you may want to add it to examples/form.raku to demonstrate its usage. This also gives you an opportunity to make sure its behavior makes sense in context.

Add Tests (if you haven't already)

If you haven't been developing the new widget using TDD, now's the time to write tests for it, and iterate on fixing bugs until the tests are once again clean. Make sure to test error handling as well.

Commit

With all tests passing and examples working, you can now commit your new widget and all the associated changes. Don't forget that you may need to add any new changes to the class module since you first did git add above, otherwise you will commit the original out-of-date version.

Please use a clear title and description for your commit, because it will show up in your pull request.

Send a Pull Request

Push your commit to your fork using git push -u origin <the-branch-name>; the commit response from GitHub will include a URL that you can browse to create the PR to include your new widget in Terminal-Widgets. Once you've created the PR, a message will be sent to the maintainer (currently japhb) to review.

Thank you! :-)

Terminal::Widgets v0.0.1

Basic TUI Widgets

Authors

  • Geoffrey Broadwell

License

Artistic-2.0

Dependencies

Terminal::LineEditor:auth<zef:japhb>:ver<0.0.13>Terminal::Print:auth<zef:terminal-printers>:ver<0.973>

Test Dependencies

Provides

  • Terminal::Widgets
  • Terminal::Widgets::App
  • Terminal::Widgets::Events
  • Terminal::Widgets::Form
  • Terminal::Widgets::Input
  • Terminal::Widgets::Input::Boolean
  • Terminal::Widgets::Input::Button
  • Terminal::Widgets::Input::Checkbox
  • Terminal::Widgets::Input::Labeled
  • Terminal::Widgets::Input::RadioButton
  • Terminal::Widgets::Input::Text
  • Terminal::Widgets::Layout
  • Terminal::Widgets::Layout::BoxModel
  • Terminal::Widgets::Simple
  • Terminal::Widgets::Simple::TopLevel
  • Terminal::Widgets::StandardWidgetBuilder
  • Terminal::Widgets::Terminal
  • Terminal::Widgets::TopLevel
  • Terminal::Widgets::Utils
  • Terminal::Widgets::Viewer::Log
  • Terminal::Widgets::Widget

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.