mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
convergence & cleanup & simplification & fixes of tab drag/drop, panel rearranging
This commit is contained in:
@@ -153,6 +153,16 @@ dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs)
|
||||
return run_list;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
dr_dim_from_fstrs(DR_FStrList *fstrs)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, 0, fstrs);
|
||||
Vec2F32 dim = fruns.dim;
|
||||
scratch_end(scratch);
|
||||
return dim;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Top-Level API
|
||||
//
|
||||
|
||||
@@ -122,6 +122,7 @@ internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push);
|
||||
internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src);
|
||||
internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list);
|
||||
internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs);
|
||||
internal Vec2F32 dr_dim_from_fstrs(DR_FStrList *fstrs);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Top-Level API
|
||||
|
||||
+367
-367
@@ -4797,6 +4797,7 @@ rd_window_frame(void)
|
||||
UI_PrefHeight(main_height)
|
||||
UI_TextAlignment(main_text_align)
|
||||
{
|
||||
ui_state->tooltip_can_overflow_window = 1;
|
||||
ui_set_next_pref_width(ui_em(60.f, 1.f));
|
||||
ui_set_next_pref_height(ui_em(40.f, 1.f));
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
@@ -7257,7 +7258,7 @@ rd_window_frame(void)
|
||||
F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f);
|
||||
UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t)
|
||||
{
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key);
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key);
|
||||
ui_signal_from_box(site_box);
|
||||
}
|
||||
UI_Box *site_box_viz = &ui_nil_box;
|
||||
@@ -7265,16 +7266,14 @@ rd_window_frame(void)
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
UI_Column
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
UI_GroupKey(key)
|
||||
{
|
||||
ui_set_next_child_layout_axis(axis2_flip(axis));
|
||||
if(ui_key_match(key, ui_drop_hot_key()))
|
||||
{
|
||||
ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover)));
|
||||
}
|
||||
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawDropShadow|
|
||||
UI_BoxFlag_DrawBackgroundBlur, ui_key_zero());
|
||||
UI_BoxFlag_DrawBackgroundBlur|
|
||||
UI_BoxFlag_DrawHotEffects, ui_key_zero());
|
||||
}
|
||||
UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f))
|
||||
{
|
||||
@@ -7350,7 +7349,7 @@ rd_window_frame(void)
|
||||
F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f);
|
||||
UI_Rect(site_rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t)
|
||||
{
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key);
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key);
|
||||
ui_signal_from_box(site_box);
|
||||
}
|
||||
UI_Box *site_box_viz = &ui_nil_box;
|
||||
@@ -7358,16 +7357,14 @@ rd_window_frame(void)
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
UI_Column
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
UI_GroupKey(key)
|
||||
{
|
||||
ui_set_next_child_layout_axis(axis2_flip(split_axis));
|
||||
if(ui_key_match(key, ui_drop_hot_key()))
|
||||
{
|
||||
ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover)));
|
||||
}
|
||||
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawDropShadow|
|
||||
UI_BoxFlag_DrawBackgroundBlur, ui_key_zero());
|
||||
UI_BoxFlag_DrawBackgroundBlur|
|
||||
UI_BoxFlag_DrawHotEffects, ui_key_zero());
|
||||
}
|
||||
UI_Parent(site_box_viz) UI_WidthFill UI_HeightFill UI_Padding(ui_px(padding, 1.f))
|
||||
{
|
||||
@@ -7518,13 +7515,14 @@ rd_window_frame(void)
|
||||
target_rect_px.y0/content_rect_dim.y,
|
||||
target_rect_px.x1/content_rect_dim.x,
|
||||
target_rect_px.y1/content_rect_dim.y);
|
||||
B32 reset = (ws->frames_alive < 5 || is_changing_panel_boundaries);
|
||||
B32 reset = (ws->window_layout_reset || ws->frames_alive < 5 || is_changing_panel_boundaries);
|
||||
ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x0", panel->cfg), target_rect_pct.x0, .initial = target_rect_pct.x0, .reset = reset);
|
||||
ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y0", panel->cfg), target_rect_pct.y0, .initial = target_rect_pct.y0, .reset = reset);
|
||||
ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_x1", panel->cfg), target_rect_pct.x1, .initial = target_rect_pct.x1, .reset = reset);
|
||||
ui_anim(ui_key_from_stringf(ui_key_zero(), "panel_%p_y1", panel->cfg), target_rect_pct.y1, .initial = target_rect_pct.y1, .reset = reset);
|
||||
}
|
||||
}
|
||||
ws->window_layout_reset = 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
@@ -7598,6 +7596,8 @@ rd_window_frame(void)
|
||||
if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && view != &rd_nil_cfg && contains_2f32(panel_rect, ui_mouse()) && ui_key_match(ui_drop_hot_key(), ui_key_zero()))
|
||||
{
|
||||
F32 drop_site_dim_px = ceil_f32(ui_top_font_size()*7.f);
|
||||
drop_site_dim_px = Min(drop_site_dim_px, dim_2f32(panel_rect).v[panel->split_axis]/4.f);
|
||||
drop_site_dim_px = Max(drop_site_dim_px, ceil_f32(ui_top_font_size()*3.f));
|
||||
Vec2F32 drop_site_half_dim = v2f32(drop_site_dim_px/2, drop_site_dim_px/2);
|
||||
Vec2F32 panel_center = center_2f32(panel_rect);
|
||||
F32 corner_radius = ui_top_font_size()*0.5f;
|
||||
@@ -7666,24 +7666,22 @@ rd_window_frame(void)
|
||||
F32 site_open_t = ui_anim(ui_key_from_stringf(key, "open_t"), 1.f);
|
||||
UI_Rect(rect) UI_Squish(0.25f-0.25f*site_open_t) UI_Transparency(1-site_open_t)
|
||||
{
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite, key);
|
||||
site_box = ui_build_box_from_key(UI_BoxFlag_DropSite|UI_BoxFlag_DrawHotEffects, key);
|
||||
ui_signal_from_box(site_box);
|
||||
}
|
||||
UI_Box *site_box_viz = &ui_nil_box;
|
||||
UI_Parent(site_box) UI_WidthFill UI_HeightFill
|
||||
UI_GroupKey(key)
|
||||
UI_Parent(site_box) UI_WidthFill UI_HeightFill
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
UI_Column
|
||||
UI_Padding(ui_px(padding, 1.f))
|
||||
{
|
||||
ui_set_next_child_layout_axis(axis2_flip(split_axis));
|
||||
if(ui_key_match(key, ui_drop_hot_key()))
|
||||
{
|
||||
ui_set_next_palette(ui_build_palette(ui_top_palette(), .border = rd_rgba_from_theme_color(RD_ThemeColor_Hover)));
|
||||
}
|
||||
site_box_viz = ui_build_box_from_key(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawDropShadow|
|
||||
UI_BoxFlag_DrawBackgroundBlur, ui_key_zero());
|
||||
UI_BoxFlag_DrawBackgroundBlur|
|
||||
UI_BoxFlag_DrawHotEffects, ui_key_zero());
|
||||
}
|
||||
if(dir != Dir2_Invalid)
|
||||
{
|
||||
@@ -7767,16 +7765,11 @@ rd_window_frame(void)
|
||||
//////////////////////////
|
||||
//- rjf: build catch-all panel drop-site
|
||||
//
|
||||
B32 catchall_drop_site_hovered = 0;
|
||||
if(rd_drag_is_active() && ui_key_match(ui_key_zero(), ui_drop_hot_key()))
|
||||
UI_Key catchall_drop_site_key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg);
|
||||
UI_Rect(panel_rect)
|
||||
{
|
||||
UI_Rect(panel_rect)
|
||||
{
|
||||
UI_Key key = ui_key_from_stringf(ui_key_zero(), "catchall_drop_site_%p", panel->cfg);
|
||||
UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, key);
|
||||
ui_signal_from_box(catchall_drop_site);
|
||||
catchall_drop_site_hovered = ui_key_match(key, ui_drop_hot_key());
|
||||
}
|
||||
UI_Box *catchall_drop_site = ui_build_box_from_key(UI_BoxFlag_DropSite, catchall_drop_site_key);
|
||||
ui_signal_from_box(catchall_drop_site);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
@@ -8002,361 +7995,325 @@ rd_window_frame(void)
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: build tab bar
|
||||
//- rjf: compute tab build tasks
|
||||
//
|
||||
UI_Focus(UI_FocusKind_Off)
|
||||
typedef struct TabTask TabTask;
|
||||
struct TabTask
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
// rjf: types
|
||||
typedef struct DropSite DropSite;
|
||||
struct DropSite
|
||||
TabTask *next;
|
||||
RD_Cfg *tab;
|
||||
DR_FStrList fstrs;
|
||||
F32 tab_width;
|
||||
};
|
||||
TabTask *first_tab_task = 0;
|
||||
TabTask *last_tab_task = 0;
|
||||
U64 tab_task_count = 0;
|
||||
F32 tab_close_width_px = ui_top_font_size()*2.5f;
|
||||
{
|
||||
for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next)
|
||||
{
|
||||
F32 p;
|
||||
RD_Cfg *prev_view;
|
||||
};
|
||||
|
||||
// rjf: prep output data
|
||||
RD_Cfg *next_selected_tab = selected_tab;
|
||||
UI_Box *tab_bar_box = &ui_nil_box;
|
||||
U64 drop_site_count = panel->tabs.count+1;
|
||||
DropSite *drop_sites = push_array(scratch.arena, DropSite, drop_site_count);
|
||||
F32 drop_site_max_p = 0;
|
||||
U64 view_idx = 0;
|
||||
|
||||
// rjf: build
|
||||
UI_CornerRadius(0)
|
||||
{
|
||||
UI_Rect(tab_bar_rect) tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowY|UI_BoxFlag_ViewClampX|UI_BoxFlag_ViewScrollX|UI_BoxFlag_Clickable, "tab_bar_%p", panel->cfg);
|
||||
if(panel->tab_side == Side_Max)
|
||||
RD_Cfg *tab = n->v;
|
||||
if(rd_cfg_is_project_filtered(tab))
|
||||
{
|
||||
tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
TabTask *t = push_array(scratch.arena, TabTask, 1);
|
||||
t->tab = tab;
|
||||
t->fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size());
|
||||
t->tab_width = dr_dim_from_fstrs(&t->fstrs).x + tab_close_width_px + ui_top_font_size()*1.f;
|
||||
SLLQueuePush(first_tab_task, last_tab_task, t);
|
||||
tab_task_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: build tab bar container
|
||||
//
|
||||
UI_Box *tab_bar_box = &ui_nil_box;
|
||||
UI_CornerRadius(0) UI_Rect(tab_bar_rect)
|
||||
{
|
||||
tab_bar_box = ui_build_box_from_stringf(UI_BoxFlag_Clip|
|
||||
UI_BoxFlag_AllowOverflowY|
|
||||
UI_BoxFlag_ViewClampX|
|
||||
UI_BoxFlag_ViewScrollX|
|
||||
UI_BoxFlag_Clickable,
|
||||
"tab_bar_%p", panel->cfg);
|
||||
if(panel->tab_side == Side_Max)
|
||||
{
|
||||
tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = (tab_bar_rheight - tab_bar_vheight);
|
||||
}
|
||||
else
|
||||
{
|
||||
tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: determine tab drop site
|
||||
//
|
||||
B32 tab_drop_is_active = ui_key_match(ui_drop_hot_key(), catchall_drop_site_key);
|
||||
RD_Cfg *tab_drop_prev = &rd_nil_cfg;
|
||||
{
|
||||
F32 best_prev_distance_px = 1000000.f;
|
||||
TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg};
|
||||
F32 off = 0;
|
||||
for(TabTask *task = &start_boundary_tab_task; task != 0; task = task->next)
|
||||
{
|
||||
off += task->tab_width;
|
||||
Vec2F32 anchor_pt = v2f32(tab_bar_box->rect.x0 + off, tab_bar_box->rect.y1);
|
||||
F32 distance = length_2f32(sub_2f32(ui_mouse(), anchor_pt));
|
||||
if(distance < best_prev_distance_px)
|
||||
{
|
||||
tab_bar_box->view_off.y = tab_bar_box->view_off_target.y = 0;
|
||||
best_prev_distance_px = distance;
|
||||
tab_drop_prev = task->tab;
|
||||
}
|
||||
}
|
||||
UI_Parent(tab_bar_box) UI_PrefHeight(ui_pct(1, 0))
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: turn off drop visualization if this drag would be a no-op
|
||||
//
|
||||
if(tab_drop_is_active && rd_state->drag_drop_regs->panel == panel->cfg->id)
|
||||
{
|
||||
TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg};
|
||||
if(tab_drop_prev->id == rd_state->drag_drop_regs->view)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
F32 corner_radius = ui_em(0.6f, 1.f).value;
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
|
||||
// rjf: build tabs
|
||||
RD_Cfg *tab = &rd_nil_cfg;
|
||||
RD_Cfg *prev_tab = &rd_nil_cfg;
|
||||
UI_PrefWidth(ui_em(18.f, 0.5f))
|
||||
UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius)
|
||||
UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius)
|
||||
for(RD_CfgNode *tab_n = panel->tabs.first; tab_n != 0; tab_n = tab_n->next, view_idx += 1)
|
||||
tab_drop_is_active = 0;
|
||||
}
|
||||
if(tab_drop_is_active) for(TabTask *t = &start_boundary_tab_task; t != 0; t = t->next)
|
||||
{
|
||||
if(t->tab == tab_drop_prev && t->next != 0 && t->next->tab->id == rd_state->drag_drop_regs->view)
|
||||
{
|
||||
prev_tab = tab;
|
||||
tab = tab_n->v;
|
||||
temp_end(scratch);
|
||||
if(rd_cfg_is_project_filtered(tab)) { continue; }
|
||||
tab_drop_is_active = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: build tab bar contents
|
||||
//
|
||||
UI_Focus(UI_FocusKind_Off) UI_Parent(tab_bar_box) UI_Padding(ui_em(0.5f, 1.f)) UI_PrefHeight(ui_pct(1, 0))
|
||||
{
|
||||
F32 corner_radius = ui_top_font_size()*0.6f;
|
||||
TabTask start_boundary_tab_task = {first_tab_task, &rd_nil_cfg};
|
||||
UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius01(panel->tab_side == Side_Min ? 0 : corner_radius)
|
||||
UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius11(panel->tab_side == Side_Min ? 0 : corner_radius)
|
||||
for(TabTask *tab_task = &start_boundary_tab_task; tab_task != 0; tab_task = tab_task->next)
|
||||
{
|
||||
RD_Cfg *tab = tab_task->tab;
|
||||
|
||||
//- rjf: build tab
|
||||
DR_FStrList tab_fstrs = tab_task->fstrs;
|
||||
F32 tab_width_px = tab_task->tab_width;
|
||||
if(tab != &rd_nil_cfg) RD_RegsScope(.panel = panel->cfg->id, .view = tab->id)
|
||||
{
|
||||
// rjf: gather info for this tab
|
||||
B32 tab_is_selected = (tab == panel->selected_tab);
|
||||
|
||||
// rjf: if before this tab is the prev-view of the current tab drag,
|
||||
// draw empty space
|
||||
if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && catchall_drop_site_hovered)
|
||||
// rjf: begin vertical region for this tab
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
ui_set_next_pref_width(ui_px(tab_width_px, 1));
|
||||
UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab);
|
||||
|
||||
// rjf: choose palette
|
||||
B32 omit_name = 0;
|
||||
RD_PaletteCode palette_code = RD_PaletteCode_TabInactive;
|
||||
if(tab_is_selected)
|
||||
{
|
||||
#if 0 // TODO(rjf): @cfg_dragdrop
|
||||
RD_Panel *dst_panel = rd_panel_from_handle(rd_last_drag_drop_panel);
|
||||
RD_View *drag_view = rd_view_from_handle(rd_state->drag_drop_regs->view);
|
||||
RD_View *dst_prev_view = rd_view_from_handle(rd_last_drag_drop_prev_tab);
|
||||
if(dst_panel == panel &&
|
||||
((!rd_view_is_nil(view) && dst_prev_view == view->order_prev && drag_view != view && drag_view != view->order_prev) ||
|
||||
(rd_view_is_nil(view) && dst_prev_view == panel->last_tab_view && drag_view != panel->last_tab_view)))
|
||||
palette_code = RD_PaletteCode_Tab;
|
||||
}
|
||||
if(rd_drag_is_active() && rd_state->drag_drop_regs->view == tab->id && rd_state->drag_drop_regs_slot == RD_RegSlot_View)
|
||||
{
|
||||
palette_code = RD_PaletteCode_DropSiteOverlay;
|
||||
omit_name = 1;
|
||||
}
|
||||
|
||||
// rjf: build tab container box
|
||||
UI_Parent(tab_column_box)
|
||||
UI_PrefHeight(ui_px(tab_bar_vheight, 1))
|
||||
RD_Palette(palette_code)
|
||||
{
|
||||
if(panel->tab_side == Side_Max)
|
||||
{
|
||||
UI_PrefWidth(ui_em(9.f, 0.2f)) UI_Column
|
||||
{
|
||||
ui_spacer(ui_em(0.2f, 1.f));
|
||||
UI_CornerRadius00(corner_radius)
|
||||
UI_CornerRadius10(corner_radius)
|
||||
RD_Palette(RD_PaletteCode_DropSiteOverlay)
|
||||
{
|
||||
ui_build_box_from_key(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, ui_key_zero());
|
||||
}
|
||||
}
|
||||
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// rjf: end on nil view
|
||||
if(tab == &rd_nil_cfg)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: build per-tab info
|
||||
RD_RegsScope(.panel = panel->cfg->id, .view = tab->id)
|
||||
{
|
||||
// rjf: gather info for this tab
|
||||
B32 view_is_selected = (tab == panel->selected_tab);
|
||||
DR_FStrList title_fstrs = rd_title_fstrs_from_cfg(scratch.arena, tab, ui_top_palette()->text_weak, ui_top_font_size());
|
||||
|
||||
// rjf: begin vertical region for this tab
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab);
|
||||
|
||||
// rjf: build tab container box
|
||||
UI_Parent(tab_column_box) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) RD_Palette(view_is_selected ? RD_PaletteCode_Tab : RD_PaletteCode_TabInactive)
|
||||
else
|
||||
{
|
||||
if(panel->tab_side == Side_Max)
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
(UI_BoxFlag_DrawDropShadow*tab_is_selected)|
|
||||
UI_BoxFlag_Clickable,
|
||||
"tab_%p", tab);
|
||||
|
||||
// rjf: build tab contents
|
||||
if(!omit_name) UI_Parent(tab_box)
|
||||
{
|
||||
UI_WidthFill UI_Row
|
||||
{
|
||||
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Box *tab_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
(UI_BoxFlag_DrawDropShadow*view_is_selected)|
|
||||
UI_BoxFlag_Clickable,
|
||||
"tab_%p", tab);
|
||||
|
||||
// rjf: build tab contents
|
||||
UI_Parent(tab_box)
|
||||
{
|
||||
UI_WidthFill UI_Row
|
||||
ui_spacer(ui_em(0.5f, 1.f));
|
||||
UI_PrefWidth(ui_text_dim(10, 0))
|
||||
{
|
||||
ui_spacer(ui_em(0.5f, 1.f));
|
||||
UI_PrefWidth(ui_text_dim(10, 0))
|
||||
{
|
||||
UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
|
||||
ui_box_equip_display_fstrs(name_box, &title_fstrs);
|
||||
}
|
||||
}
|
||||
UI_PrefWidth(ui_em(2.35f, 1.f)) UI_TextAlignment(UI_TextAlign_Center)
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f)
|
||||
UI_Flags(UI_BoxFlag_DrawTextWeak)
|
||||
UI_CornerRadius00(0)
|
||||
UI_CornerRadius01(0)
|
||||
{
|
||||
UI_Palette *palette = ui_build_palette(ui_top_palette());
|
||||
palette->background = v4f32(0, 0, 0, 0);
|
||||
ui_set_next_palette(palette);
|
||||
UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab);
|
||||
if(ui_clicked(sig) || ui_middle_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_CloseTab);
|
||||
}
|
||||
UI_Box *name_box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
|
||||
ui_box_equip_display_fstrs(name_box, &tab_fstrs);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: consume events for tab clicking
|
||||
UI_PrefWidth(ui_px(tab_close_width_px, 1.f)) UI_TextAlignment(UI_TextAlign_Center)
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Icons)*0.75f)
|
||||
UI_Flags(UI_BoxFlag_DrawTextWeak)
|
||||
UI_CornerRadius00(0)
|
||||
UI_CornerRadius01(0)
|
||||
{
|
||||
UI_Signal sig = ui_signal_from_box(tab_box);
|
||||
if(ui_pressed(sig))
|
||||
{
|
||||
next_selected_tab = tab;
|
||||
rd_cmd(RD_CmdKind_FocusPanel);
|
||||
}
|
||||
else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f)
|
||||
{
|
||||
rd_drag_begin(RD_RegSlot_View);
|
||||
}
|
||||
else if(ui_right_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_PushQuery,
|
||||
.reg_slot = RD_RegSlot_View,
|
||||
.ui_key = sig.box->key,
|
||||
.off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0),
|
||||
.lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings);
|
||||
}
|
||||
else if(ui_middle_clicked(sig))
|
||||
UI_Palette *palette = ui_build_palette(ui_top_palette());
|
||||
palette->background = v4f32(0, 0, 0, 0);
|
||||
ui_set_next_palette(palette);
|
||||
UI_Signal sig = ui_buttonf("%S###close_view_%p", rd_icon_kind_text_table[RD_IconKind_X], tab);
|
||||
if(ui_clicked(sig) || ui_middle_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_CloseTab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: space for next tab
|
||||
// rjf: consume events for tab clicking
|
||||
{
|
||||
ui_spacer(ui_em(0.3f, 1.f));
|
||||
}
|
||||
|
||||
// rjf: store off drop-site
|
||||
drop_sites[view_idx].p = tab_column_box->rect.x0 - tab_spacing/2;
|
||||
drop_sites[view_idx].prev_view = prev_tab;
|
||||
drop_site_max_p = Max(tab_column_box->rect.x1, drop_site_max_p);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: build add-new-tab button
|
||||
UI_TextAlignment(UI_TextAlign_Center)
|
||||
UI_PrefWidth(ui_px(tab_bar_vheight, 1.f))
|
||||
UI_PrefHeight(ui_px(tab_bar_vheight, 1.f))
|
||||
UI_Column
|
||||
{
|
||||
if(panel->tab_side == Side_Max)
|
||||
{
|
||||
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
}
|
||||
UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0)
|
||||
UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0)
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(ui_top_font_size())
|
||||
UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
|
||||
UI_HoverCursor(OS_Cursor_HandPoint)
|
||||
RD_Palette(RD_PaletteCode_ImplicitButton)
|
||||
{
|
||||
UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawText|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects|
|
||||
UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DisableTextTrunc,
|
||||
"%S##add_new_tab_button_%p",
|
||||
rd_icon_kind_text_table[RD_IconKind_Add],
|
||||
panel->cfg);
|
||||
UI_Signal sig = ui_signal_from_box(add_new_box);
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FocusPanel);
|
||||
UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_"));
|
||||
ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
// rjf: interact with tab bar
|
||||
ui_signal_from_box(tab_bar_box);
|
||||
|
||||
// rjf: fill out last drop site
|
||||
{
|
||||
drop_sites[drop_site_count-1].p = drop_site_max_p;
|
||||
drop_sites[drop_site_count-1].prev_view = rd_cfg_list_last(&panel->tabs);
|
||||
}
|
||||
|
||||
// rjf: more precise drop-sites on tab bar
|
||||
{
|
||||
Vec2F32 mouse = ui_mouse();
|
||||
RD_Cfg *drag_tab = rd_cfg_from_id(rd_state->drag_drop_regs->view);
|
||||
if(rd_drag_is_active() && rd_state->drag_drop_regs_slot == RD_RegSlot_View && window_is_focused && contains_2f32(panel_rect, mouse) && drag_tab != &rd_nil_cfg)
|
||||
{
|
||||
// rjf: mouse => hovered drop site
|
||||
F32 min_distance = 0;
|
||||
DropSite *active_drop_site = 0;
|
||||
if(catchall_drop_site_hovered)
|
||||
{
|
||||
for(U64 drop_site_idx = 0; drop_site_idx < drop_site_count; drop_site_idx += 1)
|
||||
{
|
||||
F32 distance = abs_f32(drop_sites[drop_site_idx].p - mouse.x);
|
||||
if(drop_site_idx == 0 || distance < min_distance)
|
||||
UI_Signal sig = ui_signal_from_box(tab_box);
|
||||
if(ui_pressed(sig))
|
||||
{
|
||||
active_drop_site = &drop_sites[drop_site_idx];
|
||||
min_distance = distance;
|
||||
rd_cmd(RD_CmdKind_FocusTab);
|
||||
rd_cmd(RD_CmdKind_FocusPanel);
|
||||
}
|
||||
else if(ui_dragging(sig) && !rd_drag_is_active() && length_2f32(ui_drag_delta()) > 10.f)
|
||||
{
|
||||
rd_drag_begin(RD_RegSlot_View);
|
||||
}
|
||||
else if(ui_right_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_PushQuery,
|
||||
.reg_slot = RD_RegSlot_View,
|
||||
.ui_key = sig.box->key,
|
||||
.off_px = v2f32(0, sig.box->rect.y1 - sig.box->rect.y0),
|
||||
.lister_flags = RD_ListerFlag_LineEdit|RD_ListerFlag_Commands|RD_ListerFlag_Settings);
|
||||
}
|
||||
else if(ui_middle_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_CloseTab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: store closest prev-view
|
||||
if(active_drop_site != 0)
|
||||
// rjf: space for next tab
|
||||
{
|
||||
rd_last_drag_drop_prev_tab = active_drop_site->prev_view->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
rd_last_drag_drop_prev_tab = 0;
|
||||
ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f));
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: if this is the currently active drop site's previous tab, then build empty space
|
||||
// to visualize where tab will be moved once dropped
|
||||
if(tab_drop_is_active &&
|
||||
rd_drag_is_active() &&
|
||||
rd_state->drag_drop_regs_slot == RD_RegSlot_View &&
|
||||
tab == tab_drop_prev)
|
||||
{
|
||||
// rjf: begin vertical region for this spot
|
||||
ui_set_next_child_layout_axis(Axis2_Y);
|
||||
ui_set_next_pref_width(ui_px(ui_top_font_size()*4.f, 1));
|
||||
UI_Box *tab_column_box = ui_build_box_from_stringf(!is_changing_panel_boundaries*UI_BoxFlag_AnimatePosX, "tab_column_%p", tab);
|
||||
|
||||
// rjf: vis
|
||||
if(drag_tab != &rd_nil_cfg && active_drop_site != 0)
|
||||
// rjf: build spot container box
|
||||
UI_Parent(tab_column_box)
|
||||
UI_PrefHeight(ui_px(tab_bar_vheight, 1))
|
||||
RD_Palette(RD_PaletteCode_DropSiteOverlay)
|
||||
{
|
||||
RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(tab_bar_rect)
|
||||
ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero());
|
||||
}
|
||||
|
||||
// rjf: drop
|
||||
if(catchall_drop_site_hovered && (active_drop_site != 0 && rd_drag_drop()))
|
||||
{
|
||||
RD_Cfg *drag_view = rd_cfg_from_id(rd_state->drag_drop_regs->view);
|
||||
RD_Cfg *src_panel = rd_cfg_from_id(rd_state->drag_drop_regs->panel);
|
||||
RD_Cfg *dst_panel = panel->cfg;
|
||||
if(dst_panel != &rd_nil_cfg && drag_view != &rd_nil_cfg)
|
||||
if(panel->tab_side == Side_Max)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_MoveTab,
|
||||
.panel = src_panel->id,
|
||||
.dst_panel = dst_panel->id,
|
||||
.view = drag_view->id,
|
||||
.prev_view = active_drop_site->prev_view->id);
|
||||
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
ui_set_next_group_key(catchall_drop_site_key);
|
||||
UI_Box *tab_box = ui_build_box_from_key(UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_Clickable,
|
||||
ui_key_zero());
|
||||
}
|
||||
|
||||
// rjf: space for next tab
|
||||
{
|
||||
ui_spacer(ui_px(floor_f32(ui_top_font_size()*0.4f), 1.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: apply tab change
|
||||
if(next_selected_tab != panel->selected_tab)
|
||||
// rjf: build add-new-tab button
|
||||
UI_TextAlignment(UI_TextAlign_Center)
|
||||
UI_PrefWidth(ui_px(tab_bar_vheight, 1.f))
|
||||
UI_PrefHeight(ui_px(tab_bar_vheight, 1.f))
|
||||
UI_Column
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FocusTab, .view = next_selected_tab->id);
|
||||
if(panel->tab_side == Side_Max)
|
||||
{
|
||||
ui_spacer(ui_px(tab_bar_rv_diff-1.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_spacer(ui_px(1.f, 1.f));
|
||||
}
|
||||
UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius10(panel->tab_side == Side_Min ? corner_radius : 0)
|
||||
UI_CornerRadius01(panel->tab_side == Side_Max ? corner_radius : 0)
|
||||
UI_CornerRadius11(panel->tab_side == Side_Max ? corner_radius : 0)
|
||||
RD_Font(RD_FontSlot_Icons)
|
||||
UI_FontSize(ui_top_font_size())
|
||||
UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
|
||||
UI_HoverCursor(OS_Cursor_HandPoint)
|
||||
RD_Palette(RD_PaletteCode_ImplicitButton)
|
||||
{
|
||||
UI_Box *add_new_box = ui_build_box_from_stringf(UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawText|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects|
|
||||
UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DisableTextTrunc,
|
||||
"%S##add_new_tab_button_%p",
|
||||
rd_icon_kind_text_table[RD_IconKind_Add],
|
||||
panel->cfg);
|
||||
UI_Signal sig = ui_signal_from_box(add_new_box);
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FocusPanel);
|
||||
UI_Key view_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_view_menu_key_"));
|
||||
ui_ctx_menu_open(view_menu_key, add_new_box->key, v2f32(0, tab_bar_vheight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
// rjf: interact with tab bar
|
||||
ui_signal_from_box(tab_bar_box);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: less granular panel-wide drop-site
|
||||
//- rjf: accept tab drops
|
||||
//
|
||||
if(catchall_drop_site_hovered)
|
||||
if(tab_drop_is_active && rd_drag_drop() && rd_state->drag_drop_regs_slot == RD_RegSlot_View)
|
||||
{
|
||||
#if 0 // TODO(rjf): @cfg_dragdrop
|
||||
rd_last_drag_drop_panel = rd_handle_from_panel(panel);
|
||||
|
||||
RD_View *dragged_view = rd_view_from_handle(rd_state->drag_drop_regs->view);
|
||||
B32 view_is_in_panel = 0;
|
||||
for(RD_View *view = panel->first_tab_view; !rd_view_is_nil(view); view = view->order_next)
|
||||
{
|
||||
if(rd_view_is_project_filtered(view)) { continue; }
|
||||
if(view == dragged_view)
|
||||
{
|
||||
view_is_in_panel = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(view_is_in_panel == 0)
|
||||
{
|
||||
// rjf: vis
|
||||
{
|
||||
RD_Palette(RD_PaletteCode_DropSiteOverlay) UI_Rect(content_rect)
|
||||
ui_build_box_from_key(UI_BoxFlag_DrawBackground, ui_key_zero());
|
||||
}
|
||||
|
||||
// rjf: drop
|
||||
{
|
||||
if(rd_drag_drop())
|
||||
{
|
||||
RD_Panel *src_panel = rd_panel_from_handle(rd_state->drag_drop_regs->panel);
|
||||
RD_View *view = rd_view_from_handle(rd_state->drag_drop_regs->view);
|
||||
if(rd_state->drag_drop_regs_slot == RD_RegSlot_View && !rd_view_is_nil(view))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_MoveTab,
|
||||
.prev_view = rd_handle_from_view(panel->last_tab_view),
|
||||
.panel = rd_handle_from_panel(src_panel),
|
||||
.dst_panel = rd_handle_from_panel(panel),
|
||||
.view = rd_handle_from_view(view));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rd_cmd(RD_CmdKind_MoveTab,
|
||||
.dst_panel = panel->cfg->id,
|
||||
.panel = rd_state->drag_drop_regs->panel,
|
||||
.view = rd_state->drag_drop_regs->view,
|
||||
.prev_view = tab_drop_prev->id);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
@@ -8646,7 +8603,7 @@ rd_window_frame(void)
|
||||
}
|
||||
|
||||
// rjf: soft circle around mouse
|
||||
if(ui_key_match(ui_hot_key(), box->key)) DR_ClipScope(box->rect)
|
||||
if(box->hot_t > 0.01f) DR_ClipScope(box->rect)
|
||||
{
|
||||
Vec2F32 center = ui_mouse();
|
||||
F32 radius = box->font_size*12.f;
|
||||
@@ -13197,6 +13154,12 @@ rd_frame(void)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FocusPanel, .panel = new_panel_cfg->id);
|
||||
}
|
||||
|
||||
// rjf: tabs on bottom on split panel? -> tabs on bottom on new panel
|
||||
if(panel->tab_side == Side_Max && split_axis == Axis2_X)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_TabBarBottom, .panel = new_panel_cfg->id);
|
||||
}
|
||||
}break;
|
||||
|
||||
//- rjf: panel rotation
|
||||
@@ -13628,20 +13591,47 @@ rd_frame(void)
|
||||
case RD_CmdKind_MoveTabRight:
|
||||
case RD_CmdKind_MoveTabLeft:
|
||||
{
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
RD_Window *ws = rd_window_from_handle(rd_regs()->window);
|
||||
RD_Panel *panel = ws->focused_panel;
|
||||
RD_View *view = rd_selected_tab_from_panel(panel);
|
||||
RD_View *prev_view = (kind == RD_CmdKind_MoveTabRight ? view->order_next : view->order_prev->order_prev);
|
||||
if(!rd_view_is_nil(prev_view) || kind == RD_CmdKind_MoveTabLeft)
|
||||
RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view);
|
||||
RD_Cfg *window = rd_window_from_cfg(tab);
|
||||
RD_PanelTree panel_tree = rd_panel_tree_from_cfg(scratch.arena, window);
|
||||
RD_PanelNode *panel = rd_panel_node_from_tree_cfg(panel_tree.root, tab->parent);
|
||||
RD_CfgList filtered_tabs = {0};
|
||||
for(RD_CfgNode *n = panel->tabs.first; n != 0; n = n->next)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_MoveTab,
|
||||
.panel = rd_handle_from_panel(panel),
|
||||
.dst_panel = rd_handle_from_panel(panel),
|
||||
.view = rd_handle_from_view(view),
|
||||
.prev_view = rd_handle_from_view(prev_view));
|
||||
if(rd_cfg_is_project_filtered(n->v))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
rd_cfg_list_push(scratch.arena, &filtered_tabs, n->v);
|
||||
}
|
||||
#endif
|
||||
RD_Cfg *tab_prev2 = &rd_nil_cfg;
|
||||
RD_Cfg *tab_prev = &rd_nil_cfg;
|
||||
RD_Cfg *tab_next = &rd_nil_cfg;
|
||||
{
|
||||
RD_Cfg *prev2 = &rd_nil_cfg;
|
||||
RD_Cfg *prev = &rd_nil_cfg;
|
||||
RD_Cfg *next = &rd_nil_cfg;
|
||||
for(RD_CfgNode *n = filtered_tabs.first; n != 0; (prev2 = prev, prev = n->v, n = n->next))
|
||||
{
|
||||
next = n->next ? n->next->v : &rd_nil_cfg;
|
||||
if(n->v == tab)
|
||||
{
|
||||
tab_prev2 = prev2;
|
||||
tab_prev = prev;
|
||||
tab_next = next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RD_Cfg *new_prev = (kind == RD_CmdKind_MoveTabRight ? tab_next : tab_prev2);
|
||||
if(new_prev == tab_prev && filtered_tabs.last)
|
||||
{
|
||||
new_prev = filtered_tabs.last->v;
|
||||
}
|
||||
rd_cmd(RD_CmdKind_MoveTab,
|
||||
.dst_panel = panel->cfg->id,
|
||||
.view = tab->id,
|
||||
.prev_view = new_prev->id);
|
||||
}break;
|
||||
case RD_CmdKind_OpenTab:
|
||||
{
|
||||
@@ -13681,34 +13671,37 @@ rd_frame(void)
|
||||
}break;
|
||||
case RD_CmdKind_MoveTab:
|
||||
{
|
||||
#if 0 // TODO(rjf): @cfg
|
||||
RD_Window *ws = rd_window_from_handle(rd_regs()->window);
|
||||
RD_Panel *src_panel = rd_panel_from_handle(rd_regs()->panel);
|
||||
RD_View *view = rd_view_from_handle(rd_regs()->view);
|
||||
RD_Panel *dst_panel = rd_panel_from_handle(rd_regs()->dst_panel);
|
||||
RD_View *prev_view = rd_view_from_handle(rd_regs()->prev_view);
|
||||
if(!rd_panel_is_nil(src_panel) &&
|
||||
!rd_panel_is_nil(dst_panel) &&
|
||||
prev_view != view)
|
||||
RD_Cfg *tab = rd_cfg_from_id(rd_regs()->view);
|
||||
RD_Cfg *prev_tab = rd_cfg_from_id(rd_regs()->prev_view);
|
||||
RD_Cfg *src_panel = tab->parent;
|
||||
RD_Cfg *dst_panel = rd_cfg_from_id(rd_regs()->dst_panel);
|
||||
if(dst_panel != &rd_nil_cfg && prev_tab != tab)
|
||||
{
|
||||
rd_panel_remove_tab_view(src_panel, view);
|
||||
rd_panel_insert_tab_view(dst_panel, prev_view, view);
|
||||
ws->focused_panel = dst_panel;
|
||||
B32 src_panel_is_empty = 1;
|
||||
for(RD_View *v = src_panel->first_tab_view; !rd_view_is_nil(v); v = v->order_next)
|
||||
rd_cfg_unhook(src_panel, tab);
|
||||
rd_cfg_insert_child(dst_panel, prev_tab, tab);
|
||||
rd_cmd(RD_CmdKind_FocusTab, .panel = dst_panel->id, .view = tab->id);
|
||||
rd_cmd(RD_CmdKind_FocusPanel, .panel = dst_panel->id);
|
||||
RD_PanelTree src_panel_tree = rd_panel_tree_from_cfg(scratch.arena, src_panel);
|
||||
RD_PanelNode *src_panel_node = rd_panel_node_from_tree_cfg(src_panel_tree.root, src_panel);
|
||||
B32 src_panel_is_empty = 0;
|
||||
if(src_panel != dst_panel)
|
||||
{
|
||||
if(!rd_view_is_project_filtered(v))
|
||||
src_panel_is_empty = 1;
|
||||
for(RD_CfgNode *n = src_panel_node->tabs.first; n != 0; n = n->next)
|
||||
{
|
||||
src_panel_is_empty = 0;
|
||||
break;
|
||||
if(!rd_cfg_is_project_filtered(n->v))
|
||||
{
|
||||
rd_cmd(RD_CmdKind_FocusTab, .panel = src_panel->id, .view = n->v->id);
|
||||
src_panel_is_empty = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(src_panel_is_empty && src_panel != ws->root_panel)
|
||||
if(src_panel_is_empty)
|
||||
{
|
||||
rd_cmd(RD_CmdKind_ClosePanel, .panel = rd_handle_from_panel(src_panel));
|
||||
rd_cmd(RD_CmdKind_ClosePanel, .panel = src_panel->id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
case RD_CmdKind_TabBarTop:
|
||||
{
|
||||
@@ -14132,6 +14125,13 @@ Z(getting_started)
|
||||
#undef X
|
||||
#undef Y
|
||||
#undef Z
|
||||
|
||||
//- rjf: remember that we reset the panel layouts
|
||||
RD_WindowState *ws = rd_window_state_from_cfg(window);
|
||||
if(ws != &rd_nil_window_state)
|
||||
{
|
||||
ws->window_layout_reset = 1;
|
||||
}
|
||||
}break;
|
||||
|
||||
//- rjf: thread finding
|
||||
|
||||
@@ -540,6 +540,7 @@ struct RD_WindowState
|
||||
UI_State *ui;
|
||||
F32 last_dpi;
|
||||
B32 window_temporarily_focused_ipc;
|
||||
B32 window_layout_reset;
|
||||
|
||||
// rjf: config/settings
|
||||
UI_Palette cfg_palettes[RD_PaletteCode_COUNT]; // derivative from theme
|
||||
|
||||
+14
-4
@@ -796,6 +796,7 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U
|
||||
ui_state->tooltip_open = 0;
|
||||
ui_state->ctx_menu_changed = 0;
|
||||
ui_state->default_animation_rate = 1 - pow_f32(2, (-80.f * ui_state->animation_dt));
|
||||
ui_state->tooltip_can_overflow_window = 0;
|
||||
}
|
||||
|
||||
//- rjf: prune unused animation nodes
|
||||
@@ -1234,9 +1235,7 @@ ui_end_build(void)
|
||||
UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root};
|
||||
B32 force_contain[] =
|
||||
{
|
||||
(ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) &&
|
||||
ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) &&
|
||||
ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())),
|
||||
!ui_state->tooltip_can_overflow_window,
|
||||
1,
|
||||
};
|
||||
for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1)
|
||||
@@ -1327,7 +1326,8 @@ ui_end_build(void)
|
||||
box = box->hash_next)
|
||||
{
|
||||
// rjf: grab states informing animation
|
||||
B32 is_hot = ui_key_match(box->key, ui_state->hot_box_key);
|
||||
B32 is_hot = (ui_key_match(box->key, ui_state->hot_box_key) ||
|
||||
ui_key_match(box->key, ui_state->drop_hot_box_key));
|
||||
B32 is_active = ui_key_match(box->key, ui_state->active_box_key[UI_MouseButtonKind_Left]);
|
||||
B32 is_disabled = !!(box->flags & UI_BoxFlag_Disabled) && (box->first_disabled_build_index+2 < ui_state->build_index ||
|
||||
box->first_touched_build_index == box->first_disabled_build_index);
|
||||
@@ -1419,6 +1419,16 @@ ui_end_build(void)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: use group keys for box animation data if possible
|
||||
for(UI_Box *b = ui_state->root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, ui_state->root).next)
|
||||
{
|
||||
if(ui_key_match(b->key, ui_key_zero()) && !ui_key_match(b->group_key, ui_key_zero()))
|
||||
{
|
||||
UI_Box *group_box = ui_box_from_key(b->group_key);
|
||||
b->hot_t = group_box->hot_t;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: animate context menu
|
||||
if(ui_state->ctx_menu_open && !ui_box_is_nil(ui_state->ctx_menu_root) && !ui_state->ctx_menu_changed)
|
||||
{
|
||||
|
||||
@@ -657,6 +657,7 @@ struct UI_State
|
||||
U64 build_box_count;
|
||||
U64 last_build_box_count;
|
||||
B32 ctx_menu_touched_this_frame;
|
||||
B32 tooltip_can_overflow_window;
|
||||
B32 is_animating;
|
||||
|
||||
//- rjf: build parameters
|
||||
|
||||
Reference in New Issue
Block a user