Skip to main content

core.scrollbar

Scrollable viewport indicator with draggable thumb. Supports both vertical and horizontal orientation with configurable alignment. Uses a "normal" coordinate system internally that treats all scrollbars as vertical-end-aligned, then transforms to the actual orientation/alignment.

local scrollbar = require "core.scrollbar"

__index

(field) __index: core.object

Base class providing OOP functionality for Lua. All classes in Pragtical inherit from Object.


alignment

(field) alignment: "e"|"s"

Start or end position (left/top vs right/bottom)


contracted_margin

(field) contracted_margin: number?

Override for style.contracted_scrollbar_margin


contracted_size

(field) contracted_size: number?

Override for style.scrollbar_size


direction

(field) direction: "h"|"v"

Vertical or horizontal orientation


drag_start_offset

(field) drag_start_offset: number

Offset from thumb top when drag started


dragging

(field) dragging: boolean

True when user is dragging the thumb


expand_percent

(field) expand_percent: number

Animation state [0-1] for hover expansion


expanded_margin

(field) expanded_margin: number?

Override for style.expanded_scrollbar_margin


expanded_size

(field) expanded_size: number?

Override for style.expanded_scrollbar_size


force_status

(field) force_status: ("contracted"|"expanded"|false)?

Forced display state


minimum_thumb_size

(field) minimum_thumb_size: number?

Override for style.minimum_thumb_size


percent

(field) percent: number

Scroll position [0-1]


super

(field) super: core.object

Base class providing OOP functionality for Lua. All classes in Pragtical inherit from Object.


core.scrollbar.hovering

thumb

(field) thumb: boolean

True if mouse is over thumb


track

(field) track: boolean

True if mouse is over track


core.scrollbar.normal_rect

across

(field) across: number

Position perpendicular to scroll direction


across_size

(field) across_size: number

Size perpendicular to scroll direction


along

(field) along: number

Position parallel to scroll direction


along_size

(field) along_size: number

Size parallel to scroll direction


scrollable

(field) scrollable: number

Total scrollable size


core.scrollbar.options

Configuration options for creating a scrollbar.

alignment

(field) alignment: ("e"|"s")?

Start or End - left/top vs right/bottom (default: "e")


contracted_margin

(field) contracted_margin: number?

Override style.contracted_scrollbar_margin


contracted_size

(field) contracted_size: number?

Override style.scrollbar_size


direction

(field) direction: ("h"|"v")?

Vertical or Horizontal (default: "v")


expanded_margin

(field) expanded_margin: number?

Override style.expanded_scrollbar_margin


expanded_size

(field) expanded_size: number?

Override style.expanded_scrollbar_size


force_status

(field) force_status: ("contracted"|"expanded"|false)?

Force display state


minimum_thumb_size

(field) minimum_thumb_size: number?

Override style.minimum_thumb_size


core.scrollbar.rect

h

(field) h: number

scrollable

(field) scrollable: number

Total scrollable size


w

(field) w: number

x

(field) x: number

y

(field) y: number

__call

(method) core.object:__call(...any)
-> obj: core.object

Metamethod allowing class to be called like a constructor. Enables syntax: local obj = MyClass(args) instead of MyClass:new(args) Automatically creates instance and calls new() with provided arguments.

@return obj: core.object — The new instance of the class


__tostring

(method) core.scrollbar:__tostring()
-> string

_get_thumb_rect_normal

(method) core.scrollbar:_get_thumb_rect_normal()
-> x: number
2. y: number
3. w: number
4. h: number

Get thumb rectangle in normalized coordinates. Internal helper - use get_thumb_rect() for real coordinates.

@return x: number — Normalized x coordinate

@return y: number — Normalized y coordinate

@return w: number — Normalized width

@return h: number — Normalized height


_get_track_rect_normal

(method) core.scrollbar:_get_track_rect_normal()
-> x: number
2. y: number
3. w: number
4. h: number

Get track rectangle in normalized coordinates. Internal helper - use get_track_rect() for real coordinates.

@return x: number — Normalized x coordinate

@return y: number — Normalized y coordinate

@return w: number — Normalized width

@return h: number — Normalized height


_on_mouse_moved_normal

(method) core.scrollbar:_on_mouse_moved_normal(x: number, y: number, dx: number, dy: number)
-> result: boolean|number

Handle mouse movement in normalized coordinates. Internal helper - use on_mouse_moved() for real coordinates.

@param x: number — Normalized x coordinate

