Skip to content

Commit

Permalink
Scrollbar, Slider, Anchor System
Browse files Browse the repository at this point in the history
* Add Scrollbar
* Vertical Slider
* Improve Anchor System
  • Loading branch information
malisipi committed Jul 7, 2022
1 parent fca61b0 commit bab15ca
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 61 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ You can find more examples in `./examples/` folder.
* Theme from system accent color, _If couldn't found accent color, use dark/light theme preference. If couldn't found dark/light theme preference, choose light theme_
![Themes](./pictures/Themes.png "Themes")
* Widgets
* Slider
* Slider (Verical & Horizontal)
* Button
* Label
* Textbox
Expand All @@ -49,7 +49,8 @@ You can find more examples in `./examples/` folder.
* Graphs
* Menubar
* Map
* Screen Reader Support (Experimental)
* Scrollbar
* Screen Reader Support (Experimental)
* Dialogs
* Messagebox
* Inputbox
Expand All @@ -67,10 +68,8 @@ You can find more examples in `./examples/` folder.
* Textfield
* Codefield
* System Icon Support
* Scrollbars
* Status Bar
* Spinner
* Vertical Slider
* Spin Button
* Editable Label
* Switch
Expand Down
94 changes: 57 additions & 37 deletions anchor.v
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
module mui

