/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "gui/divider.hh"
#include "window/style.hh"
#include "window/win_evt.hh"
void i4_divider_class::reparent(i4_image_class *draw_area, i4_parent_window_class *parent)
{
if (parent && (w_attached && width()!=parent->width() ||
h_attached && height()!=parent->height()))
{
int nw=w_attached ? parent->width() : width();
int nh=h_attached ? parent->height() : height();
resize(nw,nw);
}
i4_parent_window_class::reparent(draw_area, parent);
}
void i4_divider_class::resize(w16 new_width, w16 new_height)
{
if (w_attached && parent)
new_width=parent->width();
if (h_attached && parent)
new_height=parent->height();
i4_parent_window_class::resize(new_width, new_height);
int x1,y1,x2,y2;
get_drag_area(x1,y1,x2,y2);
if (split_up_down)
{
if (w1.get())
{
remove_child(w1.get());
if (y1<0) y1=0;
w1->resize(new_width, y1);
add_child(0,0,w1.get());
}
if (w2.get())
{
remove_child(w2.get());
int nh=new_height-y2;
if (nh<0) nh=0;
w2->resize(w, nh);
add_child(0,y2+1, w2.get());
}
}
else
{
if (w1.get())
{
remove_child(w1.get());
if (x1<0) x1=0;
w1->resize(x1, new_height);
add_child(0,0,w1.get());
}
if (w2.get())
{
remove_child(w2.get());
int nw=new_width-x2;
if (nw<0) nw=0;
w2->resize(nw, new_height);
add_child(x2+1,0, w2.get());
}
}
}
void i4_divider_class::get_drag_area(int &x1, int &y1, int &x2, int &y2)
{
w32 l,r,t,b;
style->get_out_deco_size(l,t,r,b);
if (split_up_down)
{
int vbh=t+b;
y1=split_value-vbh/2;
y2=y1+vbh-1;
x1=0; x2=width()-1;
}
else
{
int vbw=l+r;
x1=split_value-vbw/2;
x2=x1+vbw-1;
y1=0;
y2=height()-1;
}
}
i4_divider_class::i4_divider_class(int w, int h,
i4_bool split_up_down,
int split_x_or_y,
i4_window_class *window1,
i4_window_class *window2,
i4_graphical_style_class *style,
int window1_min_size,
int window2_min_size)
: split_up_down(split_up_down),
split_value(split_x_or_y),
style(style),
i4_parent_window_class(w,h),
min1(window1_min_size),
min2(window2_min_size)
{
w1=window1;
w2=window2;
if (w==-1)
{
w_attached=i4_T;
w=0;
}
else
w_attached=i4_F;
if (h==-1)
{
h=0;
h_attached=i4_T;
}
else
h_attached=i4_F;
dragging=i4_F;
if (split_x_or_y==-1)
{
if (split_up_down)
split_value=h/2;
else
split_value=w/2;
}
w1=window1;
w2=window2;
add_child(0,0, window1);
add_child(0,0, window2);
resize(w,h);
}
void i4_divider_class::parent_draw(i4_draw_context_class &context)
{
int x1,y1,x2,y2;
get_drag_area(x1,y1,x2,y2);
local_image->add_dirty(x1,y1,x2,y2, context);
style->draw_out_deco(local_image, x1,y1, x2,y2, i4_F, context);
}
void i4_divider_class::receive_event(i4_event *ev)
{
switch (ev->type())
{
case i4_event::MOUSE_BUTTON_DOWN :
{
CAST_PTR(bev, i4_mouse_button_down_event_class, ev);
if (bev->left())
{
int x1,y1,x2,y2;
get_drag_area(x1,y1,x2,y2);
if (bev->x>=x1 && bev->x<=x2 &&
bev->y>=y1 && bev->y<=y2)
{
dragging=i4_T;
i4_window_request_mouse_grab_class grab(this);
i4_kernel.send_event(parent, &grab);
}
else i4_parent_window_class::receive_event(ev);
}
else i4_parent_window_class::receive_event(ev);
} break;
case i4_event::MOUSE_BUTTON_UP :
{
CAST_PTR(bev, i4_mouse_button_up_event_class, ev);
if (dragging && bev->left())
{
dragging=i4_F;
i4_window_request_mouse_ungrab_class ungrab(this);
i4_kernel.send_event(parent, &ungrab);
}
else i4_parent_window_class::receive_event(ev);
} break;
case i4_event::MOUSE_MOVE :
{
CAST_PTR(mev, i4_mouse_move_event_class, ev);
if (dragging)
{
if (split_up_down)
{
if (mev->y!=split_value && mev->y>min1 && height()-mev->y>min2)
{
split_value=mev->y;
resize(width(), height());
}
}
else if (mev->y!=split_value && mev->x>min1 && width()-mev->x>min2)
{
split_value=mev->x;
resize(width(), height());
}
}
else i4_parent_window_class::receive_event(ev);
} break;
default:
i4_parent_window_class::receive_event(ev);
}
}