/**********************************************************************
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/slider.hh"
#include "window/style.hh"
#include "window/win_evt.hh"
i4_slider_class::i4_slider_class(sw32 width,
sw32 initial_start,
i4_event_handler_class *notify,
w32 milli_delay,
i4_graphical_style_class *style)
: i4_window_class(width,style->font_hint->normal_font->largest_height()+2),
style(style),
notify(notify),
milli_delay(milli_delay)
{
off=initial_start;
grab=i4_F;
active=i4_F;
w32 ol,or,ot,ob;
style->get_out_deco_size(ol,ot,or,ob);
bw=ol+or+2;
need_cancel=i4_F;
}
void i4_slider_class::draw(i4_draw_context_class &context)
{
w32 il,ir,it,ib;
w32 med=style->color_hint->window.passive.medium;
local_image->clear(med, context);
style->get_in_deco_size(il,it,ir,ib);
style->draw_in_deco(local_image, 0,height()/2-it,width()-1,height()/2+ib, active, context);
w32 ol,or,ot,ob;
style->get_out_deco_size(ol,ot,or,ob);
style->draw_out_deco(local_image, off,0,off+bw-1,height()-1, active, context);
local_image->bar(off+ol, ot, off+bw-or, height()-ob, med, context);
}
void i4_slider_class::send_change()
{
if (notify)
{
if (need_cancel)
{
i4_time_dev.cancel_event(t_event);
need_cancel=i4_F;
}
i4_slider_event ev(this, off, width()-bw);
if (milli_delay)
{
t_event=i4_time_dev.request_event(notify, &ev, milli_delay);
need_cancel=i4_T;
} else i4_kernel.send_event(notify, &ev);
}
}
i4_slider_class::~i4_slider_class()
{
if (need_cancel)
{
milli_delay=0;
send_change();
}
}
void i4_slider_class::set_off_from_mouse()
{
w32 ol,or,ot,ob;
sw32 loff=off;
style->get_out_deco_size(ol,ot,or,ob);
off=lx-bw/2;
if (off<0) off=0;
if (off+bw>=width())
off=width()-bw;
if (loff!=off)
{
send_change();
request_redraw();
}
}
void i4_slider_class::receive_event(i4_event *ev)
{
switch (ev->type())
{
case i4_event::WINDOW_MESSAGE :
{
CAST_PTR(wev, i4_window_message_class, ev);
if (wev->sub_type==i4_window_message_class::GOT_MOUSE_FOCUS)
{
active=i4_T;
request_redraw();
}
else if (wev->sub_type==i4_window_message_class::LOST_MOUSE_FOCUS)
{
active=i4_F;
request_redraw();
}
} break;
case i4_event::MOUSE_MOVE :
{
CAST_PTR(mev, i4_mouse_move_event_class, ev);
lx=mev->x;
ly=mev->y;
if (grab)
set_off_from_mouse();
} break;
case i4_event::MOUSE_BUTTON_DOWN :
{
CAST_PTR(bev, i4_mouse_button_down_event_class, ev);
if (bev->left() && !grab)
{
grab=i4_T;
i4_window_request_mouse_grab_class grab(this);
i4_kernel.send_event(parent,&grab);
set_off_from_mouse();
}
} break;
case i4_event::MOUSE_BUTTON_UP :
{
CAST_PTR(bev, i4_mouse_button_up_event_class, ev);
if (grab && bev->left())
{
i4_window_request_mouse_ungrab_class ungrab(this);
i4_kernel.send_event(parent,&ungrab);
grab=i4_F;
}
} break;
}
}