455 lines
13 KiB
C++
455 lines
13 KiB
C++
//----------------------------------------------------------------------------
|
|
// Anti-Grain Geometry - Version 2.4
|
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
//
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
// is granted provided this copyright notice appears in all copies.
|
|
// This software is provided "as is" without express or implied
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
// Contact: mcseem@antigrain.com
|
|
// mcseemagg@yahoo.com
|
|
// http://www.antigrain.com
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// classes scale_ctrl_impl, scale_ctrl
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "ctrl/agg_scale_ctrl.h"
|
|
|
|
namespace agg
|
|
{
|
|
|
|
//------------------------------------------------------------------------
|
|
scale_ctrl_impl::scale_ctrl_impl(double x1, double y1,
|
|
double x2, double y2, bool flip_y) :
|
|
ctrl(x1, y1, x2, y2, flip_y),
|
|
m_border_thickness(1.0),
|
|
m_border_extra((fabs(x2 - x1) > fabs(y2 - y1)) ? (y2 - y1) / 2 : (x2 - x1) / 2),
|
|
m_pdx(0.0),
|
|
m_pdy(0.0),
|
|
m_move_what(move_nothing),
|
|
m_value1(0.3),
|
|
m_value2(0.7),
|
|
m_min_d(0.01)
|
|
{
|
|
calc_box();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::calc_box()
|
|
{
|
|
m_xs1 = m_x1 + m_border_thickness;
|
|
m_ys1 = m_y1 + m_border_thickness;
|
|
m_xs2 = m_x2 - m_border_thickness;
|
|
m_ys2 = m_y2 - m_border_thickness;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::border_thickness(double t, double extra)
|
|
{
|
|
m_border_thickness = t;
|
|
m_border_extra = extra;
|
|
calc_box();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::resize(double x1, double y1, double x2, double y2)
|
|
{
|
|
m_x1 = x1;
|
|
m_y1 = y1;
|
|
m_x2 = x2;
|
|
m_y2 = y2;
|
|
calc_box();
|
|
m_border_extra = (fabs(x2 - x1) > fabs(y2 - y1)) ?
|
|
(y2 - y1) / 2 :
|
|
(x2 - x1) / 2;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::value1(double value)
|
|
{
|
|
if(value < 0.0) value = 0.0;
|
|
if(value > 1.0) value = 1.0;
|
|
if(m_value2 - value < m_min_d) value = m_value2 - m_min_d;
|
|
m_value1 = value;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::value2(double value)
|
|
{
|
|
if(value < 0.0) value = 0.0;
|
|
if(value > 1.0) value = 1.0;
|
|
if(m_value1 + value < m_min_d) value = m_value1 + m_min_d;
|
|
m_value2 = value;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::move(double d)
|
|
{
|
|
m_value1 += d;
|
|
m_value2 += d;
|
|
if(m_value1 < 0.0)
|
|
{
|
|
m_value2 -= m_value1;
|
|
m_value1 = 0.0;
|
|
}
|
|
if(m_value2 > 1.0)
|
|
{
|
|
m_value1 -= m_value2 - 1.0;
|
|
m_value2 = 1.0;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void scale_ctrl_impl::rewind(unsigned idx)
|
|
{
|
|
m_idx = idx;
|
|
|
|
switch(idx)
|
|
{
|
|
default:
|
|
|
|
case 0: // Background
|
|
m_vertex = 0;
|
|
m_vx[0] = m_x1 - m_border_extra;
|
|
m_vy[0] = m_y1 - m_border_extra;
|
|
m_vx[1] = m_x2 + m_border_extra;
|
|
m_vy[1] = m_y1 - m_border_extra;
|
|
m_vx[2] = m_x2 + m_border_extra;
|
|
m_vy[2] = m_y2 + m_border_extra;
|
|
m_vx[3] = m_x1 - m_border_extra;
|
|
m_vy[3] = m_y2 + m_border_extra;
|
|
break;
|
|
|
|
case 1: // Border
|
|
m_vertex = 0;
|
|
m_vx[0] = m_x1;
|
|
m_vy[0] = m_y1;
|
|
m_vx[1] = m_x2;
|
|
m_vy[1] = m_y1;
|
|
m_vx[2] = m_x2;
|
|
m_vy[2] = m_y2;
|
|
m_vx[3] = m_x1;
|
|
m_vy[3] = m_y2;
|
|
m_vx[4] = m_x1 + m_border_thickness;
|
|
m_vy[4] = m_y1 + m_border_thickness;
|
|
m_vx[5] = m_x1 + m_border_thickness;
|
|
m_vy[5] = m_y2 - m_border_thickness;
|
|
m_vx[6] = m_x2 - m_border_thickness;
|
|
m_vy[6] = m_y2 - m_border_thickness;
|
|
m_vx[7] = m_x2 - m_border_thickness;
|
|
m_vy[7] = m_y1 + m_border_thickness;
|
|
break;
|
|
|
|
case 2: // pointer1
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1,
|
|
(m_ys1 + m_ys2) / 2.0,
|
|
m_y2 - m_y1,
|
|
m_y2 - m_y1,
|
|
32);
|
|
}
|
|
else
|
|
{
|
|
m_ellipse.init((m_xs1 + m_xs2) / 2.0,
|
|
m_ys1 + (m_ys2 - m_ys1) * m_value1,
|
|
m_x2 - m_x1,
|
|
m_x2 - m_x1,
|
|
32);
|
|
}
|
|
m_ellipse.rewind(0);
|
|
break;
|
|
|
|
case 3: // pointer2
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2,
|
|
(m_ys1 + m_ys2) / 2.0,
|
|
m_y2 - m_y1,
|
|
m_y2 - m_y1,
|
|
32);
|
|
}
|
|
else
|
|
{
|
|
m_ellipse.init((m_xs1 + m_xs2) / 2.0,
|
|
m_ys1 + (m_ys2 - m_ys1) * m_value2,
|
|
m_x2 - m_x1,
|
|
m_x2 - m_x1,
|
|
32);
|
|
}
|
|
m_ellipse.rewind(0);
|
|
break;
|
|
|
|
case 4: // slider
|
|
m_vertex = 0;
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1;
|
|
m_vy[0] = m_y1 - m_border_extra / 2.0;
|
|
m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2;
|
|
m_vy[1] = m_vy[0];
|
|
m_vx[2] = m_vx[1];
|
|
m_vy[2] = m_y2 + m_border_extra / 2.0;
|
|
m_vx[3] = m_vx[0];
|
|
m_vy[3] = m_vy[2];
|
|
}
|
|
else
|
|
{
|
|
m_vx[0] = m_x1 - m_border_extra / 2.0;
|
|
m_vy[0] = m_ys1 + (m_ys2 - m_ys1) * m_value1;
|
|
m_vx[1] = m_vx[0];
|
|
m_vy[1] = m_ys1 + (m_ys2 - m_ys1) * m_value2;
|
|
m_vx[2] = m_x2 + m_border_extra / 2.0;
|
|
m_vy[2] = m_vy[1];
|
|
m_vx[3] = m_vx[2];
|
|
m_vy[3] = m_vy[0];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
unsigned scale_ctrl_impl::vertex(double* x, double* y)
|
|
{
|
|
unsigned cmd = path_cmd_line_to;
|
|
switch(m_idx)
|
|
{
|
|
case 0:
|
|
case 4:
|
|
if(m_vertex == 0) cmd = path_cmd_move_to;
|
|
if(m_vertex >= 4) cmd = path_cmd_stop;
|
|
*x = m_vx[m_vertex];
|
|
*y = m_vy[m_vertex];
|
|
m_vertex++;
|
|
break;
|
|
|
|
case 1:
|
|
if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to;
|
|
if(m_vertex >= 8) cmd = path_cmd_stop;
|
|
*x = m_vx[m_vertex];
|
|
*y = m_vy[m_vertex];
|
|
m_vertex++;
|
|
break;
|
|
|
|
case 2:
|
|
case 3:
|
|
cmd = m_ellipse.vertex(x, y);
|
|
break;
|
|
|
|
default:
|
|
cmd = path_cmd_stop;
|
|
break;
|
|
}
|
|
|
|
if(!is_stop(cmd))
|
|
{
|
|
transform_xy(x, y);
|
|
}
|
|
|
|
return cmd;
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
bool scale_ctrl_impl::in_rect(double x, double y) const
|
|
{
|
|
inverse_transform_xy(&x, &y);
|
|
return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
bool scale_ctrl_impl::on_mouse_button_down(double x, double y)
|
|
{
|
|
inverse_transform_xy(&x, &y);
|
|
|
|
double xp1;
|
|
double xp2;
|
|
double ys1;
|
|
double ys2;
|
|
double xp;
|
|
double yp;
|
|
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1;
|
|
xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2;
|
|
ys1 = m_y1 - m_border_extra / 2.0;
|
|
ys2 = m_y2 + m_border_extra / 2.0;
|
|
yp = (m_ys1 + m_ys2) / 2.0;
|
|
|
|
if(x > xp1 && y > ys1 && x < xp2 && y < ys2)
|
|
{
|
|
m_pdx = xp1 - x;
|
|
m_move_what = move_slider;
|
|
return true;
|
|
}
|
|
|
|
//if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1)
|
|
if(calc_distance(x, y, xp1, yp) <= m_y2 - m_y1)
|
|
{
|
|
m_pdx = xp1 - x;
|
|
m_move_what = move_value1;
|
|
return true;
|
|
}
|
|
|
|
//if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1)
|
|
if(calc_distance(x, y, xp2, yp) <= m_y2 - m_y1)
|
|
{
|
|
m_pdx = xp2 - x;
|
|
m_move_what = move_value2;
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xp1 = m_x1 - m_border_extra / 2.0;
|
|
xp2 = m_x2 + m_border_extra / 2.0;
|
|
ys1 = m_ys1 + (m_ys2 - m_ys1) * m_value1;
|
|
ys2 = m_ys1 + (m_ys2 - m_ys1) * m_value2;
|
|
xp = (m_xs1 + m_xs2) / 2.0;
|
|
|
|
if(x > xp1 && y > ys1 && x < xp2 && y < ys2)
|
|
{
|
|
m_pdy = ys1 - y;
|
|
m_move_what = move_slider;
|
|
return true;
|
|
}
|
|
|
|
//if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1)
|
|
if(calc_distance(x, y, xp, ys1) <= m_x2 - m_x1)
|
|
{
|
|
m_pdy = ys1 - y;
|
|
m_move_what = move_value1;
|
|
return true;
|
|
}
|
|
|
|
//if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1)
|
|
if(calc_distance(x, y, xp, ys2) <= m_x2 - m_x1)
|
|
{
|
|
m_pdy = ys2 - y;
|
|
m_move_what = move_value2;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
|
|
{
|
|
inverse_transform_xy(&x, &y);
|
|
if(!button_flag)
|
|
{
|
|
return on_mouse_button_up(x, y);
|
|
}
|
|
|
|
double xp = x + m_pdx;
|
|
double yp = y + m_pdy;
|
|
double dv;
|
|
|
|
switch(m_move_what)
|
|
{
|
|
case move_value1:
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1);
|
|
}
|
|
else
|
|
{
|
|
m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1);
|
|
}
|
|
if(m_value1 < 0.0) m_value1 = 0.0;
|
|
if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d;
|
|
return true;
|
|
|
|
case move_value2:
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1);
|
|
}
|
|
else
|
|
{
|
|
m_value2 = (yp - m_ys1) / (m_ys2 - m_ys1);
|
|
}
|
|
if(m_value2 > 1.0) m_value2 = 1.0;
|
|
if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d;
|
|
return true;
|
|
|
|
case move_slider:
|
|
dv = m_value2 - m_value1;
|
|
if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
|
|
{
|
|
m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1);
|
|
}
|
|
else
|
|
{
|
|
m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1);
|
|
}
|
|
m_value2 = m_value1 + dv;
|
|
if(m_value1 < 0.0)
|
|
{
|
|
dv = m_value2 - m_value1;
|
|
m_value1 = 0.0;
|
|
m_value2 = m_value1 + dv;
|
|
}
|
|
if(m_value2 > 1.0)
|
|
{
|
|
dv = m_value2 - m_value1;
|
|
m_value2 = 1.0;
|
|
m_value1 = m_value2 - dv;
|
|
}
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
bool scale_ctrl_impl::on_mouse_button_up(double, double)
|
|
{
|
|
m_move_what = move_nothing;
|
|
return false;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
bool scale_ctrl_impl::on_arrow_keys(bool /*left*/, bool /*right*/, bool /*down*/, bool /*up*/)
|
|
{
|
|
/*
|
|
if(right || up)
|
|
{
|
|
m_value += 0.005;
|
|
if(m_value > 1.0) m_value = 1.0;
|
|
return true;
|
|
}
|
|
|
|
if(left || down)
|
|
{
|
|
m_value -= 0.005;
|
|
if(m_value < 0.0) m_value = 0.0;
|
|
return true;
|
|
}
|
|
*/
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|