Skip to content

Commit

Permalink
Support scrollbar for list and table
Browse files Browse the repository at this point in the history
  • Loading branch information
malisipi committed Feb 1, 2023
1 parent 1e495b1 commit 2329691
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 52 deletions.
2 changes: 1 addition & 1 deletion events.v
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ fn click_fn(x f32, y f32, mb gg.MouseButton, mut app &Window) {
group["s"].num=which_item
group["fnchg"].fun(EventDetails{event:"value_change",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str, value:which_item.str()},mut app, mut app.app_data)
} "list" {
object["s"].num = int(y-object["y"].num) / int(object["height"].num / object["table"].tbl[0].len)
object["s"].num = int(y-object["y"].num+object["schsl"].num) / int(if object["row_h"].num==-1 { object["height"].num / object["table"].tbl[0].len } else {object["row_h"].num})
object["fnchg"].fun(EventDetails{event:"click",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str,value:object["s"].num.str()},mut app, mut app.app_data)
} "image", "map" {
object["fn"].fun(EventDetails{event:"click",trigger:"mouse_left",target_type:object["type"].str,target_id:object["id"].str,value:true.str()},mut app, mut app.app_data)
Expand Down
10 changes: 5 additions & 5 deletions examples/notepad.v
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ menubar:=[

mut app:=m.create(m.WindowConfig{ title:"Notepad - MUI Examples", width:400, height: 300, menubar:menubar, file_handler:load_file, ask_quit:true, app_data:&AppData{}, y_offset:25 })

app.button(m.Widget{ id:"open", x:"!& 0", y:"!& 25" width:25, height:25, text:open_file_emoji, onclick:load_file, icon:true})
app.button(m.Widget{ id:"save", x:"!& 30", y:"!& 25" width:25, height:25, text:save_file_emoji, onclick:save_file, icon:true})
app.switch(m.Widget{ id:"codefield", x:"!& 60", y:"!& 30" width:30, height:15, text:"Codefield", onchange:change_codefield})
app.slider(m.Widget{ id:"text_size", x:"!& 180", y:"!& 30" width:80, height:15, value_min:8, value_max:40, value:20, onclick:change_text_size, onchange:change_text_size, onunclick:change_text_size})
app.button(id:"open", x:"!& 0", y:"!& 25" width:25, height:25, text:open_file_emoji, onclick:load_file, icon:true)
app.button(id:"save", x:"!& 30", y:"!& 25" width:25, height:25, text:save_file_emoji, onclick:save_file, icon:true)
app.switch(id:"codefield", x:"!& 60", y:"!& 30" width:30, height:15, text:"Codefield", onchange:change_codefield)
app.slider(id:"text_size", x:"!& 180", y:"!& 30" width:80, height:15, value_min:8, value_max:40, value:20, onclick:change_text_size, onchange:change_text_size, onunclick:change_text_size)

app.textarea(m.Widget{ id:"textarea", x:0, y:0, width:"100%x -20", height:"100%y", placeholder:"Open/Drop a file to edit\nOr create a new file"})
app.textarea(id:"textarea", x:0, y:0, width:"100%x -20", height:"100%y", placeholder:"Open/Drop a file to edit\nOr create a new file")
app.scrollbar(id:"textarea_scrollbar", x:"# 0", y:"# 0", width: 20, height:"100%y", vertical:true, connected_widget:app.get_object_by_id("textarea")[0], value_min:0, value_max:250, value:0)

app.run()
13 changes: 13 additions & 0 deletions examples/scrollable_widgets.v
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import malisipi.mui as m

user_list:=[
["Sam", "Johnson", "29","United States"],
["Kate", "Williams","26","Canada" ],
["Hank", "Anderson","34","United States"],
["Nathan","Drake", "28","Canada" ]
]

mut app:=m.create(title:"MUI", scrollbar:true, width:800, height: 600 view_area:[1000,1000])

app.textarea(id:"textarea", x:20, y:20, width:160, height:200, text:"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20")
app.scrollbar(id:"textarea_scrollbar", x:180, y:20, width: 20, height:200, vertical:true, connected_widget:app.get_object_by_id("textarea")[0])

app.table(id:"table", table:user_list x:300, y:20, width:380, height:100, row_height:40)
app.scrollbar(id:"table_scrollbar", x:680, y:20, width: 20, height:100, vertical:true, connected_widget:app.get_object_by_id("table")[0])

app.list(id:"list", table:user_list x:300, y:220, width:380, height:100, row_height:40)
app.scrollbar(id:"list_scrollbar", x:680, y:220, width: 20, height:100, vertical:true, connected_widget:app.get_object_by_id("list")[0])

app.run()
44 changes: 31 additions & 13 deletions list.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module mui
import gg
import gx

pub fn add_list(mut app &Window, table [][]string, id string, x IntOrString, y IntOrString, w IntOrString, h IntOrString, hi bool, bg gx.Color, bfg gx.Color, fg gx.Color, frame string, zindex int, fnchg OnEvent, selected int, tSize int){
pub fn add_list(mut app &Window, table [][]string, id string, x IntOrString, y IntOrString, w IntOrString, h IntOrString, hi bool, bg gx.Color, bfg gx.Color, fg gx.Color, frame string, zindex int, fnchg OnEvent, selected int, tSize int, row_h int){
app.objects << {
"type": WindowData{str:"list"},
"table":WindowData{tbl:table},
Expand All @@ -24,7 +24,11 @@ pub fn add_list(mut app &Window, table [][]string, id string, x IntOrString, y I
"s": WindowData{num:selected},
"fg": WindowData{clr:fg},
"fnchg":WindowData{fun:fnchg},
"tSize":WindowData{num:tSize}
"tSize":WindowData{num:tSize},
"row_h":WindowData{num:row_h},
"schmx":WindowData{num:0},
"schvl":WindowData{num:0},
"schsl":WindowData{num:0}
}
}

Expand All @@ -34,21 +38,35 @@ fn draw_list(app &Window, object map[string]WindowData){
table:=object["table"].tbl
table_y:=table.len
table_x:=table[0].len
per_cell:=[object["w"].num/table_x,object["h"].num/table_y]
fit_inside_viewarea := object["row_h"].num==-1
per_cell:=[object["w"].num/table_x,if fit_inside_viewarea {object["h"].num/table_y} else {object["row_h"].num}]

mut scrolled_height := 0
if !fit_inside_viewarea {
max_height := table_y * object["row_h"].num
view_height := object["h"].num
if max_height > view_height && object["schvl"].num > 0{
scrolled_height = (max_height - view_height) * object["schmx"].num / object["schvl"].num
object["schsl"].num = scrolled_height
}
}

app.gg.draw_rect_filled(object["x"].num, object["y"].num, per_cell[0]*table_x, per_cell[1]*table_y, object["bg"].clr)

app.gg.draw_rect_filled(object["x"].num, object["y"].num + per_cell[1] * object["s"].num, per_cell[0]*table_x, per_cell[1], object["bfg"].clr)
if fit_inside_viewarea || ( (object["s"].num+1)*per_cell[1] > scrolled_height && object["s"].num*per_cell[1] < object["h"].num + scrolled_height ) {
app.gg.draw_rect_filled(object["x"].num, object["y"].num + per_cell[1] * object["s"].num - scrolled_height, per_cell[0]*table_x, per_cell[1]-1, object["bfg"].clr)
}

for wy,y_ in table{
for wx,x_ in y_{
app.gg.draw_rect_empty(object["x"].num+per_cell[0]*wx, object["y"].num+per_cell[1]*wy, per_cell[0], per_cell[1], object["bfg"].clr)
app.gg.draw_text(object["x"].num+per_cell[0]*wx+per_cell[0]/2, object["y"].num+per_cell[1]*wy+per_cell[1]/2, x_, gx.TextCfg{
color: object["fg"].clr
size: object["tSize"].num
align: .center
vertical_align: .middle
})
if fit_inside_viewarea || ( (wy+1)*per_cell[1] > scrolled_height && wy*per_cell[1] < object["h"].num + scrolled_height ) {
for wx,x_ in y_{
app.gg.draw_rect_empty(object["x"].num+per_cell[0]*wx+1, object["y"].num+per_cell[1]*wy+1 - scrolled_height, per_cell[0]-2, per_cell[1]-2, object["bfg"].clr)
app.gg.draw_text(object["x"].num+per_cell[0]*wx+per_cell[0]/2, object["y"].num+per_cell[1]*wy+per_cell[1]/2 - scrolled_height, x_, gx.TextCfg{
color: object["fg"].clr
size: object["tSize"].num
align: .center
vertical_align: .middle
})
}
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions mui.v
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn frame_fn(app &Window) {
if app.focus!="" { objects << get_object_by_id(app, app.focus) }
real_size:=app.gg.window_size()
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()
app.gg.scissor_rect(0, 0, real_size.width, real_size.height)
$if !dont_clip ? { app.gg.scissor_rect(0, 0, real_size.width, real_size.height) }

if app.active_dialog!="" {
objects=app.dialog_objects.clone()
Expand Down Expand Up @@ -116,7 +116,7 @@ fn frame_fn(app &Window) {
}
if object["x"].num+object["w"].num>=0 && object["y"].num+object["h"].num>=0
&& object["x"].num<=window_info[2] && object["y"].num<=window_info[3] && object["w"].num>0 && object["h"].num>0 {
app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num, object["h"].num)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num, object["h"].num) }
match object["type"].str{
"rect"{
draw_rect(app, object)
Expand All @@ -133,21 +133,21 @@ fn frame_fn(app &Window) {
}"password"{
draw_password(app, object)
}"checkbox"{
app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num) }
draw_checkbox(app, object)
}"switch"{
app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num) }
draw_switch(app, object)
}"selectbox"{
app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num, object["h"].num+800)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num, object["h"].num+800) }
draw_selectbox(app, object)
}"slider"{
app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num + 200)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num, object["y"].num, object["w"].num + 200, object["h"].num + 200) }
draw_slider(app, object)
}"link"{
draw_link(app, object)
}"radio"{
app.gg.scissor_rect(object["x"].num-1, object["y"].num-1, object["w"].num + 200, object["h"].num+2)
$if !dont_clip ? { app.gg.scissor_rect(object["x"].num-1, object["y"].num-1, object["w"].num + 200, object["h"].num+2) }
draw_radio(app, object)
}"group"{
draw_group(app, object)
Expand Down Expand Up @@ -179,7 +179,7 @@ fn frame_fn(app &Window) {
}
}
}
app.gg.scissor_rect(0, 0, real_size.width, real_size.height)
$if !dont_clip ? { app.gg.scissor_rect(0, 0, real_size.width, real_size.height) }
draw_focus(mut app)
if app.menubar!=[]map["string"]WindowData{} {
draw_menubar(mut app, real_size)
Expand Down
22 changes: 15 additions & 7 deletions scrollbar.v
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ pub fn add_scrollbar(mut app &Window, val int, min int, max int, step int, sthum
"id": WindowData{str:id},
"in": WindowData{str:frame},
"z_ind":WindowData{num:zindex},
"val": WindowData{num:val-(val-min)%step},
"vlMin":WindowData{num:min},
"vlMax":WindowData{num:max-(max-min)%step},
"vStep":WindowData{num:step},
"val": WindowData{num:if connected_object==null_object{val-(val-min)%step} else { 0 } },
"vlMin":WindowData{num:if connected_object==null_object{min} else { 0 } },
"vlMax":WindowData{num:if connected_object==null_object{max-(max-min)%step} else { 99999 } },
"vStep":WindowData{num:if connected_object==null_object{step} else { 1 }},
"sThum":WindowData{num:sthum},
"x": WindowData{num:0},
"y": WindowData{num:0},
Expand All @@ -57,7 +57,7 @@ pub fn add_scrollbar(mut app &Window, val int, min int, max int, step int, sthum
fn change_connected_object_viewarea(event_details EventDetails, mut window &Window, mut app_data voidptr){
unsafe {
// TODO: check "vert"
mut scrollbar:= window.get_object_by_id(event_details.target_id)[0]
mut scrollbar := window.get_object_by_id(event_details.target_id)[0]
scrollbar["cnObj"].lst[0]["schmx"].num = scrollbar["val"].num - scrollbar["vlMin"].num
scrollbar["cnObj"].lst[0]["schvl"].num = scrollbar["vlMax"].num - scrollbar["vlMin"].num
}
Expand All @@ -68,12 +68,20 @@ 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)
thumb_size:=if object["cnObj"].lst[0] == null_object {
int(f32(object["sThum"].num-object["vlMin"].num)/f32(object["vlMax"].num-object["vlMin"].num)*object["w"].num)
} else {
object["w"].num/4
}
width_of_thumb:=int(f32(object["w"].num-thumb_size)/(f32(object["vlMax"].num-object["sThum"].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)
thumb_size:=if object["cnObj"].lst[0] == null_object {
int(f32(object["sThum"].num-object["vlMin"].num)/f32(object["vlMax"].num-object["vlMin"].num)*object["h"].num)
} else {
object["h"].num/4
}
height_of_thumb:=int(f32(object["h"].num-thumb_size)/(f32(object["vlMax"].num-object["sThum"].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)
}
Expand Down
40 changes: 28 additions & 12 deletions table.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module mui
import gg
import gx

pub fn add_table(mut app &Window, table [][]string, id string, x IntOrString, y IntOrString, w IntOrString, h IntOrString, hi bool, bg gx.Color, bfg gx.Color, fg gx.Color, frame string, zindex int, tSize int){
pub fn add_table(mut app &Window, table [][]string, id string, x IntOrString, y IntOrString, w IntOrString, h IntOrString, hi bool, bg gx.Color, bfg gx.Color, fg gx.Color, frame string, zindex int, tSize int, row_h int){
app.objects << {
"type": WindowData{str:"table"},
"table":WindowData{tbl:table},
Expand All @@ -22,30 +22,46 @@ pub fn add_table(mut app &Window, table [][]string, id string, x IntOrString, y
"bg": WindowData{clr:bg},
"bfg": WindowData{clr:bfg},
"fg": WindowData{clr:fg},
"tSize":WindowData{num:tSize}
"tSize":WindowData{num:tSize},
"row_h":WindowData{num:row_h},
"schmx":WindowData{num:0},
"schvl":WindowData{num:0},
"schsl":WindowData{num:0}
}
}

[unsafe]
fn draw_table(app &Window, object map[string]WindowData){
unsafe{

table:=object["table"].tbl
table_y:=table.len
table_x:=table[0].len
per_cell:=[object["w"].num/table_x,object["h"].num/table_y]
fit_inside_viewarea := object["row_h"].num==-1
per_cell:=[object["w"].num/table_x,if fit_inside_viewarea {object["h"].num/table_y} else {object["row_h"].num}]

mut scrolled_height := 0
if !fit_inside_viewarea {
max_height := table_y * object["row_h"].num
view_height := object["h"].num
if max_height > view_height && object["schvl"].num > 0{
scrolled_height = (max_height - view_height) * object["schmx"].num / object["schvl"].num
object["schsl"].num = scrolled_height
}
}

app.gg.draw_rect_filled(object["x"].num, object["y"].num, per_cell[0]*table_x, per_cell[1]*table_y, object["bg"].clr)

for wy,y_ in table{
for wx,x_ in y_{
app.gg.draw_rect_empty(object["x"].num+per_cell[0]*wx, object["y"].num+per_cell[1]*wy, per_cell[0], per_cell[1], object["bfg"].clr)
app.gg.draw_text(object["x"].num+per_cell[0]*wx+per_cell[0]/2, object["y"].num+per_cell[1]*wy+per_cell[1]/2, x_, gx.TextCfg{
color: object["fg"].clr
size: object["tSize"].num
align: .center
vertical_align: .middle
})
if !fit_inside_viewarea && (wy+1)*per_cell[1] > scrolled_height && wy*per_cell[1] < object["h"].num + scrolled_height {
for wx,x_ in y_{
app.gg.draw_rect_empty(object["x"].num+per_cell[0]*wx+1, object["y"].num+per_cell[1]*wy+1 - scrolled_height, per_cell[0]-2, per_cell[1]-2, object["bfg"].clr)
app.gg.draw_text(object["x"].num+per_cell[0]*wx+per_cell[0]/2, object["y"].num+per_cell[1]*wy+per_cell[1]/2 - scrolled_height, x_, gx.TextCfg{
color: object["fg"].clr
size: object["tSize"].num
align: .center
vertical_align: .middle
})
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions textarea.v
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ pub fn add_textarea(mut app &Window, text string, id string, placeholder string,
[unsafe]
fn draw_textarea(app &Window, object map[string]WindowData){
unsafe{
line_count := object["text"].str.count("\n")
line_count := object["text"].str.count("\n") + 1
max_height := line_count * object["tSize"].num
view_height := object["h"].num - 16 - line_count * 4 / 3
view_height := object["h"].num - 8
mut scrolled_height := 0
if max_height > view_height && object["schvl"].num > 0{
scrolled_height = (max_height - view_height) * object["schmx"].num / object["schvl"].num
Expand All @@ -52,7 +52,7 @@ fn draw_textarea(app &Window, object map[string]WindowData){
the_text=object["ph"].str
}
for w,split_text in the_text.replace("\t"," ").split("\n"){
if 4+w*object["tSize"].num - scrolled_height > 0 && 4+w*object["tSize"].num - scrolled_height < object["h"].num {
if 4+(w+1)*object["tSize"].num - scrolled_height > 0 && 4+w*object["tSize"].num - scrolled_height < object["h"].num {
app.gg.draw_text(object["x"].num+4, object["y"].num+4+w*object["tSize"].num - scrolled_height, split_text, gx.TextCfg{
color: object["fg"].clr
mono: object["code"].bol
Expand All @@ -64,7 +64,7 @@ fn draw_textarea(app &Window, object map[string]WindowData){
}
} else {
for w,split_text in object["text"].str.replace("\t"," ").replace("\0",text_cursor).split("\n"){
if 4+w*object["tSize"].num - scrolled_height > 0 && 4+w*object["tSize"].num - scrolled_height < object["h"].num{
if 4+(w+1)*object["tSize"].num - scrolled_height > 0 && 4+w*object["tSize"].num - scrolled_height < object["h"].num{
app.gg.draw_text(object["x"].num+4, object["y"].num+4+w*object["tSize"].num - scrolled_height, split_text, gx.TextCfg{
color: object["fg"].clr
mono: object["code"].bol
Expand Down
1 change: 1 addition & 0 deletions types.v
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ pub mut:
frame string //= "" //in
z_index int //= 0 //z_ind
connected_widget map[string]WindowData = null_object //cnObj
row_height int = -1 //row_h
}

pub struct Modal {
Expand Down
4 changes: 2 additions & 2 deletions widgets.v
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ pub fn (mut app Window) area_graph ( args Widget ){ //dialog support not done
}

pub fn (mut app Window) table ( args Widget ){ //dialog support not done
add_table (mut app, args.table, args.id, args.x, args.y, args.width, args.height, args.hidden, app.color_scheme[0], app.color_scheme[2], app.color_scheme[3], args.frame, args.z_index, args.text_size)
add_table (mut app, args.table, args.id, args.x, args.y, args.width, args.height, args.hidden, app.color_scheme[0], app.color_scheme[2], app.color_scheme[3], args.frame, args.z_index, args.text_size, args.row_height)
}

pub fn (mut app Window) list ( args Widget ){ //dialog support not done
add_list (mut app, args.table, args.id, args.x, args.y, args.width, args.height, args.hidden, app.color_scheme[0], app.color_scheme[2], app.color_scheme[3], args.frame, args.z_index, args.onchange, args.selected, args.text_size)
add_list (mut app, args.table, args.id, args.x, args.y, args.width, args.height, args.hidden, app.color_scheme[0], app.color_scheme[2], app.color_scheme[3], args.frame, args.z_index, args.onchange, args.selected, args.text_size, args.row_height)
}

pub fn (mut app Window) group ( args Widget ){ //dialog support not done
Expand Down

0 comments on commit 2329691

Please sign in to comment.