fn calc_get_percent(window_size []int, percent string) int {
fn calc_get_percent(window_info []int, percent string) int {
mut x:=0
match percent.split("%")[1]{
"x"{
x=window_size[0]
x=window_info[0]
} "y"{
x=window_size[1]
x=window_info[1]
} else {}
}
return percent.split("%")[0].int()*x/100
}

fn calc_size(window_size []int, w int|string, h int|string) (int, int){
fn calc_size(window_info []int, w int|string, h int|string) (int, int){
mut data:=[]int{}
for x in [w,h]{
match x{
int{
data << x
} string {
params:=x.split(" ")
mut params:=x.split(" ")
mut window_size:=window_info.clone()
if x.starts_with("!") {
params=x.replace("! ","").replace("!","").split(" ")
window_size=[window_info[2],window_info[3]]
}
match params.len{
1 {
if params[0].split("%").len==1{
Expand All @@ -39,53 +44,68 @@ fn calc_size(window_size []int, w int|string, h int|string) (int, int){
return data[0], data[1]
}

fn calc_x_y(window_size []int, x int|string, y int|string, size []int) (int, int){
fn calc_x_y(window_info []int, x int|string, y int|string, size []int) (int, int){
mut data:=[]int{}
for w, q in [x,y].clone(){
match q{
for w, r in [x,y].clone(){
mut x_y_scroll:=window_info#[-2..]
match r{
int{
data << q
data << r-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
} string {
if q.starts_with("#"){
params:=q.replace("# ","").split(" ")
offset:=if w==0{window_size[0]} else {window_size[1]}-size[w]
match params.len{
1 {
if params[0].split("%").len==1{
data << offset-params[0].int()

mut q:=r
mut window_size:=window_info.clone()
if q.starts_with("!") {
q=q.replace("! ","").replace("!","")
window_size=[window_info[2],window_info[3],window_info[4],window_info[5]]
}
if q.starts_with("&") {
x_y_scroll=[0,0]
q=q.replace("& ","").replace("&","")
}

if q.starts_with("#"){
params:=q.replace("# ","").replace("#","").split(" ")
offset:=if w==0{window_size[0]} else {window_size[1]}-size[w]
match params.len{
1 {
if params[0].split("%").len==1{
data << offset-params[0].int() -if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
} else {
data << offset-calc_get_percent(window_size, params[0])-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
}
} 2 {
data << offset-calc_get_percent(window_size, params[0]) + params[1].int()-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
} else {
data << offset-calc_get_percent(window_size, params[0])
error("Unable to calculate position. Parameters should be like `50%x`, `90`, `# 25%x +50` ")
}
} 2 {
data << offset-calc_get_percent(window_size, params[0]) + params[1].int()
} else {
error("Unable to calculate position. Parameters should be like `50%x`, `90`, `# 25%x +50` ")
}
}
} else {
params:=q.split(" ")
match params.len{
1 {
if params[0].split("%").len==1{
data << params[0].int()
} else {
params:=q.split(" ")
match params.len{
1 {
if params[0].split("%").len==1{
data << params[0].int()-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
} else {
data << calc_get_percent(window_size, params[0])-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
}
} 2 {
data << calc_get_percent(window_size, params[0]) + params[1].int()-if w==0{x_y_scroll[0]} else {x_y_scroll[1]}
} else {
data << calc_get_percent(window_size, params[0])
error("Unable to calculate position. Parameters should be like `50%x`, `90`, `# 25%x +50` ")
}
} 2 {
data << calc_get_percent(window_size, params[0]) + params[1].int()
} else {
error("Unable to calculate position. Parameters should be like `50%x`, `90`, `# 25%x +50` ")
}
}
}


}
}
}
return data[0], data[1]
}

fn calc_points(window_size []int, x int|string, y int|string, w int|string, h int|string) []int{
calc_width,calc_height:=calc_size(window_size, w, h)
x_,y_:=calc_x_y(window_size, x, y, [calc_width, calc_height])
fn calc_points(window_info []int, x int|string, y int|string, w int|string, h int|string) []int{
calc_width,calc_height:=calc_size(window_info, w, h)
x_,y_:=calc_x_y(window_info, x, y, [calc_width, calc_height])
return [x_,y_,calc_width, calc_height]
}
9 changes: 9 additions & 0 deletions examples/scrollbar_example.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import malisipi.mui as m

mut app:=m.create(m.WindowConfig{ title:"Scrollbar - MUI Example", height:300, width:300, scrollbar:true, view_area:[300,800] })

app.label(m.Widget{ id:"text1", x:"10%x", y:"50", width:"80%x", height:"50" text:"Example Text - Scroll Down" })
app.label(m.Widget{ id:"text2", x:"& 10%x", y:"& 125", width:"80%x", height:"50" text:"Example Text 2 - Fixed Position" })
app.label(m.Widget{ id:"text3", x:"10%x", y:"650", width:"80%x", height:"50" text:"Example Text 3 - Hi!" })

m.run(mut app)
9 changes: 9 additions & 0 deletions examples/vert_slider.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import malisipi.mui

fn main(){
mut app:=mui.create(mui.WindowConfig{ title:"Vertical Slider - MUI Example", height: 350, width:350})
app.slider(mui.Widget{ id:"@scrollbar:horizontal", x: 10, y:10, width:25, height:200, value_max:10, vertical:true})
mui.run(mut app)
}


43 changes: 35 additions & 8 deletions mui.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ pub fn create(args &WindowConfig) &Window{
color_scheme: if args.color!=[-1,-1,-1] { create_gx_color_from_manuel_color(args.color) } else { create_gx_color_from_color_scheme() }
gg: 0
menubar: args.menubar
scrollbar: args.scrollbar
x_offset: 0
xn_offset: if args.scrollbar { scrollbar_size } else { 0 }
y_offset: if args.menubar!=[]map["string"]WindowData{} { menubar_height } else { 0 }
yn_offset: if args.scrollbar { scrollbar_size } else { 0 }
app_data: args.app_data
screen_reader: if args.screen_reader { check_screen_reader() } else { false }
}
Expand All @@ -27,12 +30,18 @@ pub fn create(args &WindowConfig) &Window{
window_title: args.title
move_fn: move_fn
unclick_fn: unclick_fn
resized_fn: resized_fn
font_path: args.font
width: args.width
height: args.height
create_window: true
)

if args.scrollbar{
app.scrollbar(mui.Widget{ id:"@scrollbar:horizontal", x:"!& 0", y:"!&# 0", width:"! 100%x -15", height:"! 15", value_max:args.view_area[0], size_thumb:args.width, onchange: update_scroll_hor})
app.scrollbar(mui.Widget{ id:"@scrollbar:vertical", x:"!&# 0", y:"!& 0", width:"! 15", height:"! 100%y -15", value_max:args.view_area[1], size_thumb:args.height, onchange: update_scroll_ver, vertical:true})
}

return app
}

Expand All @@ -43,10 +52,10 @@ fn frame_fn(app &Window) {
mut objects:=app.objects.clone()
if app.focus!="" { objects << get_object_by_id(app, app.focus) }
real_size:=app.gg.window_size()
window_size:=[real_size.width,real_size.height-app.y_offset]
window_info:=[real_size.width-app.x_offset-app.xn_offset,real_size.height-app.y_offset-app.yn_offset,real_size.width,real_size.height,app.scroll_x,app.scroll_y].clone()
for object in objects{
if !object["hi"].bol && object["type"].str!="hidden"{
points:=calc_points(window_size,object["x_raw"].str,object["y_raw"].str,object["w_raw"].str,object["h_raw"].str)
points:=calc_points(window_info,object["x_raw"].str,object["y_raw"].str,object["w_raw"].str,object["h_raw"].str)
object["x"]=WindowData{num:points[0]}
object["y"]=WindowData{num:points[1]+app.y_offset}
object["w"]=WindowData{num:points[2]}
Expand Down Expand Up @@ -84,6 +93,8 @@ fn frame_fn(app &Window) {
draw_line_graph(app, object)
}"map"{
draw_map(app, object)
}"scrollbar"{
draw_scrollbar(app, object)
}else {}
}
}
Expand Down Expand Up @@ -153,8 +164,12 @@ fn click_fn(x f32, y f32, mb gg.MouseButton, mut app &Window) {
} "checkbox" {
object["c"]=WindowData{bol:!object["c"].bol}
object["fnchg"].fun(EventDetails{event:"value_change",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str, value:object["c"].bol.str()},mut app, mut app.app_data)
} "slider" {
object["val"]=WindowData{num:math.min(int(math.round(f32(x-object["x"].num)/f32(object["w"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
} "slider", "scrollbar" {
if !object["vert"].bol {
object["val"]=WindowData{num:math.min(int(math.round(f32(math.min(math.max(x-object["x"].num,0),object["w"].num))/f32(object["w"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
} else {
object["val"]=WindowData{num:math.min(int(math.round(f32(math.min(math.max(y-object["y"].num,0),object["h"].num))/f32(object["h"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
}
object["click"]=WindowData{bol:true}
object["fnclk"].fun(EventDetails{event:"click",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str, value:object["val"].num.str()}, mut app, mut app.app_data)
object["fnchg"].fun(EventDetails{event:"value_change",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str, value:object["val"].num.str()}, mut app, mut app.app_data)
Expand Down Expand Up @@ -204,9 +219,13 @@ fn move_fn(x f32, y f32, mut app &Window){
unsafe{
if !(app.focus==""){
object:=get_object_by_id(app, app.focus)
if object["type"].str=="slider"{
if object["type"].str=="slider" || object["type"].str=="scrollbar"{
if object["click"].bol {
object["val"]=WindowData{num:math.min(int(math.round(f32(math.min(math.max(x-object["x"].num,0),object["w"].num))/f32(object["w"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
if !object["vert"].bol {
object["val"]=WindowData{num:math.min(int(math.round(f32(math.min(math.max(x-object["x"].num,0),object["w"].num))/f32(object["w"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
} else {
object["val"]=WindowData{num:math.min(int(math.round(f32(math.min(math.max(y-object["y"].num,0),object["h"].num))/f32(object["h"].num/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num))))*object["vStep"].num+object["vlMin"].num,object["vlMax"].num)}
}
object["fnchg"].fun(EventDetails{event:"value_change",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str,value:object["val"].num.str()},mut app, mut app.app_data)
}
}
Expand All @@ -219,7 +238,7 @@ fn unclick_fn(x f32, y f32, mb gg.MouseButton, mut app &Window){
unsafe{
if !(app.focus==""){
object:=get_object_by_id(app, app.focus)
if object["type"].str=="slider"{
if object["type"].str=="slider" || object["type"].str=="scrollbar"{
object["click"]=WindowData{bol:false}
object["fnucl"].fun(EventDetails{event:"unclick",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str, value:object["val"].num.str()},mut app, mut app.app_data)
}
Expand Down Expand Up @@ -285,7 +304,7 @@ fn keyboard_fn(chr u32|string, mut app &Window){
object["c"]=WindowData{bol:!object["c"].bol}
object["fnchg"].fun(EventDetails{event:"value_change",trigger:"keyboard",target_type:object["type"].str,target_id:object["id"].str,value:object["c"].bol.str()},mut app, mut app.app_data)
}
} "slider" {
} "slider","scrollbar" {
if key=="left" {
object["val"]=WindowData{num:math.max(object["vlMin"].num,object["val"].num-object["vStep"].num)}
object["fnchg"].fun(EventDetails{event:"value_change",trigger:"keyboard",target_type:object["type"].str,target_id:object["id"].str,value:object["val"].num.str()},mut app, mut app.app_data)
Expand Down Expand Up @@ -350,6 +369,14 @@ fn keyboard_fn(chr u32|string, mut app &Window){
}
}

[unsafe]
fn resized_fn(event &gg.Event, mut app &Window){
unsafe{
app.get_object_by_id("@scrollbar:horizontal")[0]["sThum"].num=event.window_width
app.get_object_by_id("@scrollbar:vertical")[0]["sThum"].num=event.window_height
}
}

[unsafe]
fn keydown_fn(c gg.KeyCode, m gg.Modifier, mut app &Window){
//super := m == .super
Expand Down
68 changes: 68 additions & 0 deletions scrollbar.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module mui

import gg
import gx

const (
scrollbar_size=15
)

[unsafe]
fn update_scroll_hor(event_details EventDetails, mut app &Window, app_data voidptr){
unsafe{
app.scroll_x=event_details.value.int()
}
}

[unsafe]
fn update_scroll_ver(event_details EventDetails, mut app &Window, app_data voidptr){
unsafe{
app.scroll_y=event_details.value.int()
}
}

pub fn add_scrollbar(mut app &Window, val int, min int, max int, step int, sthum int, id string, x string|int, y string|int, w string|int, h string|int, vert bool, hi bool, bg gx.Color, bfg gx.Color, fg gx.Color, fnclk OnEvent, fnchg OnEvent, fnucl OnEvent){
app.objects << {
"type": WindowData{str:"scrollbar"},
"id": WindowData{str:id},
"val": WindowData{num:val-(val-min)%step},
"vlMin":WindowData{num:min},
"vlMax":WindowData{num:max-(max-min)%step},
"vStep":WindowData{num:step},
"sThum":WindowData{num:sthum},
"x": WindowData{num:0},
"y": WindowData{num:0},
"w": WindowData{num:0},
"h": WindowData{num:0},
"x_raw":WindowData{str: match x{ int{ x.str() } string{ x } } },
"y_raw":WindowData{str: match y{ int{ y.str() } string{ y } } },
"w_raw":WindowData{str: match w{ int{ w.str() } string{ w } } },
"h_raw":WindowData{str: match h{ int{ h.str() } string{ h } } },
"vert": WindowData{bol:vert},
"hi": WindowData{bol:hi},
"bg": WindowData{clr:bg},
"bfg": WindowData{clr:bfg},
"fg": WindowData{clr:fg},
"click":WindowData{bol:false},
"fnclk":WindowData{fun:fnclk},
"fnchg":WindowData{fun:fnchg},
"fnucl":WindowData{fun:fnucl}
}
}

[unsafe]
fn draw_scrollbar(app &Window, object map[string]WindowData){
unsafe{
if !object["vert"].bol {
app.gg.draw_rect_filled(object["x"].num, object["y"].num, object["w"].num, object["h"].num, object["bg"].clr)
thumb_size:=int(f32(object["sThum"].num-object["vlMin"].num)/f32(object["vlMax"].num-object["vlMin"].num)*object["w"].num)
width_of_thumb:=int(f32(object["w"].num-thumb_size)/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num)*(f32(object["val"].num-object["vlMin"].num)/object["vStep"].num))
app.gg.draw_rect_filled(object["x"].num+width_of_thumb, object["y"].num, thumb_size, object["h"].num, object["bfg"].clr)
} else {
app.gg.draw_rect_filled(object["x"].num, object["y"].num, object["w"].num, object["h"].num, object["bg"].clr)
thumb_size:=int(f32(object["sThum"].num-object["vlMin"].num)/f32(object["vlMax"].num-object["vlMin"].num)*object["h"].num)
height_of_thumb:=int(f32(object["h"].num-thumb_size)/(f32(object["vlMax"].num-object["vlMin"].num)/object["vStep"].num)*(f32(object["val"].num-object["vlMin"].num)/object["vStep"].num))
app.gg.draw_rect_filled(object["x"].num, object["y"].num+height_of_thumb, object["w"].num, thumb_size, object["bfg"].clr)
}
}
}
Loading

0 comments on commit bab15ca

Please sign in to comment.