@param y: number — Normalized y coordinate

@param dx: number — Normalized delta x

@param dy: number — Normalized delta y

@return result: boolean|number — True if hovering, 0-1 percent if dragging, falsy otherwise


_on_mouse_pressed_normal

(method) core.scrollbar:_on_mouse_pressed_normal(button: 'left'|'right', x: number, y: number, clicks: integer)
-> result: boolean|number

Handle mouse press in normalized coordinates. Internal helper - use on_mouse_pressed() for real coordinates.

button:
| 'left'
| 'right'

@param x: number — Normalized x coordinate

@param y: number — Normalized y coordinate

@param clicks: integer — Number of clicks

@return result: boolean|number — True if thumb clicked, 0-1 percent if track clicked, falsy otherwise


_on_mouse_released_normal

(method) core.scrollbar:_on_mouse_released_normal(button: 'left'|'right', x: number, y: number)
-> hovering: boolean

Handle mouse release in normalized coordinates. Internal helper - use on_mouse_released() for real coordinates.

button:
| 'left'
| 'right'

@param x: number — Normalized x coordinate

@param y: number — Normalized y coordinate

@return hovering: boolean — True if hovering track or thumb


_overlaps_normal

(method) core.scrollbar:_overlaps_normal(x: number, y: number)
-> part: "thumb"|"track"|nil

Check what part of scrollbar overlaps a point in normalized coordinates. Internal helper - use overlaps() for real coordinates.

part:
| "thumb"
| "track"

@param x: number — Normalized x coordinate

@param y: number — Normalized y coordinate

@return part: "thumb"|"track"|nil — What was hit, or nil if nothing


_update_hover_status_normal

(method) core.scrollbar:_update_hover_status_normal(x: number, y: number)
-> hovering: boolean

Update hover status in normalized coordinates. Internal helper called by other mouse methods.

@param x: number — Normalized x coordinate

@param y: number — Normalized y coordinate

@return hovering: boolean — True if hovering track or thumb


draw

(method) core.scrollbar:draw()

Draw the complete scrollbar (track and thumb). Call this from the owning view's draw() method.


draw_thumb

(method) core.scrollbar:draw_thumb()

Draw the scrollbar thumb (draggable indicator). Highlights when hovered or being dragged.


draw_track

(method) core.scrollbar:draw_track()

Draw the scrollbar track (background). Only draws when hovered/dragging or expanded. Fades in based on expand_percent animation.


extend

(method) core.object:extend()
-> cls: core.object

Create a new class that inherits from this one. Returns a new class with this class as its parent. Example: local MyClass = Object:extend()

@return cls: core.object — The new class table


extends

(method) core.object:extends(T: any)
-> extends: boolean

Check if object inherits from the given type (inheritance-aware). Use this to check class hierarchy. Example: view:extends(View) returns true for View and all subclasses

@param T: any — Class to check inheritance from

@return extends: boolean — True if object is T or inherits from T


get_thumb_rect

(method) core.scrollbar:get_thumb_rect()
-> x: number
2. y: number
3. w: number
4. h: number

Get the thumb rectangle (the draggable part of the scrollbar).

@return x: number — Screen x coordinate

@return y: number — Screen y coordinate

@return w: number — Width in pixels

@return h: number — Height in pixels


get_track_rect

(method) core.scrollbar:get_track_rect()
-> x: number
2. y: number
3. w: number
4. h: number

Get the track rectangle (the background of the scrollbar).

@return x: number — Screen x coordinate

@return y: number — Screen y coordinate

@return w: number — Width in pixels

@return h: number — Height in pixels


is

(method) core.object:is(T: any)
-> is_exact: boolean

Check if object is exactly of the given type (no inheritance check). Use this for strict type matching. Example: view:is(DocView) returns true only if view is a DocView, not a subclass

@param T: any — Class to check against

@return is_exact: boolean — True if object is exactly type T


is_class_of

(method) core.object:is_class_of(T: any)
-> is_instance: boolean

Check if the given object is exactly an instance of this class. Inverse of is() - checks if T is an instance of self. Example: DocView:is_class_of(obj) checks if obj is exactly a DocView

@param T: any — Object to check

@return is_instance: boolean — True if T is exactly an instance of this class


is_extended_by

(method) core.object:is_extended_by(T: any)
-> is_extended: boolean

Check if the given object/class inherits from this class. Inverse of extends() - checks if T is a subclass of self. Example: View:is_extended_by(DocView) checks if DocView inherits from View

