Skip to content

Commit

Permalink
Add scroll bar + sample (#130)
Browse files Browse the repository at this point in the history
Signed-off-by: Marek Maškarinec <marek@mrms.cz>
  • Loading branch information
marekmaskarinec committed Jan 1, 2025
1 parent de2f23b commit 49c2b83
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 178 deletions.
41 changes: 41 additions & 0 deletions samples/ui/scroll/main.um
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

import (
"window.um"
"rect.um"
"ui.um"
)

var gui: ui::Gui
var maxScroll, scroll: real32

const buttonCount = 30
const buttonHeight = 30

fn init*() {
window::setup("Scoll Area Sample", 640, 480)

gui = ui::mk(rect::fromVf2({}, window::wp), ui::getDefaultStyle())

window::onFrame.register({
layout := ui::LayoutFn{
gui.scrollArea(&scroll, buttonHeight * buttonCount, {
scrollBarSize: 20
})
gui.box({
dimension: buttonHeight
})

for i:=0; i < buttonHeight; i++ {
if gui.qbutton(sprintf("Button %d", i)) {
printf("Button %d\n", i)
}
}

gui.popContainer()
gui.popContainer()
}

gui.eval(layout)
gui.draw(layout)
})
}
235 changes: 91 additions & 144 deletions src/staembed.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Generated via cmd/win-buildmodules.bat
#include "tophat.h"
// Generated via src/Makefile
#include "tophat.h"
const char *th_em_modulesrc[] = {
"\n"
"import (\n"
Expand Down Expand Up @@ -3332,6 +3332,38 @@ const char *th_em_modulesrc[] = {
"\t}\n"
"}\n"
"\n"
"//~~struct ButtonConfig\n"
"// Configuration for the button.\n"
"type ButtonConfig* = struct {\n"
"\trect: rect::Rect\n"
"}\n"
"//~~\n"
"\n"
"//~~fn Gui.button\n"
"// Adds a button to the gui. The button acts like a `Stack` container, but it\n"
"// is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
"// pressed and the gui is in the eval phase, the return value will be true.\n"
"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
"//~~\n"
"\tgui.stack(StackConfig{ rect: cfg.rect })\n"
"\tr := gui.getContainer().getDims()\n"
"\n"
"\tif gui.isEval {\n"
"\t\tif gui.hover(r) && input::isJustReleased(input::Key.mouse1) {\n"
"\t\t\treturn true\n"
"\t\t}\n"
"\t\treturn false\n"
"\t} else {\n"
"\t\tif gui.hover(r) && gui.m1Pressed {\n"
"\t\t\tgui.getStyle().negBox.draw(r)\n"
"\t\t} else {\n"
"\t\t\tgui.getStyle().posBox.draw(r)\n"
"\t\t}\n"
"\t}\n"
"\n"
"\treturn false\n"
"}\n"
"\n"
"//~~struct ScrollAreaConfig\n"
"// Configuration for the scroll area.\n"
"type ScrollAreaConfig* = struct {\n"
Expand All @@ -3340,6 +3372,8 @@ const char *th_em_modulesrc[] = {
"\tspeed: real32\n"
"\t// if true, scrolling will be horizontal\n"
"\thorizontal: bool\n"
"\t// if not zero, render a scroll bar with the given width/height\n"
"\tscrollBarSize: real32\n"
"}\n"
"//~~\n"
"\n"
Expand All @@ -3359,11 +3393,11 @@ const char *th_em_modulesrc[] = {
"\tif r.y == 0 { r.y = this.dm.y }\n"
"\tif this.cfg.horizontal {\n"
"\t\tif r.w == 0 { r.w = this.maxScroll }\n"
"\t\tif r.h == 0 { r.h = this.dm.h }\n"
"\t\tif r.h == 0 { r.h = this.dm.h - this.cfg.scrollBarSize }\n"
"\t\treturn { r.x - this.scroll^, r.y, r.w, r.h }\n"
"\t}\n"
"\n"
"\tif r.w == 0 { r.w = this.dm.w }\n"
"\tif r.w == 0 { r.w = this.dm.w - this.cfg.scrollBarSize }\n"
"\tif r.h == 0 { r.h = this.maxScroll }\n"
"\treturn { r.x, r.y - this.scroll^, r.w, r.h }\n"
"}\n"
Expand Down Expand Up @@ -3397,6 +3431,37 @@ const char *th_em_modulesrc[] = {
"\t\treturn\n"
"\t}\n"
"\n"
"\tif this.cfg.scrollBarSize > 0 {\n"
"\t\tbarDm := rect::Rect{}\n"
"\t\tif this.cfg.horizontal {\n"
"\t\t\tbarDm.h = this.cfg.scrollBarSize\n"
"\t\t\tbarDm.w = this.dm.w / maxScroll * this.dm.w\n"
"\t\t\tbarDm.x = this.dm.x + (scroll^ / maxScroll) * this.dm.w\n"
"\t\t\tbarDm.y = this.dm.getEnd().y - barDm.h\n"
"\t\t} else {\n"
"\t\t\tbarDm.h = this.dm.h / maxScroll * this.dm.h\n"
"\t\t\tbarDm.w = this.cfg.scrollBarSize\n"
"\t\t\tbarDm.x = this.dm.getEnd().x - barDm.w\n"
"\t\t\tbarDm.y = this.dm.y + (scroll^ / maxScroll) * this.dm.h\n"
"\t\t}\n"
"\n"
"\t\tif gui.isEval && gui.hover(barDm) && gui.m1Pressed {\n"
"\t\t\tif this.cfg.horizontal {\n"
"\t\t\t\tscroll ^+= input::getMouseDelta().x\n"
"\t\t\t} else {\n"
"\t\t\t\tscroll ^+= input::getMouseDelta().y\n"
"\t\t\t}\n"
"\t\t}\n"
"\n"
"\t\tif !gui.isEval {\n"
"\t\t\tif gui.hover(barDm) && gui.m1Pressed {\n"
"\t\t\t\tgui.getStyle().negBox.draw(barDm)\n"
"\t\t\t} else {\n"
"\t\t\t\tgui.getStyle().posBox.draw(barDm)\n"
"\t\t\t}\n"
"\t\t}\n"
"\t}\n"
"\n"
"\tif gui.isEval && gui.hover(this.dm) {\n"
"\t\tv := input::getMouseScroll().y\n"
"\t\tif this.cfg.horizontal {\n"
Expand All @@ -3410,38 +3475,6 @@ const char *th_em_modulesrc[] = {
"\t}\n"
"}\n"
"\n"
"//~~struct ButtonConfig\n"
"// Configuration for the button.\n"
"type ButtonConfig* = struct {\n"
"\trect: rect::Rect\n"
"}\n"
"//~~\n"
"\n"
"//~~fn Gui.button\n"
"// Adds a button to the gui. The button acts like a `Stack` container, but it\n"
"// is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
"// pressed and the gui is in the eval phase, the return value will be true.\n"
"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
"//~~\n"
"\tgui.stack(StackConfig{ rect: cfg.rect })\n"
"\tr := gui.getContainer().getDims()\n"
"\n"
"\tif gui.isEval {\n"
"\t\tif gui.hover(r) && input::isJustReleased(input::Key.mouse1) {\n"
"\t\t\treturn true\n"
"\t\t}\n"
"\t\treturn false\n"
"\t} else {\n"
"\t\tif gui.hover(r) && gui.m1Pressed {\n"
"\t\t\tgui.getStyle().negBox.draw(r)\n"
"\t\t} else {\n"
"\t\t\tgui.getStyle().posBox.draw(r)\n"
"\t\t}\n"
"\t}\n"
"\n"
"\treturn false\n"
"}\n"
"\n"
"//~~struct LabelConfig\n"
"type LabelConfig* = struct {\n"
"\t// centers the label along the X axis, enables `stretchX`\n"
Expand Down Expand Up @@ -4423,94 +4456,6 @@ const char *th_em_moduledocs[] = {
"---------\n"
"\n"
"",
"\n"
"\n"
"\n"
"Canvas library allowing for drawing basic shapes. Coordinates are based on\n"
"the screen.\n"
"\n"
"---------\n"
"\n"
"fn drawText\n"
"\n"
"fn drawText*(text: str, pos: th::Vf2, color: uint32, size: th::fu) {\n"
"\n"
"Draws a basic pixel text. Only ascii is supported.\n"
"\n"
"---------\n"
"\n"
"fn textSize\n"
"\n"
"fn textSize*(text: str, scale: th::fu): th::Vf2 {\n"
"\n"
"Returns the size of text taken by an equivalent drawText call.\n"
"\n"
"---------\n"
"\n"
"Pixel Font\n"
"\n"
"var pixelFont*: PixelFont\n"
"\n"
"The `pixelFont` variable exposes the canvas pixel font as a generic font.\n"
"\n"
"---------\n"
"\n"
"fn drawRect\n"
"\n"
"fn drawRect*(color: uint32, r: rect::Rect) {\n"
"\n"
"Draws a Rectangle.\n"
"\n"
"---------\n"
"\n"
"fn drawLine\n"
"\n"
"fn drawLine*(color: uint32, b, e: th::Vf2, thickness: th::fu) {\n"
"\n"
"Draws a line.\n"
"\n"
"---------\n"
"\n"
"fn drawRectLines\n"
"\n"
"fn drawRectLines*(color: uint32, r: rect::Rect, thickness: real32 = 1.0) {\n"
"\n"
"Draws rect border.\n"
"\n"
"---------\n"
"\n"
"fn drawQuad\n"
"\n"
"fn drawQuad*(color: uint32, q: th::Quad) {\n"
"\n"
"Draws a convex quad.\n"
"\n"
"---------\n"
"\n"
"fn drawTrig\n"
"\n"
"fn drawTrig*(color: uint32, a, b, c: th::Vf2) {\n"
"\n"
"Draws a triangle.\n"
"\n"
"---------\n"
"\n"
"fn beginScissorRect\n"
"\n"
"fn beginScissorRect*(r: rect::Rect, debug: bool = false) {\n"
"\n"
"Disable rendering outside of rect `r`\n"
"\n"
"---------\n"
"\n"
"fn endScissor\n"
"\n"
"fn endScissor*() {\n"
"\n"
"Stops cropping\n"
"\n"
"---------\n"
"\n"
"",
"\n"
"\n"
Expand Down Expand Up @@ -6676,6 +6621,26 @@ const char *th_em_moduledocs[] = {
"\n"
"---------\n"
"\n"
"struct ButtonConfig\n"
"\n"
"type ButtonConfig* = struct {\n"
"\trect: rect::Rect\n"
"}\n"
"\n"
"Configuration for the button.\n"
"\n"
"---------\n"
"\n"
"fn Gui.button\n"
"\n"
"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
"\n"
"Adds a button to the gui. The button acts like a `Stack` container, but it\n"
"is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
"pressed and the gui is in the eval phase, the return value will be true.\n"
"\n"
"---------\n"
"\n"
"struct ScrollAreaConfig\n"
"\n"
"type ScrollAreaConfig* = struct {\n"
Expand All @@ -6684,6 +6649,8 @@ const char *th_em_moduledocs[] = {
"\tspeed: real32\n"
"\t// if true, scrolling will be horizontal\n"
"\thorizontal: bool\n"
"\t// if not zero, render a scroll bar with the given width/height\n"
"\tscrollBarSize: real32\n"
"}\n"
"\n"
"Configuration for the scroll area.\n"
Expand Down Expand Up @@ -6713,26 +6680,6 @@ const char *th_em_moduledocs[] = {
"\n"
"---------\n"
"\n"
"struct ButtonConfig\n"
"\n"
"type ButtonConfig* = struct {\n"
"\trect: rect::Rect\n"
"}\n"
"\n"
"Configuration for the button.\n"
"\n"
"---------\n"
"\n"
"fn Gui.button\n"
"\n"
"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n"
"\n"
"Adds a button to the gui. The button acts like a `Stack` container, but it\n"
"is drawn using the pos/nexBox styles and handles clicks. If the button is\n"
"pressed and the gui is in the eval phase, the return value will be true.\n"
"\n"
"---------\n"
"\n"
"struct LabelConfig\n"
"\n"
"type LabelConfig* = struct {\n"
Expand Down
Loading

0 comments on commit 49c2b83

Please sign in to comment.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy