panel division is now based on lerp position
This commit is contained in:
parent
9240b4a457
commit
ee9ef5d6aa
51
4ed.cpp
51
4ed.cpp
|
@ -20,7 +20,7 @@ enum App_State{
|
||||||
|
|
||||||
struct App_State_Resizing{
|
struct App_State_Resizing{
|
||||||
Panel_Divider *divider;
|
Panel_Divider *divider;
|
||||||
i32 min, max;
|
f32 min, max;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CLI_Process{
|
struct CLI_Process{
|
||||||
|
@ -797,9 +797,14 @@ COMMAND_DECL(open_panel_vsplit){
|
||||||
|
|
||||||
panel2->screen_region = panel1->screen_region;
|
panel2->screen_region = panel1->screen_region;
|
||||||
|
|
||||||
panel2->full.x0 = split.divider->pos;
|
i32 x_pos = ROUND32(lerp((f32)panel1->full.x0,
|
||||||
|
split.divider->pos,
|
||||||
|
(f32)panel1->full.x1)
|
||||||
|
);
|
||||||
|
|
||||||
|
panel2->full.x0 = x_pos;
|
||||||
panel2->full.x1 = panel1->full.x1;
|
panel2->full.x1 = panel1->full.x1;
|
||||||
panel1->full.x1 = split.divider->pos;
|
panel1->full.x1 = x_pos;
|
||||||
|
|
||||||
panel_fix_internal_area(panel1);
|
panel_fix_internal_area(panel1);
|
||||||
panel_fix_internal_area(panel2);
|
panel_fix_internal_area(panel2);
|
||||||
|
@ -823,9 +828,14 @@ COMMAND_DECL(open_panel_hsplit){
|
||||||
|
|
||||||
panel2->screen_region = panel1->screen_region;
|
panel2->screen_region = panel1->screen_region;
|
||||||
|
|
||||||
panel2->full.y0 = split.divider->pos;
|
i32 y_pos = ROUND32(lerp((f32)panel1->full.y0,
|
||||||
|
split.divider->pos,
|
||||||
|
(f32)panel1->full.y1)
|
||||||
|
);
|
||||||
|
|
||||||
|
panel2->full.y0 = y_pos;
|
||||||
panel2->full.y1 = panel1->full.y1;
|
panel2->full.y1 = panel1->full.y1;
|
||||||
panel1->full.y1 = split.divider->pos;
|
panel1->full.y1 = y_pos;
|
||||||
|
|
||||||
panel_fix_internal_area(panel1);
|
panel_fix_internal_area(panel1);
|
||||||
panel_fix_internal_area(panel2);
|
panel_fix_internal_area(panel2);
|
||||||
|
@ -2697,26 +2707,22 @@ App_Step_Sig(app_step){
|
||||||
Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id);
|
Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id);
|
||||||
vars->resizing.divider = div.divider;
|
vars->resizing.divider = div.divider;
|
||||||
|
|
||||||
i32 min, max;
|
f32 min = 0;
|
||||||
|
f32 max = 0;
|
||||||
{
|
{
|
||||||
i32 mid, MIN, MAX;
|
f32 mid = layout_get_position(&models->layout, mouse_divider_id);
|
||||||
mid = div.divider->pos;
|
|
||||||
if (mouse_divider_vertical){
|
if (mouse_divider_vertical){
|
||||||
MIN = 0;
|
max = (f32)models->layout.full_width;
|
||||||
MAX = MIN + models->layout.full_width;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
MIN = 0;
|
max = (f32)models->layout.full_height;
|
||||||
MAX = MIN + models->layout.full_height;
|
|
||||||
}
|
}
|
||||||
min = MIN;
|
|
||||||
max = MAX;
|
|
||||||
|
|
||||||
i32 divider_id = div.id;
|
i32 divider_id = div.id;
|
||||||
do{
|
do{
|
||||||
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id);
|
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id);
|
||||||
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
||||||
i32 pos = other_div.divider->pos;
|
f32 pos = layout_get_position(&models->layout, divider_id);
|
||||||
if (divider_match && pos > mid && pos < max){
|
if (divider_match && pos > mid && pos < max){
|
||||||
max = pos;
|
max = pos;
|
||||||
}
|
}
|
||||||
|
@ -2732,9 +2738,10 @@ App_Step_Sig(app_step){
|
||||||
divider_stack[top++] = div.id;
|
divider_stack[top++] = div.id;
|
||||||
|
|
||||||
while (top > 0){
|
while (top > 0){
|
||||||
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[--top]);
|
--top;
|
||||||
|
Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[top]);
|
||||||
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
|
||||||
i32 pos = other_div.divider->pos;
|
f32 pos = layout_get_position(&models->layout, divider_stack[top]);
|
||||||
if (divider_match && pos > mid && pos < max){
|
if (divider_match && pos > mid && pos < max){
|
||||||
max = pos;
|
max = pos;
|
||||||
}
|
}
|
||||||
|
@ -2752,8 +2759,8 @@ App_Step_Sig(app_step){
|
||||||
end_temp_memory(temp);
|
end_temp_memory(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
vars->resizing.min = min;
|
vars->resizing.min = 0.f;
|
||||||
vars->resizing.max = max;
|
vars->resizing.max = 1.f;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
@ -2761,12 +2768,14 @@ App_Step_Sig(app_step){
|
||||||
{
|
{
|
||||||
if (input->mouse.l){
|
if (input->mouse.l){
|
||||||
Panel_Divider *divider = vars->resizing.divider;
|
Panel_Divider *divider = vars->resizing.divider;
|
||||||
|
i32 pos = 0;
|
||||||
if (divider->v_divider){
|
if (divider->v_divider){
|
||||||
divider->pos = mx;
|
pos = clamp(0, mx, models->layout.full_width);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
divider->pos = my;
|
pos = clamp(0, my, models->layout.full_height);
|
||||||
}
|
}
|
||||||
|
divider->pos = layout_compute_position(&models->layout, divider, pos);
|
||||||
|
|
||||||
if (divider->pos < vars->resizing.min){
|
if (divider->pos < vars->resizing.min){
|
||||||
divider->pos = vars->resizing.min;
|
divider->pos = vars->resizing.min;
|
||||||
|
|
206
4ed_layout.cpp
206
4ed_layout.cpp
|
@ -15,7 +15,7 @@ struct Panel_Divider{
|
||||||
i32 which_child;
|
i32 which_child;
|
||||||
i32 child1, child2;
|
i32 child1, child2;
|
||||||
b32 v_divider;
|
b32 v_divider;
|
||||||
i32 pos;
|
f32 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Screen_Region{
|
struct Screen_Region{
|
||||||
|
@ -188,11 +188,13 @@ layout_split_panel(Editing_Layout *layout, Panel *panel, b32 vertical){
|
||||||
div.divider->which_child = panel->which_child;
|
div.divider->which_child = panel->which_child;
|
||||||
if (vertical){
|
if (vertical){
|
||||||
div.divider->v_divider = 1;
|
div.divider->v_divider = 1;
|
||||||
div.divider->pos = (panel->full.x0 + panel->full.x1) / 2;
|
//div.divider->pos = (panel->full.x0 + panel->full.x1) / 2;
|
||||||
|
div.divider->pos = 0.5f;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
div.divider->v_divider = 0;
|
div.divider->v_divider = 0;
|
||||||
div.divider->pos = (panel->full.y0 + panel->full.y1) / 2;
|
//div.divider->pos = (panel->full.y0 + panel->full.y1) / 2;
|
||||||
|
div.divider->pos = 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_panel = layout_alloc_panel(layout);
|
new_panel = layout_alloc_panel(layout);
|
||||||
|
@ -215,64 +217,111 @@ panel_fix_internal_area(Panel *panel){
|
||||||
panel->inner.y1 = panel->full.y1 - panel->b_margin;
|
panel->inner.y1 = panel->full.y1 - panel->b_margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal i32_Rect
|
||||||
|
layout_get_rect(Editing_Layout *layout, i32 id, i32 which_child){
|
||||||
|
i32 divider_chain[16];
|
||||||
|
i32 chain_count = 0;
|
||||||
|
|
||||||
|
Panel_Divider *dividers = layout->dividers;
|
||||||
|
Panel_Divider *original_div = dividers + id;
|
||||||
|
i32 root = layout->root;
|
||||||
|
|
||||||
|
Assert(0 <= id && id <= layout->panel_max_count - 1);
|
||||||
|
|
||||||
|
divider_chain[chain_count++] = id;
|
||||||
|
for (;id != root;){
|
||||||
|
Panel_Divider *div = dividers + id;
|
||||||
|
id = div->parent;
|
||||||
|
divider_chain[chain_count++] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32_Rect r = i32R(0, 0, layout->full_width, layout->full_height);
|
||||||
|
|
||||||
|
for (i32 i = chain_count-1; i > 0; --i){
|
||||||
|
Panel_Divider *div = dividers + divider_chain[i];
|
||||||
|
if (div->v_divider){
|
||||||
|
if (div->child1 == divider_chain[i-1]){
|
||||||
|
r.x1 = ROUND32(lerp((f32)r.x0,
|
||||||
|
div->pos,
|
||||||
|
(f32)r.x1));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
r.x0 = ROUND32(lerp((f32)r.x0,
|
||||||
|
div->pos,
|
||||||
|
(f32)r.x1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (div->child1 == divider_chain[i-1]){
|
||||||
|
r.y1 = ROUND32(lerp((f32)r.y0,
|
||||||
|
div->pos,
|
||||||
|
(f32)r.y1));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
r.y0 = ROUND32(lerp((f32)r.y0,
|
||||||
|
div->pos,
|
||||||
|
(f32)r.y1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (which_child){
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if (original_div->v_divider){
|
||||||
|
r.x0 = ROUND32(lerp((f32)r.x0,
|
||||||
|
original_div->pos,
|
||||||
|
(f32)r.x1));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
r.y0 = ROUND32(lerp((f32)r.y0,
|
||||||
|
original_div->pos,
|
||||||
|
(f32)r.y1));
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
{
|
||||||
|
if (original_div->v_divider){
|
||||||
|
r.x1 = ROUND32(lerp((f32)r.x0,
|
||||||
|
original_div->pos,
|
||||||
|
(f32)r.x1));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
r.y1 = ROUND32(lerp((f32)r.y0,
|
||||||
|
original_div->pos,
|
||||||
|
(f32)r.y1));
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal i32_Rect
|
||||||
|
layout_get_panel_rect(Editing_Layout *layout, Panel *panel){
|
||||||
|
Assert(layout->panel_count > 1);
|
||||||
|
|
||||||
|
i32_Rect r = layout_get_rect(layout, panel->parent, panel->which_child);
|
||||||
|
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
layout_fix_all_panels(Editing_Layout *layout){
|
layout_fix_all_panels(Editing_Layout *layout){
|
||||||
Panel *panel;
|
Panel *panel;
|
||||||
Panel_Divider *dividers = layout->dividers;
|
Panel_Divider *dividers = layout->dividers; AllowLocal(dividers);
|
||||||
i32 panel_count = layout->panel_count;
|
i32 panel_count = layout->panel_count;
|
||||||
i32_Rect r;
|
|
||||||
i32 pos, which_child, action;
|
|
||||||
Divider_And_ID div;
|
|
||||||
|
|
||||||
if (panel_count > 1){
|
if (panel_count > 1){
|
||||||
for (panel = layout->used_sentinel.next;
|
for (panel = layout->used_sentinel.next;
|
||||||
panel != &layout->used_sentinel;
|
panel != &layout->used_sentinel;
|
||||||
panel = panel->next){
|
panel = panel->next){
|
||||||
|
panel->full = layout_get_panel_rect(layout, panel);
|
||||||
r.x0 = 0;
|
|
||||||
r.x1 = r.x0 + layout->full_width;
|
|
||||||
r.y0 = 0;
|
|
||||||
r.y1 = r.y0 + layout->full_height;
|
|
||||||
|
|
||||||
which_child = panel->which_child;
|
|
||||||
|
|
||||||
div.id = panel->parent;
|
|
||||||
|
|
||||||
for (;;){
|
|
||||||
Assert(div.id != -1);
|
|
||||||
div.divider = dividers + div.id;
|
|
||||||
pos = div.divider->pos;
|
|
||||||
|
|
||||||
action = (div.divider->v_divider << 1) | (which_child > 0);
|
|
||||||
switch (action){
|
|
||||||
case 0: // v_divider : 0, which_child : -1
|
|
||||||
if (pos < r.y1) r.y1 = pos;
|
|
||||||
break;
|
|
||||||
case 1: // v_divider : 0, which_child : 1
|
|
||||||
if (pos > r.y0) r.y0 = pos;
|
|
||||||
break;
|
|
||||||
case 2: // v_divider : 1, which_child : -1
|
|
||||||
if (pos < r.x1) r.x1 = pos;
|
|
||||||
break;
|
|
||||||
case 3: // v_divider : 1, which_child : 1
|
|
||||||
if (pos > r.x0) r.x0 = pos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (div.id != layout->root){
|
|
||||||
div.id = div.divider->parent;
|
|
||||||
which_child = div.divider->which_child;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panel->full = r;
|
|
||||||
panel_fix_internal_area(panel);
|
panel_fix_internal_area(panel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
panel = layout->used_sentinel.next;
|
panel = layout->used_sentinel.next;
|
||||||
panel->full.x0 = 0;
|
panel->full.x0 = 0;
|
||||||
|
@ -289,29 +338,60 @@ layout_refit(Editing_Layout *layout, i32 prev_width, i32 prev_height){
|
||||||
Panel_Divider *dividers = layout->dividers;
|
Panel_Divider *dividers = layout->dividers;
|
||||||
i32 max = layout->panel_max_count - 1;
|
i32 max = layout->panel_max_count - 1;
|
||||||
|
|
||||||
f32 h_ratio, v_ratio;
|
|
||||||
|
|
||||||
Panel_Divider *divider = dividers;
|
Panel_Divider *divider = dividers;
|
||||||
i32 i;
|
|
||||||
|
|
||||||
if (layout->panel_count > 1){
|
if (layout->panel_count > 1){
|
||||||
Assert(prev_width != 0 && prev_height != 0);
|
Assert(prev_width != 0 && prev_height != 0);
|
||||||
|
|
||||||
h_ratio = ((f32)layout->full_width) / prev_width;
|
for (i32 i = 0; i < max; ++i, ++divider){
|
||||||
v_ratio = ((f32)layout->full_height) / prev_height;
|
|
||||||
|
|
||||||
for (i = 0; i < max; ++i, ++divider){
|
|
||||||
if (divider->v_divider){
|
if (divider->v_divider){
|
||||||
divider->pos = ROUND32((divider->pos) * h_ratio);
|
divider->pos = divider->pos;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
divider->pos = ROUND32((divider->pos) * v_ratio);
|
divider->pos = divider->pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layout_fix_all_panels(layout);
|
layout_fix_all_panels(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal f32
|
||||||
|
layout_get_position(Editing_Layout *layout, i32 id){
|
||||||
|
Panel_Divider *dividers = layout->dividers;
|
||||||
|
Panel_Divider *original_div = dividers + id;
|
||||||
|
|
||||||
|
i32_Rect r = layout_get_rect(layout, id, 0);
|
||||||
|
f32 pos = 0;
|
||||||
|
if (original_div->v_divider){
|
||||||
|
pos = lerp((f32)r.x0, original_div->pos, (f32)r.x1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pos = lerp((f32)r.y0, original_div->pos, (f32)r.y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal f32
|
||||||
|
layout_compute_position(Editing_Layout *layout, Panel_Divider *divider, i32 pos){
|
||||||
|
Panel_Divider *dividers = layout->dividers;
|
||||||
|
Panel_Divider *original_div = divider;
|
||||||
|
i32 id = (i32)(divider - dividers);
|
||||||
|
|
||||||
|
i32_Rect r = layout_get_rect(layout, id, 0);
|
||||||
|
f32 l = 0;
|
||||||
|
if (original_div->v_divider){
|
||||||
|
l = unlerp((f32)r.x0, (f32)pos, (f32)r.x1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
l = unlerp((f32)r.y0, (f32)pos, (f32)r.y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(0.f <= l && l <= 1.f);
|
||||||
|
|
||||||
|
return(l);
|
||||||
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue