Scatter: Added changing mouse behavior

git-svn-id: svn://ultimatepp.org/upp/trunk@2809 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2010-10-22 20:30:21 +00:00
parent 0275482a1e
commit ea56da2734
3 changed files with 255 additions and 53 deletions

View file

@ -4,6 +4,16 @@
#define IMAGEFILE <Scatter/Chart.iml>
#include <Draw/iml.h>
Scatter::MouseBehaviour defaultMouse[] = {
{false, false, false, true , false, 0, false, Scatter::SHOW_INFO},
{false, false, false, false, true , 0, false, Scatter::SCROLL},
{false, false, false, false, false, 1, false, Scatter::ZOOM_H_RED},
{false, false, false, false, false, 1, false, Scatter::ZOOM_V_RED},
{false, false, false, false, false,-1, false, Scatter::ZOOM_H_ENL},
{false, false, false, false, false,-1, false, Scatter::ZOOM_V_ENL},
{false, false, false, false, false, 0, false, Scatter::NO_ACTION}};
Scatter& Scatter::SetColor(const class::Color& _color)
{
graphColor=_color;
@ -486,7 +496,7 @@ void Scatter::SetFunctColor(const int& j, const class::Color& fcolor)
Refresh();
}
}
Acolor Scatter::GetDataColor(const int& j) const
Color Scatter::GetDataColor(const int& j) const
{
if(IsValid(j))
{
@ -495,7 +505,7 @@ Acolor Scatter::GetDataColor(const int& j) const
throw (Exc(t_("Invalid series index!")));
}
Acolor Scatter::GetFunctColor(const int& j) const
Color Scatter::GetFunctColor(const int& j) const
{
if(IsValid(j))
{
@ -575,7 +585,7 @@ int Scatter::GetMarkStyle(const int& j) const
throw (Exc(t_("Invalid series index!")));
}
void Scatter::SetMarkColor(const int& j, const Acolor& mcolor)
void Scatter::SetMarkColor(const int& j, const ::Color& mcolor)
{
if(IsValid(j))
{
@ -584,7 +594,7 @@ void Scatter::SetMarkColor(const int& j, const Acolor& mcolor)
}
}
Acolor Scatter::GetMarkColor(const int& j) const
Color Scatter::GetMarkColor(const int& j) const
{
if(IsValid(j))
{
@ -940,36 +950,135 @@ void Scatter::ProcessPopUp(const Point & pt)
popText.SetText(str).Move(this,p2.x,p2.y);
}
void Scatter::LeftDown(Point pt, dword)
void Scatter::DoMouseAction(bool down, Point pt, MouseAction action, int value)
{
if(paintInfo && px <=pt.x && pt.x<= GetSize().cx-px && (py + titleFont.GetHeight())<=pt.y && pt.y<= GetSize().cy-py)
{
popText.AppearOnly(this);
ProcessPopUp(pt);
isLeftDown = true;
}
}
void Scatter::LeftUp(Point, dword)
{
if(paintInfo && isLeftDown)
{
popText.Close();
isLeftDown = false;
switch (action) {
case SCROLL: Scrolling(down, pt);
break;
case ZOOM_H_ENL:
case ZOOM_H_RED: MouseZoom(value, true, false);
break;
case ZOOM_V_ENL:
case ZOOM_V_RED: MouseZoom(value, false, true);
break;
case SHOW_INFO: LabelPopUp(down, pt);
break;
}
}
void Scatter::MiddleDown(Point pt, dword)
bool Scatter::SetMouseBehavior(MouseBehaviour *_mouseBehavior)
{
if((mouseHandlingX || mouseHandlingY) && px <=pt.x && pt.x<= GetSize().cx-px && (py + titleFont.GetHeight())<=pt.y && pt.y<= GetSize().cy-py)
{
butDownX = pt.x;
butDownY = pt.y;
isMidDown = true;
if (!_mouseBehavior)
return false;
int i;
for (i = 0; _mouseBehavior[i].action != NO_ACTION && i < MAX_MOUSEBEHAVIOR; ++i) ;
if (i == MAX_MOUSEBEHAVIOR)
return false;
mouseBehavior = _mouseBehavior;
return true;
}
void Scatter::ProcessMouse(bool down, Point pt, bool ctrl, bool alt, bool shift, bool left, bool middle, int middleWheel, bool right)
{
int i;
for (i = 0; mouseBehavior[i].action != NO_ACTION && i < MAX_MOUSEBEHAVIOR; ++i) {
if (mouseBehavior[i].ctrl == ctrl && mouseBehavior[i].alt == alt &&
mouseBehavior[i].shift == shift && mouseBehavior[i].left == left &&
mouseBehavior[i].middle == middle && mouseBehavior[i].right == right &&
((mouseBehavior[i].middleWheel == 0) || mouseBehavior[i].middleWheel == ((middleWheel > 0) - (middleWheel < 0))))
DoMouseAction(down, pt, mouseBehavior[i].action, middleWheel);
}
}
void Scatter::LabelPopUp(bool down, Point pt)
{
if (down) {
if(paintInfo && px <=pt.x && pt.x<= GetSize().cx-px && (py + titleFont.GetHeight())<=pt.y && pt.y<= GetSize().cy-py)
{
popText.AppearOnly(this);
ProcessPopUp(pt);
isLabelPopUp = true;
}
} else {
if(paintInfo && isLabelPopUp)
{
popText.Close();
isLabelPopUp = false;
}
}
}
#ifdef PLATFORM_LINUX
#include <X11/cursorfont.h>
#endif
void Scatter::Scrolling(bool down, Point pt)
{
static Image mouseImg;
if (down) {
if((mouseHandlingX || mouseHandlingY) && px <=pt.x && pt.x<= GetSize().cx-px && (py + titleFont.GetHeight())<=pt.y && pt.y<= GetSize().cy-py)
{
butDownX = pt.x;
butDownY = pt.y;
isScrolling = true;
/* INTERLOCKED {
#ifdef PLATFORM_WIN32
static Image img = Win32Cursor(IDC_SIZEALL);
#else
static Image img = X11Cursor(XC_fleur);
#endif
mouseImg = Ctrl::OverrideCursor(img);
}*/
}
} else {
if (isScrolling) {
MouseMove(pt, 0);
isScrolling = false;
// Ctrl::OverrideCursor(mouseImg);
}
}
}
void Scatter::LeftDown(Point pt, dword keyFlags)
{
ProcessMouse(true, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, true, false, 0, false);
}
void Scatter::LeftUp(Point pt, dword keyFlags)
{
ProcessMouse(false, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, true, false, 0, false);
}
void Scatter::MiddleDown(Point pt, dword keyFlags)
{
ProcessMouse(true, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, false, true, 0, false);
}
void Scatter::MiddleUp(Point pt, dword keyFlags)
{
ProcessMouse(false, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, false, true, 0, false);
}
void Scatter::RightDown(Point pt, dword keyFlags)
{
ProcessMouse(true, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, false, false, 0, true);
}
void Scatter::RightUp(Point pt, dword keyFlags)
{
ProcessMouse(false, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, false, false, 0, true);
}
void Scatter::MouseWheel(Point pt, int zdelta, dword keyFlags)
{
if (zdelta == 0)
return;
ProcessMouse(true, pt, keyFlags & K_CTRL, keyFlags & K_ALT, keyFlags & K_SHIFT, false, false, zdelta, false);
}
void Scatter::MouseMove(Point pt, dword)
{
if (isMidDown)
if (isScrolling)
{
int shiftX = pt.x - butDownX;
if (mouseHandlingX && shiftX != 0) {
@ -999,7 +1108,7 @@ void Scatter::MouseMove(Point pt, dword)
WhenZoomScroll();
}
}
if(isLeftDown) {
if(isLabelPopUp) {
if (paintInfo && px <=pt.x && pt.x<= GetSize().cx-px && (py + titleFont.GetHeight())<=pt.y && pt.y<= GetSize().cy-py)
{
ProcessPopUp(pt);
@ -1007,25 +1116,23 @@ void Scatter::MouseMove(Point pt, dword)
}
}
void Scatter::MiddleUp(Point pt, dword d)
{
if (isMidDown) {
MouseMove(pt, d);
isMidDown = false;
}
}
void Scatter::MouseLeave()
{
isMidDown = false;
isScrolling = false;
}
void Scatter::Zoom(double scale)
void Scatter::MouseZoom(int zdelta, bool hor, bool ver)
{
bool mouseX = mouseHandlingX;
double scale = zdelta > 0 ? zdelta/100. : -100./zdelta;
Zoom(scale);
}
void Scatter::Zoom(double scale, bool hor, bool ver)
{
bool mouseX = mouseHandlingX && hor;
mouseX = mouseX && ((minXZoom > 0 && xRange*scale > minXZoom) || (minXZoom < 0));
mouseX = mouseX && ((maxXZoom > 0 && xRange*scale < maxXZoom) || (maxXZoom < 0));
bool mouseY = mouseHandlingY;
bool mouseY = mouseHandlingY && ver;
mouseY = mouseY && ((minYZoom > 0 && yRange*scale > minYZoom) || (minYZoom < 0));
mouseY = mouseY && ((maxYZoom > 0 && yRange*scale < maxYZoom) || (maxYZoom < 0));
mouseX = mouseX && (!mouseHandlingY || mouseY);
@ -1077,14 +1184,6 @@ void Scatter::Scroll(double factorX, double factorY)
}
}
void Scatter::MouseWheel(Point, int zdelta, dword)
{
if (zdelta == 0)
return;
double scale = zdelta > 0 ? zdelta/100. : -100./zdelta;
Zoom(scale);
}
Image Scatter::CursorImage(Point p, dword keyflags)
{
return ChartImg::cursor1();
@ -1607,7 +1706,7 @@ Scatter::Scatter():
gridColor(::Color(102,102,102)),
gridWidth(4),
paintInfo(false),
mouseHandlingX(false), mouseHandlingY(false), isMidDown(false), isLeftDown(false),
mouseHandlingX(false), mouseHandlingY(false), isScrolling(false), isLabelPopUp(false),
drawXReticle(true), drawYReticle(true), drawY2Reticle(false),
drawVGrid(true), drawHGrid(true),
showLegend(true),legendWeight(80),
@ -1618,6 +1717,7 @@ Scatter::Scatter():
Color(graphColor);
BackPaint();
popText.SetColor(::Color(200,220,255));
SetMouseBehavior(defaultMouse);
}
Scatter::~Scatter()

View file

@ -12,7 +12,6 @@ using namespace Upp;
typedef Pointf XY;
typedef class::Color Acolor;
class Scatter : public StaticRect {
public:
@ -48,6 +47,8 @@ public:
virtual void MiddleDown(Point, dword);
virtual void MouseMove(Point, dword);
virtual void MiddleUp(Point, dword);
virtual void RightDown(Point, dword);
virtual void RightUp(Point, dword);
virtual void MouseLeave();
virtual void MouseWheel(Point, int zdelta, dword);
@ -55,6 +56,23 @@ public:
Callback WhenSetRange;
Callback WhenSetXYMin;
enum MouseAction {NO_ACTION = 1111110, SCROLL, ZOOM_H_ENL, ZOOM_H_RED, ZOOM_V_ENL, ZOOM_V_RED, SHOW_INFO};
struct MouseBehaviour {
bool ctrl;
bool alt;
bool shift;
bool left;
bool middle;
int middleWheel;
bool right;
MouseAction action;
};
#define MAX_MOUSEBEHAVIOR 20
bool SetMouseBehavior(MouseBehaviour *_mouseBehavior);
Scatter& SetColor(const class::Color& _color);
Scatter& SetTitle(const String& _title);
Scatter& SetTitleFont(const Font& fontTitle);
@ -87,7 +105,7 @@ public:
Scatter& SetAntialiasing(const bool& aa=true);
void FitToData(bool Y = false);
void Zoom(double scale);
void Zoom(double scale, bool hor = true, bool ver = true);
void Scroll(double factorX, double factorY);
Scatter& SetRange(double rx, double ry, double ry2 = -1);
@ -141,7 +159,7 @@ public:
void SetMarkStyle(const int& j, MarkStyle noStyle);
int GetMarkStyle(const int& j) const;
void SetMarkColor(const int& j, const class::Color& pcolor);
Acolor GetMarkColor (const int& j) const;
::Color GetMarkColor (const int& j) const;
void SetShowMark(const int& j, const bool& show=true);
bool IsMarkShow(const int& j) const throw (Exc);
@ -247,7 +265,7 @@ private:
bool logX, logY, logY2;
int butDownX, butDownY;
bool isMidDown, isLeftDown;
bool isScrolling, isLabelPopUp;
Vector<Vector<XY> > vPointsData,vFunctionData;
Vector<bool> vFPrimaryY, vPPrimaryY;
@ -274,6 +292,14 @@ private:
Vector<XY> Cubic (const Vector<XY>& DataSet, const int& fineness=10, double tension=0.4)const;
void DrawLegend(Draw& w,const int& scale) const;
MouseBehaviour *mouseBehavior;
void DoMouseAction(bool down, Point pt, MouseAction action, int value);
void ProcessMouse(bool down, Point pt, bool ctrl, bool alt, bool shift, bool left, bool middle, int middleWheel, bool right);
void LabelPopUp(bool down, Point pt);
void Scrolling(bool down, Point pt);
void MouseZoom(int zdelta, bool hor, bool ver);
void SetDrawing(Draw& w, const int& scale)const;
void Circle(Draw& w, const int& scale, const Point& cp, const int& size, const class::Color& markColor)const;
void Square(Draw& w, const int& scale, const Point& cp, const int& size, const class::Color& markColor)const;

View file

@ -11,14 +11,19 @@ topic "Scatter Reference";
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[{_}
[ {{10000@(113.42.0) [s0;%% [*@7;4 Scatter]]}}&]
[s3; &]
[s1;:Scatter`:`:class: [@(0.0.255)3 class][3 _][*3 Scatter][3 _:_][@(0.0.255)3 public][3 _][*@3;3 St
aticRect]&]
[s9; A class to plot 2D graphs.&]
[s0;i448;a25;kKO9;@(0.0.255) &]
[ {{10000F(128)G(128)@1 [s0;%% [* Function List]]}}&]
[s4; &]
[s5;:Scatter`:`:FitToData`(bool`): [@(0.0.255) void]_[* FitToData]([@(0.0.255) bool]_[*@3 Y]_
`=_[@(0.0.255) false])&]
[s5;:Scatter`:`:class: [@(0.0.255) void]_[* FitToData]([@(0.0.255) bool]_[*@3 Y]_`=_[@(0.0.255) f
alse])&]
[s0;l288;%% Changes X axis zoom to fit visible all data in Ctrl.&]
[s0;l288;i448;a25;kKO9;%% If [%-*@3 Y ]is true, Y axis zoom is also
changed to fit the data.&]
[s3;%% &]
[s4; &]
[s5;:Scatter`:`:SaveToClipboard`(bool`): [@(0.0.255) void]_[* SaveToClipboard]([@(0.0.255) b
ool]_[*@3 saveAsMetafile]_`=_[@(0.0.255) false])&]
@ -119,4 +124,75 @@ side of control.&]
[s2;%% Gets secondary Y axis coordinate of the first visible point
in the bottommost side of control.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:SetMouseBehavior`(Scatter`:`:MouseBehaviour`*`): [@(0.0.255) bool]_[* Set
MouseBehavior]([_^Scatter`:`:MouseBehaviour^ MouseBehaviour]_`*[*@3 mouseBehavior])&]
[s2;%% Sets with [%-*@3 mouseBehavior] the array of MouseBehavior conditions
and actions to be considered when handling the mouse over the
control.&]
[s2;%% This array has to be ended with an item with action `=`= NO`_ACTION.&]
[s2;%% Returns false if [%-*@3 mouseBehavior] array is not well defined.&]
[s3; &]
[s0; &]
[ {{10000@3 [s0;%% [*@(229)4 Scatter`::MouseBehavior]]}}&]
[s3;%% &]
[s1;:Scatter`:`:MouseBehaviour`:`:struct: [@(0.0.255)3 struct][3 _][*3 MouseBehavior]&]
[s9;%% This structure is used to describe the behavior of the mouse
when used in Scatter. It includes the keyboard and mouse conditions
that, when complied, will launch the indicated action.&]
[s9;%% It is used by SetMouseBehavior(MouseBehaviour `*`_mouseBehavior)
function to set an array of MouseBehavior items that will be
used to launch actions as zooming or scrolling when mouse is
used.&]
[s9;%% The default array is in Scatter`::MouseBehaviour defaultMouse.&]
[s3;%% &]
[s0; &]
[ {{10000F(128)G(128)@1 [s0;%% [* Public Member List]]}}&]
[s3;%% &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:ctrl: [@(0.0.255) bool]_[* ctrl]&]
[s2;%% Set to true if Ctrl has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:alt: [@(0.0.255) bool]_[* alt]&]
[s2;%% Set to true if Alt has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:shift: [@(0.0.255) bool]_[* shift]&]
[s2;%% Set to true if Shift has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:left: [@(0.0.255) bool]_[* left]&]
[s2;%% Set to true if mouse left button has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:middle: [@(0.0.255) bool]_[* middle]&]
[s2;%% Set to true if mouse middle button has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:middleWheel: [@(0.0.255) int]_[* middleWheel]&]
[s2;%% Set to true if mouse middle wheel has to be rolled.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:right: [@(0.0.255) bool]_[* right]&]
[s2;%% Set to true if mouse right button has to be pressed.&]
[s3; &]
[s4; &]
[s5;:Scatter`:`:MouseBehaviour`:`:action: MouseAction_[* action]&]
[s2;%% Is the action to be launched if the previous conditions are
complied. It can be:&]
[s2;i150;O0;~~~1248;%% NO`_ACTION-|No action. It serves to mark the
end of MouseBehavior array.&]
[s2;i150;O0;~~~1248;%% SCROLL-|Scrolls the graphs.&]
[s2;i150;O0;~~~1248;%% ZOOM`_H`_ENL-|Zooms horizontally enlarging
the graphs. &]
[s2;i150;O0;~~~1248;%% ZOOM`_H`_RED-|Zooms horizontally reducing the
graphs.&]
[s2;i150;O0;~~~1248;%% ZOOM`_V`_ENL-|Zooms vertically enlarging the
graphs.&]
[s2;i150;O0;~~~1248;%% ZOOM`_V`_RED-|Zooms horizontally reducing the
graphs.&]
[s2;i150;O0;~~~1248;%% SHOW`_INFO-|Shows an info label including mouse
real X and Y coordinates.&]
[s3;%% &]
[s0; ]