@param T: any — Object or class to check

@return is_extended: boolean — True if T inherits from this class


new

(method) core.scrollbar:new(options: core.scrollbar.options)

Constructor - initializes a scrollbar with specified orientation and style.

@param options: core.scrollbar.options — Configuration options


normal_to_real

(method) core.scrollbar:normal_to_real(x?: number, y?: number, w?: number, h?: number)
-> x: number
2. y: number
3. w: number
4. h: number

Transform normalized coordinates back to real coordinate system. Internal helper for orientation/alignment handling.

@param x?: number — Normalized x coordinate

@param y?: number — Normalized y coordinate

@param w?: number — Normalized width

@param h?: number — Normalized height

@return x: number — Real x

@return y: number — Real y

@return w: number — Real width

@return h: number — Real height


on_mouse_left

(method) core.scrollbar:on_mouse_left()

Handle mouse leaving the scrollbar area. Clears all hover states.


on_mouse_moved

(method) core.scrollbar:on_mouse_moved(x: number, y: number, dx: number, dy: number)
-> result: (boolean|number)?

Handle mouse movement events on the scrollbar. Updates hover status and returns drag position if dragging. Does NOT automatically update scroll position - caller must use set_percent().

@param x: number — Screen x coordinate

@param y: number — Screen y coordinate

@param dx: number — Delta x since last move

@param dy: number — Delta y since last move

@return result: (boolean|number)? — True if hovering, 0-1 percent if dragging, falsy otherwise


on_mouse_pressed

(method) core.scrollbar:on_mouse_pressed(button: 'left'|'right', x: number, y: number, clicks: integer)
-> result: (boolean|number)?

Handle mouse press events on the scrollbar. Sets dragging state if thumb is clicked. Does NOT automatically update scroll position - caller must use set_percent().

button:
| 'left'
| 'right'

@param button: 'left'|'right' — Mouse button

@param x: number — Screen x coordinate

@param y: number — Screen y coordinate

@param clicks: integer — Number of clicks

@return result: (boolean|number)? — True if thumb clicked, 0-1 percent if track clicked, falsy otherwise


on_mouse_released

(method) core.scrollbar:on_mouse_released(button: 'left'|'right', x: number, y: number)
-> hovering: boolean?

Handle mouse release events on the scrollbar. Clears dragging state and updates hover status.

button:
| 'left'
| 'right'

@param button: 'left'|'right' — Mouse button

@param x: number — Screen x coordinate

@param y: number — Screen y coordinate

@return hovering: boolean? — True if hovering track or thumb


overlaps

(method) core.scrollbar:overlaps(x: number, y: number)
-> part: "thumb"|"track"|nil

Check what part of the scrollbar overlaps a screen point.

part:
| "thumb"
| "track"

@param x: number — Screen x coordinate

@param y: number — Screen y coordinate

@return part: "thumb"|"track"|nil — What was hit, or nil if nothing


real_to_normal

(method) core.scrollbar:real_to_normal(x?: number, y?: number, w?: number, h?: number)
-> x: number
2. y: number
3. w: number
4. h: number

Transform real coordinates to normalized coordinate system. Internal helper for orientation/alignment handling.

@param x?: number — Real x coordinate

@param y?: number — Real y coordinate

@param w?: number — Real width

@param h?: number — Real height

@return x: number — Normalized x

@return y: number — Normalized y

@return w: number — Normalized width

@return h: number — Normalized height


set_forced_status

(method) core.scrollbar:set_forced_status(status: "contracted"|"expanded"|false)

Set the forced display status of the scrollbar. When forced, the scrollbar won't animate based on hover state.

status:
| "expanded"
| "contracted"
| false

@param status: "contracted"|"expanded"|false — Status to force (false to allow auto-animation)


set_percent

(method) core.scrollbar:set_percent(percent: number)

Set the scrollbar thumb position.

@param percent: number — Position from 0-1 (0 = top/left, 1 = bottom/right)


set_size

(method) core.scrollbar:set_size(x: number, y: number, w: number, h: number, scrollable: number)

Set the bounding box of the view this scrollbar belongs to. Must be called when view size or scrollable area changes.

@param x: number — View x position

@param y: number — View y position

@param w: number — View width

@param h: number — View height

@param scrollable: number — Total scrollable size (height for vertical, width for horizontal)


update

(method) core.scrollbar:update()

Update scrollbar animations (hover expansion). Call this every frame to animate the scrollbar width on hover.