Last active
November 29, 2023 22:30
-
-
Save lazalong/6b15cfca6301b44b90baac54f6cbe79c to your computer and use it in GitHub Desktop.
Test code to rework the V file browser component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Test code to rework the file browser component. | |
NOTE: | |
- Some truct & fcts have '_LL' or '_ll' appended to differentiate them from existing ones. | |
They contain some changes to make the subwindow match the menubar style | |
- Multiple small changes to make the file browser more stylish | |
Issues in v.ui code IMO: | |
- The decoration is see subwindow.h in draw_device() is hard coded (ie gx.black) and can't be set | |
- The panel in the filebrowser is limited in height and truncates if there is too many lines. I didn't find yet where this is set. Help appreciated | |
- In FileBrowserParams, settings the Dirs to '/' will not show the content if you click on it. You need to use './'. At least on Windows. | |
- Unclear where the initialisation of the filebrowser_subwindow should happen | |
*/ | |
import ui | |
import ui.component as uic | |
import gx | |
import os | |
const ( | |
win_width = 800 | |
win_height = 600 | |
// See ui/src/menu.v | |
menu_bar_color = gx.rgb(230, 230, 230) | |
menu_bg_color = gx.rgb(240, 240, 240) | |
menu_bg_color_hover = gx.rgb(220, 220, 220) | |
menu_border_color = gx.rgb(123, 123, 123) | |
) | |
__global ( | |
g_filebrowser_subwindow_initialised bool | |
) | |
struct App { | |
mut: | |
window &ui.Window = unsafe { nil } | |
// line_numbers bool | |
default_text string = 'test test test' | |
default_text2 string = 'test2 test2 test2' | |
} | |
fn main() { | |
mut app := &App{ | |
window: 0 | |
} | |
g_filebrowser_subwindow_initialised = false | |
// dirs = dirs.map(os.real_path(it)) | |
dirs := 'D:/Documents/_Projects/_VLang/projects/30_Sample_FileMenu' | |
mut window := ui.window( | |
width: win_width | |
height: win_height | |
title: 'V UI Edit: ${dirs}' | |
native_message: false | |
mode: .resizable | |
on_init: init | |
// on_char: on_char | |
children: [ | |
] | |
layout: ui.column( | |
id: 'main' | |
spacing: 5 | |
children: [ | |
ui.column( | |
margin_: 0 | |
heights: [ui.compact, ui.compact, ui.stretch] | |
children: [ | |
uic.hideable_stack( | |
id: 'openfile' | |
layout: filebrowser_stack_ll( | |
// todo ?s | |
) | |
), | |
ui.menubar( | |
items: [ | |
ui.menuitem( | |
text: 'Open' | |
action: menu_open | |
), | |
ui.menuitem( | |
text: 'New' | |
action: menu_new | |
), | |
ui.menuitem( | |
text: 'Save' | |
action: menu_save | |
) | |
] | |
), | |
ui.textbox( | |
id: 'edit' | |
mode: .multiline | |
//height: 200 | |
bg_color: gx.Color{0, 0, 0, 128} | |
) | |
] | |
) | |
] | |
) | |
) | |
app.window = window | |
ui.run(window) | |
} | |
const ( | |
// filebrowser_subwindow_id_ll = '_sw_filebrowser' | |
newfilebrowser_subwindow_id_ll = '_sw_newfilebrowser' | |
) | |
@[params] | |
pub struct FileBrowserParams_LL { | |
id string | |
// dirs []string = ['..', os.expand_tilde_to_home('~'), './'] // TODO: just using '/' will not show the content when we click on it | |
dirs []string = ['..', './'] // TODO: just using '/' will not show the content when we click on it | |
text_ok string = 'Open' | |
text_cancel string = 'Cancel' | |
height int = int(ui.compact) | |
width int = int(ui.compact) | |
z_index int | |
folder_only bool | |
filter_types []string | |
with_fpath bool | |
hidden bool | |
bg_color gx.Color = gx.red // gx.hex(0xfcf4e4ff) | |
on_click_ok ui.ButtonFn = ui.ButtonFn(0) | |
on_click_cancel ui.ButtonFn = ui.ButtonFn(0) | |
} | |
@[params] | |
pub struct FileBrowserSubWindowParams_LL { | |
FileBrowserParams_LL | |
x int | |
y int | |
} | |
pub fn filebrowser_stack_ll(p FileBrowserParams_LL) &ui.Stack { | |
btn_cancel := ui.button( | |
id: ui.component_id(p.id, 'btn_cancel') | |
text: p.text_cancel | |
//radius: 5 | |
bg_color: menu_bg_color | |
z_index: 100 | |
on_click: p.on_click_cancel | |
) | |
mut btn_ok := ui.button( | |
id: ui.component_id(p.id, 'btn_ok') | |
text: p.text_ok | |
//radius: 5 | |
bg_color: menu_bg_color | |
z_index: 100 | |
on_click: p.on_click_ok | |
) | |
tv_layout := uic.dirtreeview_stack( | |
id: ui.component_id(p.id, 'tvd') | |
trees: p.dirs | |
folder_only: p.folder_only | |
filter_types: p.filter_types | |
bg_color: ui.transparent | |
) | |
mut children := [ | |
ui.Widget(ui.column( | |
id: ui.component_id(p.id, 'tvd_col') | |
scrollview: true | |
// heights: ui.compact | |
bg_color: p.bg_color | |
children: [tv_layout] | |
)), | |
ui.Widget(ui.row( | |
id: ui.component_id(p.id, 'btns_row') | |
widths: [ui.stretch, 50, ui.stretch, 50, ui.stretch] | |
heights: 20.0 | |
margin_: 5 | |
bg_color: menu_bar_color | |
children: [ui.spacing(), btn_ok, ui.spacing(), btn_cancel, ui.spacing()] | |
)), | |
] | |
if p.with_fpath { | |
tb := ui.textbox( | |
id: ui.component_id(p.id, 'tb'), | |
placeholder: 'File path...' | |
bg_color: gx.light_gray | |
) | |
children.insert(1, ui.Widget(tb)) | |
} | |
mut layout := ui.column( | |
id: ui.component_id(p.id, 'layout') | |
width: p.width | |
height: p.height | |
heights: if p.with_fpath { [ui.stretch, 20, 30] } else { [ui.stretch, 30] } | |
children: children | |
) | |
tv := uic.treeview_component(tv_layout) // TODO: consider making it a _LL one for testing | |
// The heart of the file browser ! | |
mut fb := &uic.FileBrowserComponent{ // TODO: consider making it a _LL one for testing | |
layout: layout | |
btn_ok: btn_ok | |
btn_cancel: btn_cancel | |
tv: tv | |
} | |
ui.component_connect(fb, layout, btn_ok, btn_cancel) | |
// TODO: Where would be logical place to call this? In init() doesn't work | |
if !g_filebrowser_subwindow_initialised { | |
println(' init menufile. Called only once...') | |
layout.on_init = menufile_init | |
g_filebrowser_subwindow_initialised = true | |
} | |
return layout | |
} | |
// see subwindow_filebrowser.v filebrowser_subwindow_add | |
fn create_filebrowser_subwindow(mut w ui.Window, p FileBrowserSubWindowParams_LL) { | |
// only once | |
if !ui.Layout(w).has_child_id(newfilebrowser_subwindow_id_ll) { | |
w.subwindows << ui.subwindow( | |
decoration: false // TODO: set to gray the rounded_rect_filled (see subwindow.h in draw_device() !!!) and - better a text 'Open file...' | |
id: newfilebrowser_subwindow_id_ll | |
x: p.x | |
y: p.y | |
layout: filebrowser_stack_ll(p.FileBrowserParams_LL) | |
) | |
} | |
} | |
fn menu_open(item &ui.MenuItem) { | |
println('Open') | |
// See subwindow_filebrowser.h newfilebrowser_subwindow_visible | |
w := item.menu.ui.window | |
mut s := w.get_or_panic[ui.SubWindow](newfilebrowser_subwindow_id_ll) | |
s.set_visible(s.hidden) | |
s.update_layout() | |
} | |
pub fn newfilebrowser_subwindow_close(w &ui.Window, id string) { | |
mut s := w.get_or_panic[ui.SubWindow](id) // i.e. newfilebrowser_subwindow_id_ll | |
s.set_visible(false) | |
s.update_layout() | |
} | |
fn menu_new(item &ui.MenuItem) { | |
println('New') | |
} | |
fn menu_save(item &ui.MenuItem) { | |
println('Save') | |
} | |
fn init(mut w &ui.Window) { | |
println('init()') | |
// Can't call create_filebrowser_subwindow() here | |
} | |
pub fn menufile_init(layout &ui.Stack) { | |
mut window := layout.ui.window | |
create_filebrowser_subwindow( | |
mut window, | |
FileBrowserSubWindowParams_LL { // TODO: Personally I prefer to put explicitly the struct that is set here.. not implicitly | |
id: newfilebrowser_subwindow_id_ll // ui.component_id_from(layout.id, 'fb') | |
folder_only: false | |
width: 400 | |
height: 300 | |
x: 50 | |
y: 50 | |
bg_color: menu_bg_color | |
on_click_ok: btn_open_ok | |
on_click_cancel: btn_open_cancel | |
} | |
) | |
} | |
fn btn_open_ok(b &ui.Button) { | |
println('ok') | |
fb := uic.filebrowser_component(b) | |
fi := fb.selected_full_title() | |
newfilebrowser_subwindow_close(b.ui.window, ui.component_parent_id(b.id)) | |
println('File/Folder to open: ${fb.selected_full_title()}') | |
// mut dtv := uic.treeview_component_from_id(b.ui.window, ui.component_id_from_by(b.id, 2, 'dtv')) | |
// mut mf := uic.menufile_component_from_id(b.ui.window, ui.component_parent_id_by(b.id, 2)) | |
// mf.folder_to_open = fb.selected_full_title() | |
// dtv.open_dir(mf.folder_to_open) | |
} | |
fn btn_open_cancel(b &ui.Button) { | |
println('cancel open') | |
newfilebrowser_subwindow_close(b.ui.window, ui.component_parent_id(b.id)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment