Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » How do I implement mouse hover in Ctrl based class (How do I implement mouse hover in Ctrl based class)
How do I implement mouse hover in Ctrl based class [message #57348] Thu, 15 July 2021 15:38 Go to next message
awksed is currently offline  awksed
Messages: 68
Registered: April 2012
Member
Hi,

How do I implement mouse hover in a Ctrl based class.

I want to display info on hover in a Ctrl based graph control but cannot find an "OnHover" type facility.

Is there an example of how to do this?

Thanks.
Re: How do I implement mouse hover in Ctrl based class [message #57349 is a reply to message #57348] Thu, 15 July 2021 16:32 Go to previous messageGo to next message
Xemuth is currently offline  Xemuth
Messages: 387
Registered: August 2018
Location: France
Senior Member
Hello Awksed,

Take a look at MOUSEENTER, MOUSEMOVE, MOUSELEAVE function.

virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags)
virtual void MouseEnter(Point p, dword keyflags)
virtual void MouseLeave()


https://www.ultimatepp.org/src$CtrlCore$Ctrl_en-us.html


If you struggle, I can show you an example when I leave my job

[Updated on: Thu, 15 July 2021 16:42]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57351 is a reply to message #57348] Thu, 15 July 2021 18:33 Go to previous messageGo to next message
awksed is currently offline  awksed
Messages: 68
Registered: April 2012
Member
Hi Xemuth,

Many thanks.

A working example would be most appreciated.
Re: How do I implement mouse hover in Ctrl based class [message #57352 is a reply to message #57351] Thu, 15 July 2021 19:38 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1143
Registered: August 2007
Senior Contributor
Hello awksed,

Try this:


#include <CtrlLib/CtrlLib.h>

using namespace Upp;


struct MyApp : TopWindow {
	Point pos;
	Rect  area;
	MyApp()
	{
		Sizeable().Zoomable().CenterScreen().SetRect(0,0, 1024, 800);
	}
	
	void Paint(Draw& w) override
	{
		w.DrawRect(GetSize(), Black());
		w.DrawRect(area, area.Contains(pos) ? Yellow() : Red());
		w.DrawText(10, 10, AsString(pos), Monospace(16), White());
	}
	
	void MouseMove(Point p, dword keyflags) override
	{
		pos = p;
		Tip(area.Contains(p) ? t_("\1This is a [* Rich[/ text tip ]]") : nullptr);
		Refresh();
		
	}
	
	void Layout() override
	{
		area =  GetView().CenterRect(GetSize() / 4);
	}
};

GUI_APP_MAIN
{
	MyApp().Run();
}



A slightly different version which retrieves the mouse position using a method.

#include <CtrlLib/CtrlLib.h>

using namespace Upp;


struct MyApp : TopWindow {
	Rect  area;
	MyApp()
	{
		Sizeable().Zoomable().CenterScreen().SetRect(0,0, 1024, 800);
	}
	
	void Paint(Draw& w) override
	{
		Point pt = GetMouseViewPos(); // This method returns the mouse cursor position relative to the Ctrl's view area.
		w.DrawRect(GetSize(), Black());
		w.DrawRect(area, area.Contains(pt) ? Yellow() : Red());
		w.DrawText(10, 10, AsString(pt), Monospace(16), White());
	}
	
	void MouseMove(Point pt, dword keyflags) override
	{
		// Dispatched when the mouse cursor moves. It CAN also be used to retrieve and store the mouse position.
		// ( instead of GetMouseViewPos() )
		Tip(area.Contains(pt) ? t_("\1This is a [* Rich[/ text tip ]]") : nullptr);
		Refresh();
		
	}
	
	void Layout() override
	{
		area =  GetView().CenterRect(GetSize() / 4);
	}
};

GUI_APP_MAIN
{
	MyApp().Run();
}



Keep in mind that this is a generic and very rudimentary way. Use the overrideable mouse methods for ctrls for fine grained behaviour (as Xemuth suggested).


U++ ctrls provide a method called Tip() which can take a plain or rich text. If all you need is a tooltip for the existing U++ widgets, you can just set the tip.


Best regards,
Oblivion


[Updated on: Thu, 15 July 2021 20:36]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57353 is a reply to message #57351] Fri, 16 July 2021 10:10 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1143
Registered: August 2007
Senior Contributor
Here's another one: Same effect but with MouseEnter/MouseLeave pair, using a child ctrl.


#include <CtrlLib/CtrlLib.h>

using namespace Upp;

struct MyCtrl : Ctrl {
	void Paint(Draw& w) override
	{
		Point pt = GetMouseViewPos();
		w.DrawRect(GetSize(), GetView().Contains(pt) ? Yellow : Red());
	}
	
	void MouseEnter(Point p, dword keyflags) override
	{
		Refresh();
	}
	
	void MouseLeave() override
	{
		Refresh();
	}

	void LeftDouble(Point p, dword keyflags) override
	{
		PromptOK("Ctrl double-clicked");
	}
};

struct MyApp : TopWindow {
	MyCtrl myctrl;
	MyApp()
	{
		Sizeable().Zoomable().CenterScreen().SetRect(0,0, 1024, 800);
		Add(myctrl.Tip(t_("\1This is a [* Rich[/ text tip ]]")));  // Set tip for child ctrl.
	}
	
	void Paint(Draw& w) override
	{
		Point pt = GetMouseViewPos(); // This method returns the mouse cursor position within the Ctrl's view area.
		w.DrawRect(GetSize(), Black());
		w.DrawText(10, 10, AsString(pt), Monospace(16), White());
	}
	
	void MouseMove(Point pt, dword keyflags) override
	{
		Refresh();
		
	}
	
	void Layout() override
	{
		myctrl.SetRect(GetView().CenterRect(GetSize() / 4));
	}
};

GUI_APP_MAIN
{
	MyApp().Run();
}



You can also see that the position display will stop if the mouse enters into the child ctrl.

Best regards,
Oblivion


[Updated on: Fri, 16 July 2021 10:20]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57354 is a reply to message #57348] Fri, 16 July 2021 22:17 Go to previous messageGo to next message
awksed is currently offline  awksed
Messages: 68
Registered: April 2012
Member
Hi Xemuth & Oblivion,

Thanks for your suggestions.

This is what I wrote:

void MyGraph::Hover()
{
 if(m_bTrackingHover)
  {
   m_bTrackingHover = false;

   Point P = GetMouseViewPos();
   
   if(P == m_MousePos)
    {
     // Mouse is hovering 

     // TODO: Call ShowHint() with text
    }
  }
}

Image MyGraph::MouseEvent(int event, Point p, int zdelta, dword keyflags)
{
 switch(event)
  {
   case Ctrl::MOUSELEAVE:
     
     if(m_bTrackingHover)
      {
       m_bTrackingHover = false;
     
       KillTimeCallback(HOVER_TIMER);
      }
     else
       if(!m_pHint)
         CloseHint();
       
     break;
         
   case Ctrl::MOUSEMOVE:

     if(!m_pHint)
      {
       m_MousePos.x     = p.x;
       m_MousePos.y     = p.y;
       m_bTrackingHover = true;
     
       KillSetTimeCallback(1000, THISBACK(Hover), HOVER_TIMER);
      }
      
     break;
  }
   
 return Image::Arrow();
}

[Updated on: Fri, 16 July 2021 22:44]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57355 is a reply to message #57354] Fri, 16 July 2021 23:47 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1143
Registered: August 2007
Senior Contributor
Hello awksed,

I am glad that your solution works. I am curious, however: Is there anything that Ctrl::Tip can't do for you in this particular situation?
Because you seem to be recreating, using the lower level methods, such as Ctrl::MouseEvents, what Ctrl::Tip does. (Don't get me wrong, there is nothing wrong with your method, but it seems just duplicating code in old fashioned way.).


P.s. Since Ctrl::Tip (And many such U++ methods) can use richtext, they can display anything you can display with qtf (including images).


Best regards,
Oblivion


[Updated on: Fri, 16 July 2021 23:48]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57373 is a reply to message #57355] Fri, 23 July 2021 17:44 Go to previous messageGo to next message
awksed is currently offline  awksed
Messages: 68
Registered: April 2012
Member
Hi Oblivion,

When hover occurs at a graph point, I search one of several lists which include the x,y coordinates of that graph line point, process the relevant data and display it.

I an curious to know how you would use Tip() to do that. I'm always eager to learn new methods, especially if it saves me writing a lot of code.

Best regards.
Re: How do I implement mouse hover in Ctrl based class [message #57374 is a reply to message #57373] Fri, 23 July 2021 19:19 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1143
Registered: August 2007
Senior Contributor
Hello awksed,

The example below simulates a similar situation in a crude way.What you need to do is set the tip when a target mouse position/area is hovered.

Tip can do this for you. But if you need more control over the popup window, you can also use a Popup window (but it can complicate things...)

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

struct RectArea : Moveable<RectArea> {
	Rect r;
	String text;
};

struct MyApp : TopWindow {
	Vector<RectArea> ra;
	MyApp()
	{
		Sizeable().Zoomable().CenterScreen().SetRect(0,0, 1024, 800);
		
		for(int i = 0; i < 50; i++) {
			RectArea& r = ra.Add();
			r.r = RectC(20 * i, 20 * i, 20, 20);
			r.text  << "\1[* Index: ]" << i << " &[* Random number: ]" << Random();
		}
	}
	
	void Paint(Draw& w) override
	{
		w.DrawRect(GetSize(), Black());
		for(const RectArea& r : ra)
			w.DrawRect(r.r, Red());
	}
	
	void MouseMove(Point pt, dword keyflags) override
	{
		// Dont forget to call the parent ctrl's MouseMove, if it is utilized!
		
		if(HasFocus() && ra.GetCount()) {
			for(const RectArea& r : ra)
				if(r.r.Contains(pt)) {
					Tip(r.text);
					return;
				}
			Tip(nullptr);
		}
	}
};

GUI_APP_MAIN
{
	MyApp().Run();
}



Now, this example is using rectangles and precalculation of areas. But the idea is the same: Do the checking in MouseMove and set or reset the Tip(), depending on the conditions, and don't forget to call the parent ctrl's MouseMove.

(In principle, this is how I display the hyperlink URLs in tips, in our TerminalCtrl)


Best regards,
Oblivion


[Updated on: Fri, 23 July 2021 19:32]

Report message to a moderator

Re: How do I implement mouse hover in Ctrl based class [message #57376 is a reply to message #57374] Sat, 24 July 2021 14:48 Go to previous message
awksed is currently offline  awksed
Messages: 68
Registered: April 2012
Member
Hi Oblivion,

I tried Tip() with my now perfectly working hover code but it was unreliable.

I now have a working hover system and when I find out why my TopWindow derived Hint class is stubbornly centering on its parent control instead of the absolute screen position I passed to SetRect() before calling Show() (to be modeless), it will all be working perfectly.

Best regards.
Previous Topic: Jsonize() Date and Time serialization [patch]
Next Topic: Probable nasty bug with StringBuffer
Goto Forum:
  


Current Time: Sat Dec 14 14:51:26 CET 2024

Total time taken to generate the page: 0.06271 seconds