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 |
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 |
|
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 #57352 is a reply to message #57351] |
Thu, 15 July 2021 19:38 |
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
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[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 |
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
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[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 |
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 |
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
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[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 #57374 is a reply to message #57373] |
Fri, 23 July 2021 19:19 |
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
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[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 |
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.
|
|
|
Goto Forum:
Current Time: Sat Dec 14 14:51:26 CET 2024
Total time taken to generate the page: 0.06271 seconds
|