Moved stable tool tip concept into the BToolManager class.

* This removes the fVisibleToolTip member from BView, and fixes bug #5669;
  BToolTipManager::ShowTip() now gets the owner of the tool tip as an extra
  parameter.
* Removed the work-around to hide that bug.
* Improved ToolTipTest application to include more test cases like a view that
  periodically update its tool tip via SetToolTip(const char*), and one that
  sets a new tool tip every second.
* Furthermore, added a test that shows that inner views inherit the tool tip
  of their parents.
* Fixed another bug in BToolTipManager::ShowTip() that would release an
  extra reference to the tool tip currently shown.
This commit is contained in:
Axel Dörfler
2012-04-28 22:14:03 +02:00
parent f790fa299e
commit 2f2f3fa042
6 changed files with 116 additions and 48 deletions
+1 -2
View File
@@ -700,9 +700,8 @@ private:
LayoutData* fLayoutData; LayoutData* fLayoutData;
BToolTip* fToolTip; BToolTip* fToolTip;
BToolTip* fVisibleToolTip;
uint32 _reserved[5]; uint32 _reserved[6];
}; };
+2 -1
View File
@@ -18,7 +18,8 @@ class BToolTipManager {
public: public:
static BToolTipManager* Manager(); static BToolTipManager* Manager();
void ShowTip(BToolTip* tip, BPoint point); void ShowTip(BToolTip* tip, BPoint point,
void* owner);
void HideTip(); void HideTip();
void SetShowDelay(bigtime_t time); void SetShowDelay(bigtime_t time);
+8 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2009, Haiku, Inc. All Rights Reserved. * Copyright 2009-2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef TOOL_TIP_WINDOW_H #ifndef TOOL_TIP_WINDOW_H
@@ -11,13 +11,19 @@
namespace BPrivate { namespace BPrivate {
class ToolTipWindow : public BWindow { class ToolTipWindow : public BWindow {
public: public:
ToolTipWindow(BToolTip* tip, BPoint where); ToolTipWindow(BToolTip* tip, BPoint where,
void* owner);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
private:
void* fOwner;
}; };
} // namespace BPrivate } // namespace BPrivate
+20 -17
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2009-2010, Axel Dörfler, [email protected]. * Copyright 2009-2012, Axel Dörfler, [email protected].
* Copyright 2009, Stephan Aßmus <[email protected]>. * Copyright 2009, Stephan Aßmus <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@@ -285,12 +285,13 @@ ToolTipView::ResetWindowFrame(BPoint where)
// #pragma mark - // #pragma mark -
ToolTipWindow::ToolTipWindow(BToolTip* tip, BPoint where) ToolTipWindow::ToolTipWindow(BToolTip* tip, BPoint where, void* owner)
: :
BWindow(BRect(0, 0, 250, 10).OffsetBySelf(where), "tool tip", BWindow(BRect(0, 0, 250, 10).OffsetBySelf(where), "tool tip",
B_BORDERED_WINDOW_LOOK, kMenuWindowFeel, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel,
B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS
| B_AVOID_FRONT | B_AVOID_FOCUS) | B_AVOID_FRONT | B_AVOID_FOCUS),
fOwner(owner)
{ {
SetLayout(new BGroupLayout(B_VERTICAL)); SetLayout(new BGroupLayout(B_VERTICAL));
@@ -323,6 +324,7 @@ ToolTipWindow::MessageReceived(BMessage* message)
BMessage reply(B_REPLY); BMessage reply(B_REPLY);
reply.AddPointer("current", tip); reply.AddPointer("current", tip);
reply.AddPointer("owner", fOwner);
if (message->SendReply(&reply) == B_OK) if (message->SendReply(&reply) == B_OK)
tip->AcquireReference(); tip->AcquireReference();
@@ -363,36 +365,30 @@ BToolTipManager::Manager()
} }
/*static*/ void
BToolTipManager::_InitSingleton()
{
sDefaultInstance = new BToolTipManager();
}
void void
BToolTipManager::ShowTip(BToolTip* tip, BPoint point) BToolTipManager::ShowTip(BToolTip* tip, BPoint point, void* owner)
{ {
BToolTip* current = NULL; BToolTip* current = NULL;
void* currentOwner = NULL;
BMessage reply; BMessage reply;
if (fWindow.SendMessage(kMsgCurrentToolTip, &reply) == B_OK) if (fWindow.SendMessage(kMsgCurrentToolTip, &reply) == B_OK) {
reply.FindPointer("current", (void**)&current); reply.FindPointer("current", (void**)&current);
reply.FindPointer("owner", &currentOwner);
}
// Release reference from the message
if (current != NULL) if (current != NULL)
current->ReleaseReference(); current->ReleaseReference();
if (current == tip) { if (current == tip || currentOwner == owner) {
fWindow.SendMessage(kMsgShowToolTip); fWindow.SendMessage(kMsgShowToolTip);
return; return;
} }
fWindow.SendMessage(kMsgHideToolTip); fWindow.SendMessage(kMsgHideToolTip);
if (current != NULL)
current->ReleaseReference();
if (tip != NULL) { if (tip != NULL) {
BWindow* window = new BPrivate::ToolTipWindow(tip, point); BWindow* window = new BPrivate::ToolTipWindow(tip, point, owner);
window->Show(); window->Show();
fWindow = BMessenger(window); fWindow = BMessenger(window);
@@ -459,3 +455,10 @@ BToolTipManager::BToolTipManager()
BToolTipManager::~BToolTipManager() BToolTipManager::~BToolTipManager()
{ {
} }
/*static*/ void
BToolTipManager::_InitSingleton()
{
sDefaultInstance = new BToolTipManager();
}
+1 -13
View File
@@ -4817,10 +4817,6 @@ BView::DoLayout()
void void
BView::SetToolTip(const char* text) BView::SetToolTip(const char* text)
{ {
// TODO: temporary work-around for bug #5669
HideToolTip();
SetToolTip(static_cast<BToolTip*>(NULL));
if (text == NULL || text[0] == '\0') if (text == NULL || text[0] == '\0')
return; return;
@@ -4858,12 +4854,10 @@ BView::ShowToolTip(BToolTip* tip)
if (tip == NULL) if (tip == NULL)
return; return;
fVisibleToolTip = tip;
BPoint where; BPoint where;
GetMouse(&where, NULL, false); GetMouse(&where, NULL, false);
BToolTipManager::Manager()->ShowTip(tip, ConvertToScreen(where)); BToolTipManager::Manager()->ShowTip(tip, ConvertToScreen(where), this);
} }
@@ -4871,17 +4865,12 @@ void
BView::HideToolTip() BView::HideToolTip()
{ {
BToolTipManager::Manager()->HideTip(); BToolTipManager::Manager()->HideTip();
fVisibleToolTip = NULL;
} }
bool bool
BView::GetToolTipAt(BPoint point, BToolTip** _tip) BView::GetToolTipAt(BPoint point, BToolTip** _tip)
{ {
if (fVisibleToolTip != NULL) {
*_tip = fVisibleToolTip;
return true;
}
if (fToolTip != NULL) { if (fToolTip != NULL) {
*_tip = fToolTip; *_tip = fToolTip;
return true; return true;
@@ -5038,7 +5027,6 @@ BView::_InitData(BRect frame, const char* name, uint32 resizingMode,
fLayoutData = new LayoutData; fLayoutData = new LayoutData;
fToolTip = NULL; fToolTip = NULL;
fVisibleToolTip = NULL;
} }
+84 -13
View File
@@ -1,13 +1,15 @@
/* /*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de. * Copyright 2009-2012, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <Application.h> #include <Application.h>
#include <Box.h> #include <Box.h>
#include <GroupView.h>
#include <LayoutBuilder.h> #include <LayoutBuilder.h>
#include <MessageRunner.h> #include <MessageRunner.h>
#include <String.h>
#include <StringView.h> #include <StringView.h>
#include <Window.h> #include <Window.h>
@@ -18,9 +20,9 @@
class CustomToolTip : public BToolTip { class CustomToolTip : public BToolTip {
public: public:
CustomToolTip() CustomToolTip(const char* text)
{ {
fView = new BStringView("", "Custom tool tip!"); fView = new BStringView("", text);
fView->SetFont(be_bold_font); fView->SetFont(be_bold_font);
fView->SetHighColor(255, 0, 0); fView->SetHighColor(255, 0, 0);
} }
@@ -176,6 +178,52 @@ public:
}; };
class PulseStringView : public BStringView {
public:
PulseStringView(const char* name, const char* label)
:
BStringView(name, label, B_WILL_DRAW | B_PULSE_NEEDED)
{
}
virtual void Pulse()
{
char buffer[256];
time_t now = time(NULL);
strftime(buffer, sizeof(buffer), "%X", localtime(&now));
SetToolTip(buffer);
}
};
class PulseToolTipView : public BStringView {
public:
PulseToolTipView(const char* name, const char* label)
:
BStringView(name, label, B_WILL_DRAW | B_PULSE_NEEDED),
fToolTip(NULL),
fCounter(0)
{
}
virtual void Pulse()
{
if (fToolTip != NULL)
fToolTip->ReleaseReference();
BString text;
text.SetToFormat("New tool tip every second! (%d)", fCounter++);
fToolTip = new CustomToolTip(text.String());
SetToolTip(fToolTip);
}
private:
BToolTip* fToolTip;
int fCounter;
};
class Window : public BWindow { class Window : public BWindow {
public: public:
Window(); Window();
@@ -204,22 +252,44 @@ Window::Window()
simple->SetToolTip("This is a really\nsimple tool tip!"); simple->SetToolTip("This is a really\nsimple tool tip!");
BView* custom = new BStringView("2", "Custom Tool Tip"); BView* custom = new BStringView("2", "Custom Tool Tip");
custom->SetToolTip(new CustomToolTip()); custom->SetToolTip(new CustomToolTip("Custom tool tip!"));
BView* changing = new BStringView("3", "Changing Tool Tip"); BView* changing = new BStringView("3", "Changing Tool Tip");
changing->SetToolTip(new ChangingToolTip()); changing->SetToolTip(new ChangingToolTip());
BView* mouse = new BStringView("3", "Mouse Tool Tip (sticky)"); BView* mouse = new BStringView("4", "Mouse Tool Tip (sticky)");
mouse->SetToolTip(new MouseToolTip()); mouse->SetToolTip(new MouseToolTip());
BView* immediate = new ImmediateView("3", "Immediate Tool Tip (sticky)"); BView* immediate = new ImmediateView("5", "Immediate Tool Tip (sticky)");
BLayoutBuilder::Group<>(this, B_VERTICAL) BView* pulseString = new PulseStringView("pulseString",
.Add(simple) "Periodically changing tool tip text");
.Add(custom)
.Add(changing) BView* pulseToolTip = new PulseToolTipView("pulseToolTip",
.Add(mouse) "Periodically changing tool tip");
.Add(immediate);
BGroupView* nested = new BGroupView();
nested->SetViewColor(50, 50, 90);
nested->GroupLayout()->SetInsets(30);
nested->SetToolTip("The outer view has a tool tip,\n"
"the inner one doesn't.");
nested->AddChild(new BGroupView("inner"));
BLayoutBuilder::Group<>(this, B_HORIZONTAL)
.SetInsets(B_USE_DEFAULT_SPACING)
.AddGroup(B_VERTICAL)
.Add(simple)
.Add(custom)
.Add(changing)
.Add(mouse)
.Add(immediate)
.End()
.AddGroup(B_VERTICAL)
.Add(pulseString)
.Add(pulseToolTip)
.Add(nested);
SetPulseRate(1000000LL);
} }
@@ -235,7 +305,8 @@ Window::QuitRequested()
Application::Application() Application::Application()
: BApplication("application/x-vnd.haiku-tooltiptest") :
BApplication("application/x-vnd.haiku-tooltiptest")
{ {
} }