Harbour

class Harbour(initialContent: Node? = null) : Region

Allows Docks to be placed at the sides of a scene. A typical application places the Harbour in the center of a BorderPane, with a MenuBar and ToolBars at the top.

The content of the Harbour is the main area of your application.

A Harbour has four sides (top,right,bottom,left), where Docks can be placed. Each side is split into two independent groups primary and secondary. At most one Dock in each group is visible at a time. Therefore, each side can show 0, 1 or 2 Docks.

The design shamelessly mimics the docks in JetBrain's IntelliJ IDE.

Structure

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Primary Top Buttons           Secondary Top Buttons ┃
┠───┬────────────────────────────┰────────────────┬───┨
┃ P │ Primary Top Dock           ║ Secondary      │ P ┃
┃   │                            ║ Top Dock       │   ┃
┃   │                            ║                │   ┃
┃   │                            ║                │   ┃
┃   ┝═══════╤════════════════════╧═════╤══════════┥   ┃
┃   │ Pri.  ║ `content`                ║ Pri.     │   ┃
┃   │ Left  ║                          ║ Right    │   ┃
┃   │ Dock  ║ Your applications        ║ Dock     │   ┃
┃   │       ║ main content.            ║          │   ┃
┃   ┝═══════╢                          ║          │   ┃
┃   │ Sec.  ║                          ╟══════════┥   ┃
┃   │ Left  ║                          ║ Sec.     │   ┃
┃   │ Dock  ║                          ║ Right    │   ┃
┃   │       ║                          ║ Dock     │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   ┝═══════╧══════════╤═══════════════╧══════════┥   ┃
┃   │ Pri. Bottom Dock ║         Sec. Bottom Dock │   ┃
┃ S │                  ║                          │ S ┃
┠───┴──────────────────┸──────────────────────────┴───┨
┃ Primary Bottom Buttons     Secondary Bottom Buttons ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Created with Blokart

The double-walled lines represent the dividers of a SplitPane. These can be dragged by the user to adjust the width / height of the Dock(s).

P and S labels are short for Primary Buttons and Secondary Buttons.

Each side of the harbour can have any number of Docks, with a toggle button for each. However, on each side there is at most 1 primary, and at most 1 secondary Dock visible. Therefore, there can be a maximum of 8 docks visible.

The Harbour uses a BorderPane, with the primary and secondary buttons occupying the top, left, bottom and right parts.

The center of the BorderPane contains a pair of nested SplitPanes. (the horizontal SplitPane is inside the vertical SplitPane). The application's main content lives in the center-middle of these two SplitPanes. The left/right top/bottom of these split panes are where the open Docks live.

When a primary and secondary dock are both open on one side of the Harbour, we see yet another SplitPane. The user can choose how much space is allocated to each by dragging the divider.

So in this diagram above, we see a total of 6 SplitPanes (the nested pair, plus 4 more - one for each side of the Harbour).

If we hide some docks, so that only 3 docks remain visible :

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Primary Top Buttons           Secondary Top Buttons ┃
┠───┬─────────────────────────────────────────────┬───┨
┃ P │ Primary Top Dock                            │ P ┃
┃   │                                             │   ┃
┃   │                                             │   ┃
┃   │                                             │   ┃
┃   ┝═══════╤══════════════════════════╤══════════┥   ┃
┃   │ Pri.  ║ `content`                ║ Sec.     │   ┃
┃   │ Left  ║                          ║ Right    │   ┃
┃   │ Dock  ║ Your applications        ║ Dock     │   ┃
┃   │       ║ main content.            ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃   │       ║                          ║          │   ┃
┃ S │       ║                          ║          │ S ┃
┠───┴───────┸──────────────────────────┸──────────┴───┨
┃ Primary Bottom Buttons     Secondary Bottom Buttons ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Theme DSL

"harbour" {
}

"harbour_side" {
    // The top/right/bottom/left nodes of the Harbour's BorderPane.
    // It does NOT contain the docks themselves.

    // Tantalum does not use these.
    ":top" { ... }
    ":right" { ... }
    ":bottom" { ... }
    ":left" { ... }

    child( ".buttons" ) { // A Box
        child( ".primary" ) { // A Box
            descendant( "toggle_button" ) {
            // These are the buttons which show/hide a Dock.
        }
    }
    child( ".secondary" ) { // A Box
        descendant( "toggle_button" ) {
            // These are the buttons which show/hide a Dock.
        }
    }


    // Set when a Dock is being dragged.
    ":drag_target" {

        // Highlight ".gap" to indicate a dock can be dragged here.
        // There are 8 "gaps" in total. On each side, there are two "gaps" between the
        // primary and secondary buttons.

        descendant(".gap") {

            minWidth(number)    // Set minWidth and minHeight, otherwise the drag target won't be visible
            minHeight(number)   //  if there are docks on this side of the harbour yet.

            ":drag_hover" {
                // When a Dock is being dragged over to this gap.
            }
        }
    }
}

Harbour and Dock inherit the features of Region.

Constructors

Link copied to clipboard
constructor(initialContent: Node? = null)

Properties

Link copied to clipboard
open override val children: ObservableList<Node>
Link copied to clipboard

Prevents the user moving Docks to the specified sides. This does NOT affect where docks can be placed programmatically.

Link copied to clipboard
Link copied to clipboard

The Node at the center of the Harbour - the part of your application which are not Docks.

Link copied to clipboard
Link copied to clipboard

The Docks which have been added to this Harbour. This includes docks which are collapsed (i.e. their content is not visible).

Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
fun add(dockID: String): Dock?

Adds a dock at its preferred side of the Harbour. See Dock.defaultSide. If the dock is already present, this is a no-op.

fun add(dock: Dock)

Add a dock to its preferred side of the Harbour. See Dock.defaultSide. This is rarely used because it is preferable to use add which takes a dockID.

fun add(dockID: String, side: Side, isPrimary: Boolean = true): Dock?

Adds a dock to a particular side of the Harbour. If the dock is already present (in any position), this is a no-op.

fun add(dock: Dock, side: Side, isPrimary: Boolean = true)

Adds the dock to this Harbour at a particular position give by side and isPrimary. If the dock is already present (in any position), this is a no-op.

Link copied to clipboard
fun findDock(dockID: String): Dock?
Link copied to clipboard

Gets the position of a SplitPane's divider (as a ratio), which determines the size of an open Dock.

Link copied to clipboard

Gets the position of the SplitPane's divider (as a ratio), which separates the Primary and Secondary Docks when both are visible.

Link copied to clipboard
fun Harbour.load(preferences: Preferences): Boolean

Load the layout of the Harbour from Preferences (aka the registry on Windows).

Link copied to clipboard
open override fun nodePrefHeight(): Float
Link copied to clipboard
open override fun nodePrefWidth(): Float
Link copied to clipboard
fun Harbour.save(preferences: Preferences)

Saves the layout of the Harbour to Java Preferences (aka the registry on Windows).

Link copied to clipboard
fun setDividerPosition(side: Side, ratio: Float)

Sets the position of a SplitPane's divider (as a ratio), which determines the size of an open Dock. For side LEFT/TOP the default value is 0.25, and for RIGHT/BOTTOM is 0.75 i.e. open docks are allocated a quarter of the available space.

Link copied to clipboard
fun setSplitPosition(side: Side, ratio: Float)

Sets the position of the SplitPane's divider (as a ratio), which separates the Primary and Secondary Docks when both are visible. The default value is 0.5, i.e. both Docks are given equal space.