ptk: Parenthesized tk
Author: Pascal Raymond
Keywords: tcltk, gui
Date: 2020-04-01

# ptk overview

Ptk (parenthesized tk) is a library to ease the programming of tcltk-based gui’s. The main goal is to provide a progamming style that reflects the logical layout of the the gui, and hides/abstracts the technical details. - avoid the manipulation widget paths; - write things once; in particular creation and packing are not two different features.

Concretely, a gui consists in a recursive structure of horizontal and vertical frames containing basic widgets (leaves).

## Containers

Each container has a kind that determines how nested items will be displayed and managed. Containers are created and finalized using `begin` and `end`. Every ptk items appearing within `begin` and `end` belongs to the container.

    ptk::begin kind ?params? ?opts?
        ....
    ptk::end ?kind?

- `kind` is the type of container; basic kinds are `main` (top-level), `line`, `col` etc.
- `params` is the list mandatory parameters (passed by position); their number and types depend on `kind`
- `opts` is a list of classical tk options `-key value`; valid options depends on `kind`.
- `kind` is optional for command `end`, but recommended to tract nesting errors.

## Leaves

Each leaf has a kind that determines its layout and behavior. Ptk inherits classical tk widgets (`label`, `button`, `checkbutton` etc.), and provides some other meta-widgets (`combobox`, `select_file`, etc.). Leaves are created by the `add` command, whose arguments are similar to those of `begin`:

    ptk::add kind ?params? ?opts?

## Hello world

    package require Ptk
    namespace import ptk::*

    begin main "My program"
        begin line
            button -text "push me" -command {puts "Hello world!"}
        end line
    end main

## Customization and components

Ptk items are made of tk-widget that can be customized using `-key values` options. Each item has a main component, and possibly some others. When creating an item (with `add` or `begin`) options are directly passed to this main component. It is also possible to pass options just after the creation using the `configure` command. Note that this command is necessary to customize other component than the main one.

    ptk::configure ?component? ?opts?

- `configure` applies implicitly to the last created item, and then must follow a `add` or `begin` command.
- `component` identifies the widget to customize inside the current item; valid components depend on item `kind`; if omitted, configure applies to the main component.

Note: it is possible to customize distant items (not the last created one) using the advanced store and reuse feature.

# Basic items

## Basic leaves

Basic leaves are just wrappers around basic tk widgets, and inherit their options:

    ptk::label ?label-opts?
    ptk::button ?buttons-opts?
    ptk::checkbutton ?checkbutton-opts?
    ptk::radiobutton ?radiobutton-opts?
    ptk::scale ?scale-opts?
    ptk::entry ?entry-opts?

Customization can be performed after `add`; valid options are the same than for `add`.

    ptk::configure ?opts?

## Packers

### Line/column layout

Basic containers are packers. They allow to organize the layout as a structure of nested horizontal and vertical frames.

- horizontal packers: sons are inserted from left to right; basic ones are `line` and `hbar`.
- vertical packers: sons are inserted from top to bottom; basic ones `col` and `vbar`.

Each container has a predefined packing policy that defines how the container behaves within its own container, and how it handles its content:

- `line` and `col` expand in both direction within their container, and expand their content if both direction too.
- `hbar` and `vbar` expand in one direction only (resp. x and y), and does not expand their content but stack them side by side (resp. left to right, top to bottom).

### Example:

Here is a typical layout with a top `hbar` (e.g., for filling with menu entries), a left `vbar` (e.g. tool bar), and a central expandable zone to put the rest.

    begin main "My program"
        begin hbar -text "Menu bar"
            .....
        end hbar
        begin line
            begin vbar -text "Tool bar"
                .....
            end vbar
            begin col -relief sunken
                .....
            end col
        end line
    end main

### Packers summary:

    ptk::begin col|line|vbar|hbar ?opts?
    ...
    ptk::end ?col|line|vbar|hbar?

- packers have no mandatory parameters
- valid options are any valid tk frame or labelframe options:
  - if `-text <string>` is specified, the packer is interpreted as a labelframe
  - otherwise as a simple frame

Customization can be performed after `begin`, valid options are tk-frame options.

    ptk::configure ?opts?

### Packing customization

Do not mix up with widget customization. The `packreq` command passes specific packing request from a item to its contained.

    ptk::packreq ?pack-opts?

- `pack-opts` are packing option (cf. tk command `pack configure`)
- useful in particular to bypass the default packing policy, e.g. `-expand 1` inside a `vbar/hbar` or `-expand 0` inside a `line/col`
- useful options are:
  - `-anchor anchor`
  - `-expand boolean`
  - `-fill style`
  - `-ipadx amount`
  - `-ipady amount`
  - `-padx amount`
  - `-pady amount`
- NEVER USE OTHER OPTIONS since they interfere with ptk algorithm and will lead to undefined behaviors.

### Conditional display

TODO showif

# Meta-containers

## Switch and toggle

`switch` displays exactly one from its n sons one according to the value of an enumerate variable.

    ptk::begin switch var values ?opts?
        <son 1>
        ...
        <son n>
    ptk::end ?switch?

- `values` is a list of n string values (v1 … vn)
- `var` is a variable taking its value in `values`
- must contain exactly n sons, the ith son is displayed iff `var` holds value vi
- valid `opts` are tk-frame options

`toggle` is basically a switch commanded by a Boolean variable.

    ptk::add toggle var ?opts?
        <son 1>
        <son 0>
    ptk::add ?toggle?

- `var` is a variable containing Boolean values
- must contain exactly 2 sons, first son is displayed is `var` is true, second son if `var` is false.
- valid `opts` are tk-frame options

Customization: can be performed after begin:

    ptk::configure ?opts?

## Popup

`popup` displays a button which, when pressed opens a toplevel (independent) window displaying its content plus a predefined dissmis button.

    ptk::begin popup title ?opts?
    ptk::end ?popup?

- `title` is the name of the opened window; and the default text of the popup button.
- `opts` are tk-button options, in particular one can use `-text` to change button label.

Customization: `popup` has two configurable tk components, `button` (main one) and `frame` (main frame of the popup window):

    ptk::configure ?button-opts?
    ptk::configure button ?button-opts?
    ptk::configure frame ?frame-opts?

# Meta-leaves

## Show var

{kind outer params components} {showvar packer {var} {labelframe label}}

## Combobox

wrapper for Bryan Oakley’s combobox opts -> passed to combobox

{kind outer params components} {combobox packer {title var values} {combobox}}

# Store and reuse

## Principle

store

## Reopen container

reopen reclose

## Reconfigure

reconfigure

# Appendix: Combobox (Bryan Oakley)

This section is extracted from Bryan Oakley’s Combobox manual.

Combobox options