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