More progress on themes + workspace resize handles support
Still need to add support for centered resize of boxes with the handles. (Will need a different alignment configuration) Theme manipulation is getting cleaned up iteratively code is slowly looking less nosiy
This commit is contained in:
@ -81,8 +81,7 @@ ui_hbox_end_auto :: proc( hbox : UI_HBox ) {
|
||||
UI_Resizable :: struct {
|
||||
using widget : UI_Widget,
|
||||
handle_width : f32,
|
||||
color_non_default : Color,
|
||||
color_default : Color,
|
||||
theme : ^UI_Theme,
|
||||
left : bool,
|
||||
right : bool,
|
||||
top : bool,
|
||||
@ -95,9 +94,8 @@ UI_Resizable :: struct {
|
||||
}
|
||||
|
||||
ui_resizable_begin :: proc( label : string, flags : UI_BoxFlags = {},
|
||||
handle_width : f32 = 15,
|
||||
handle_color_non_default : Color = Color_ResizeHandle,
|
||||
handle_color_default : Color = Color_Transparent,
|
||||
handle_width : f32 = 15,
|
||||
theme : ^UI_Theme,
|
||||
left := true,
|
||||
right := true,
|
||||
top := true,
|
||||
@ -111,18 +109,17 @@ ui_resizable_begin :: proc( label : string, flags : UI_BoxFlags = {},
|
||||
resizable.box = ui_box_make(flags, label)
|
||||
resizable.signal = ui_signal_from_box(resizable.box)
|
||||
|
||||
resizable.handle_width = handle_width
|
||||
resizable.color_non_default = handle_color_non_default
|
||||
resizable.color_default = handle_color_default
|
||||
resizable.left = left
|
||||
resizable.right = right
|
||||
resizable.top = top
|
||||
resizable.bottom = bottom
|
||||
resizable.corner_tr = corner_tr
|
||||
resizable.corner_tl = corner_tl
|
||||
resizable.corner_br = corner_br
|
||||
resizable.corner_bl = corner_bl
|
||||
resizable.compute_layout = compute_layout
|
||||
resizable.handle_width = handle_width
|
||||
resizable.theme = theme
|
||||
resizable.left = left
|
||||
resizable.right = right
|
||||
resizable.top = top
|
||||
resizable.bottom = bottom
|
||||
resizable.corner_tr = corner_tr
|
||||
resizable.corner_tl = corner_tl
|
||||
resizable.corner_br = corner_br
|
||||
resizable.corner_bl = corner_bl
|
||||
resizable.compute_layout = compute_layout
|
||||
return
|
||||
}
|
||||
|
||||
@ -130,8 +127,7 @@ ui_resizable_end :: proc( resizable : ^UI_Resizable, pos, size : ^Vec2 ) {
|
||||
using resizable
|
||||
ui_resizable_handles( & widget, pos, size,
|
||||
handle_width,
|
||||
color_non_default,
|
||||
color_default,
|
||||
theme,
|
||||
left,
|
||||
right,
|
||||
top,
|
||||
@ -154,9 +150,8 @@ ui_resizable_end_auto :: proc() {
|
||||
// Adds resizable handles to a widget
|
||||
// TODO(Ed): Add centered resize support (use center alignment on shift-click)
|
||||
ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
|
||||
handle_width : f32 = 15,
|
||||
handle_color_non_default : Color = Color_ResizeHandle,
|
||||
handle_color_default : Color = Color_Transparent,
|
||||
handle_width : f32 = 15,
|
||||
theme : ^UI_Theme = nil,
|
||||
left := true,
|
||||
right := true,
|
||||
top := true,
|
||||
@ -176,72 +171,114 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
|
||||
handle_corner_tl : UI_Widget
|
||||
handle_corner_br : UI_Widget
|
||||
handle_corner_bl : UI_Widget
|
||||
|
||||
ui_parent(parent)
|
||||
flags := UI_BoxFlags { .Mouse_Clickable, .Focusable }
|
||||
|
||||
layout_bar_width := UI_Layout {
|
||||
flags = { .Fixed_Width },
|
||||
alignment = {1, 0},
|
||||
margins = { handle_width, handle_width, 0, 0 },
|
||||
size = range2({handle_width, 0}, {}),
|
||||
@(deferred_none = ui_theme_pop)
|
||||
theme_handle :: proc( base : ^UI_Theme, margins, size : Vec2, flags : UI_LayoutFlags = {})
|
||||
{
|
||||
layout_combo : UI_LayoutCombo
|
||||
style_combo : UI_StyleCombo
|
||||
if base != nil
|
||||
{
|
||||
layout_combo = base.layout
|
||||
style_combo = base.style
|
||||
{
|
||||
layout_combo.default.margins = {margins.x, margins.x, margins.y, margins.y}
|
||||
layout_combo.default.size.min = size
|
||||
}
|
||||
{
|
||||
layout_combo.hot.margins = {margins.x, margins.x, margins.y, margins.y}
|
||||
layout_combo.hot.size.min = size
|
||||
}
|
||||
{
|
||||
layout_combo.active.margins = {margins.x, margins.x, margins.y, margins.y}
|
||||
layout_combo.active.size.min = size
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
layout := UI_Layout {
|
||||
flags = flags,
|
||||
anchor = range2({},{}),
|
||||
alignment = {0, 0},
|
||||
text_alignment = {0.0, 0.0},
|
||||
font_size = 16,
|
||||
margins = to_ui_layout_side(margins),
|
||||
padding = {0, 0, 0, 0},
|
||||
border_width = 0,
|
||||
pos = {0, 0},
|
||||
size = range2(size,{})
|
||||
}
|
||||
style := UI_Style {
|
||||
bg_color = Color_Transparent,
|
||||
border_color = Color_Transparent,
|
||||
corner_radii = {5, 0, 0, 0},
|
||||
blur_size = 0,
|
||||
font = get_state().default_font,
|
||||
text_color = Color_ThmDark_Text_Default,
|
||||
cursor = {},
|
||||
}
|
||||
layout_combo = to_ui_layout_combo(layout)
|
||||
style_combo = to_ui_style_combo(style)
|
||||
{
|
||||
using layout_combo.hot
|
||||
using style_combo.hot
|
||||
bg_color = Color_ThmDark_ResizeHandle_Hot
|
||||
}
|
||||
{
|
||||
using layout_combo.active
|
||||
using style_combo.active
|
||||
bg_color = Color_ThmDark_ResizeHandle_Active
|
||||
}
|
||||
}
|
||||
theme := UI_Theme {
|
||||
layout_combo, style_combo
|
||||
}
|
||||
ui_layout_push(theme.layout)
|
||||
ui_style_push(theme.style)
|
||||
}
|
||||
style_bar := UI_Style {
|
||||
bg_color = Color_ResizeHandle,
|
||||
corner_radii = { 5, 0, 0, 0 }
|
||||
}
|
||||
theme_bar := to_ui_style_combo(style_bar)
|
||||
theme_bar.default.bg_color = handle_color_default
|
||||
theme_bar.default.corner_radii[0] = 0
|
||||
ui_layout(layout_bar_width)
|
||||
ui_style(theme_bar)
|
||||
layout_bar_height := layout_bar_width
|
||||
layout_bar_height.flags = {.Fixed_Height}
|
||||
layout_bar_height.size.min = {0, handle_width}
|
||||
layout_bar_height.margins = { 0, 0, handle_width, handle_width }
|
||||
layout_bar_height.alignment = {0, -1}
|
||||
|
||||
context.user_ptr = & parent.label
|
||||
name :: proc( ) -> StrRunesPair {
|
||||
flags := UI_BoxFlags { .Mouse_Clickable }
|
||||
|
||||
name :: proc( label : string ) -> string {
|
||||
parent_label := (transmute(^string) context.user_ptr) ^
|
||||
return str_intern(str_fmt_tmp("%v: %v", ))
|
||||
return str_intern(str_fmt_alloc("%v: %v", parent_label, label )).str
|
||||
}
|
||||
context.user_ptr = & parent.label
|
||||
|
||||
if left do handle_left = ui_widget("Settings Menu: Resize Left Handle", flags )
|
||||
#region("Handle & Corner construction")
|
||||
theme_handle( theme, {handle_width, 0}, {handle_width,0})
|
||||
if left {
|
||||
handle_left = ui_widget(name("resize_handle_left"), flags )
|
||||
handle_left.layout.anchor.left = 0
|
||||
handle_left.layout.anchor.right = 1
|
||||
handle_left.layout.alignment = {1, 0}
|
||||
}
|
||||
if right {
|
||||
handle_right = ui_widget("Settings Menu: Resize Right Handle", flags)
|
||||
handle_right = ui_widget(name("resize_handle_right"), flags )
|
||||
handle_right.layout.anchor.left = 1
|
||||
handle_right.layout.alignment = { 0, 0 }
|
||||
}
|
||||
|
||||
ui_layout(layout_bar_height)
|
||||
ui_style_ref().default.bg_color = handle_color_default
|
||||
if top do handle_top = ui_widget("Settings Menu: Resize Top Border", flags )
|
||||
theme_handle( theme, {0, handle_width}, {0, handle_width})
|
||||
if top {
|
||||
handle_top = ui_widget(name("resize_handle_top"), flags )
|
||||
handle_top.layout.anchor.bottom = 1
|
||||
handle_top.layout.alignment = {0, -1}
|
||||
}
|
||||
if bottom {
|
||||
handle_bottom = ui_widget("Settings Menu: Resize Bottom Border", flags)
|
||||
using handle_bottom.layout
|
||||
anchor.top = 1
|
||||
alignment = { 0, 0 }
|
||||
handle_bottom = ui_widget("resize_handle_bottom", flags)
|
||||
handle_bottom.layout.anchor.top = 1
|
||||
handle_bottom.layout.alignment = { 0, 0 }
|
||||
}
|
||||
|
||||
layout_corner := UI_Layout {
|
||||
flags = { .Fixed_Width, .Fixed_Height },
|
||||
alignment = {1, -1},
|
||||
size = range2({handle_width, handle_width}, {}),
|
||||
theme_handle( theme, {0,0}, {handle_width, handle_width}, {.Fixed_Width, .Fixed_Height} )
|
||||
if corner_tl {
|
||||
handle_corner_tl = ui_widget(name("corner_top_left"), flags)
|
||||
handle_corner_tl.layout.alignment = {1, -1}
|
||||
}
|
||||
style_corner := UI_Style {
|
||||
bg_color = Color_ResizeHandle,
|
||||
corner_radii = { 5, 0, 0, 0 },
|
||||
}
|
||||
ui_theme(layout_corner, style_corner)
|
||||
ui_style_ref().default.bg_color = handle_color_default
|
||||
if corner_tl do handle_corner_tl = ui_widget("Settings Menu: Corner TL", flags)
|
||||
if corner_tr {
|
||||
handle_corner_tr = ui_widget("Settings Menu: Corner TR", flags)
|
||||
handle_corner_tr = ui_widget(name("corner_top_right"), flags)
|
||||
handle_corner_tr.layout.anchor = range2({1, 0}, {})
|
||||
handle_corner_tr.layout.alignment = {0, -1}
|
||||
}
|
||||
|
||||
if corner_bl {
|
||||
handle_corner_bl = ui_widget("Settings Menu: Corner BL", flags)
|
||||
handle_corner_bl.layout.anchor = range2({}, {0, 1})
|
||||
@ -252,27 +289,42 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
|
||||
handle_corner_br.layout.anchor = range2({1, 0}, {0, 1})
|
||||
handle_corner_br.layout.alignment = {0, 0}
|
||||
}
|
||||
#endregion("Handle & Corner construction")
|
||||
|
||||
process_handle_drag :: #force_inline proc ( handle : ^UI_Widget,
|
||||
direction : Vec2,
|
||||
size_delta : Vec2,
|
||||
target_alignment : Vec2,
|
||||
target_center_aligned : Vec2,
|
||||
pos : ^Vec2,
|
||||
size : ^Vec2,
|
||||
alignment : ^Vec2, ) -> b32
|
||||
{
|
||||
ui := get_state().ui_context
|
||||
if ui.last_pressed_key != handle.key { return false }
|
||||
@static active_context : ^UI_State
|
||||
@static was_dragging : b32 = false
|
||||
@static start_size : Vec2
|
||||
|
||||
size_delta := size_delta
|
||||
ui := get_state().ui_context
|
||||
if ui.last_pressed_key != handle.key do return false
|
||||
using handle
|
||||
|
||||
direction := direction
|
||||
target_alignment := target_alignment
|
||||
|
||||
size_delta := ui_drag_delta()
|
||||
pos_adjust := size^ * (alignment^ - target_alignment)
|
||||
|
||||
@static was_dragging : b32 = false
|
||||
|
||||
using handle
|
||||
if active
|
||||
{
|
||||
size^ += size_delta * direction
|
||||
if pressed
|
||||
{
|
||||
active_context = ui
|
||||
start_size = size^
|
||||
if .Origin_At_Anchor_Center in parent.layout.flags {
|
||||
pos_adjust = size^ * 0.5 * direction
|
||||
}
|
||||
}
|
||||
size^ = start_size + size_delta * direction
|
||||
if pressed {
|
||||
pos^ -= pos_adjust
|
||||
}
|
||||
@ -283,26 +335,49 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2,
|
||||
}
|
||||
else if released && was_dragging
|
||||
{
|
||||
pos^ += pos_adjust
|
||||
alignment^ = target_alignment
|
||||
was_dragging = false
|
||||
// This needed to be added as for some reason, this was getting called in screen_ui even when we were resizing with a handle in a worksapce
|
||||
if active_context != ui do return false
|
||||
|
||||
if .Origin_At_Anchor_Center in parent.layout.flags {
|
||||
pos_adjust = size^ * 0.5 * direction
|
||||
}
|
||||
pos^ += pos_adjust
|
||||
alignment^ = target_alignment
|
||||
was_dragging = false
|
||||
start_size = 0
|
||||
active_context = ui
|
||||
}
|
||||
return was_dragging
|
||||
}
|
||||
|
||||
delta := get_state().input.mouse.delta
|
||||
state := get_state()
|
||||
delta := state.input.mouse.delta //state.ui_context == & state.screen_ui ? state.input.mouse.delta : ui_ws_drag_delta()
|
||||
alignment := & parent.layout.alignment
|
||||
|
||||
if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment )
|
||||
if left do drag_signal |= process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment )
|
||||
if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment )
|
||||
if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment )
|
||||
if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment )
|
||||
if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment )
|
||||
if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment )
|
||||
if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment )
|
||||
if .Origin_At_Anchor_Center in parent.layout.flags
|
||||
{
|
||||
if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0}, delta, { 0.5, 0}, {}, pos, size, alignment )
|
||||
if left do drag_signal |= process_handle_drag( & handle_left, {-1, 0}, delta, {-0.5, 0}, {}, pos, size, alignment )
|
||||
if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1}, delta, { 0, 0.5}, {}, pos, size, alignment )
|
||||
if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1}, delta, { 0, -0.5}, {}, pos, size, alignment )
|
||||
if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1}, delta, { 0.5, 0.5}, {}, pos, size, alignment )
|
||||
if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, {-1, 1}, delta, {-0.5, 0.5}, {}, pos, size, alignment )
|
||||
if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1}, delta, { 0.5, -0.5}, {}, pos, size, alignment )
|
||||
if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, {-1, -1}, delta, {-0.5, -0.5}, {}, pos, size, alignment )
|
||||
}
|
||||
else
|
||||
{
|
||||
if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, {}, pos, size, alignment )
|
||||
if left do drag_signal |= process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, {}, pos, size, alignment )
|
||||
if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1 }, delta, {0, -1}, {}, pos, size, alignment )
|
||||
if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 0}, {}, pos, size, alignment )
|
||||
if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, -1}, {}, pos, size, alignment )
|
||||
if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, -1}, {}, pos, size, alignment )
|
||||
if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 0}, {}, pos, size, alignment )
|
||||
if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 0}, {}, pos, size, alignment )
|
||||
}
|
||||
|
||||
ui_box_compute_layout(parent)
|
||||
if drag_signal && compute_layout do ui_box_compute_layout(parent)
|
||||
return
|
||||
}
|
||||
#endregion("Resizable")
|
||||
|
Reference in New Issue
Block a user