From 2f2f3fa042bf2de464d8318de702db7106b686a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 28 Apr 2012 22:09:14 +0200 Subject: [PATCH] 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. --- headers/os/interface/View.h | 3 +- headers/private/interface/ToolTipManager.h | 3 +- headers/private/interface/ToolTipWindow.h | 10 ++- src/kits/interface/ToolTipManager.cpp | 37 +++++---- src/kits/interface/View.cpp | 14 +--- src/tests/kits/interface/ToolTipTest.cpp | 97 +++++++++++++++++++--- 6 files changed, 116 insertions(+), 48 deletions(-) diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index 1d3e5f6b7f..42e7d5e402 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -700,9 +700,8 @@ private: LayoutData* fLayoutData; BToolTip* fToolTip; - BToolTip* fVisibleToolTip; - uint32 _reserved[5]; + uint32 _reserved[6]; }; diff --git a/headers/private/interface/ToolTipManager.h b/headers/private/interface/ToolTipManager.h index 190d6ab1a3..bfd863fb48 100644 --- a/headers/private/interface/ToolTipManager.h +++ b/headers/private/interface/ToolTipManager.h @@ -18,7 +18,8 @@ class BToolTipManager { public: static BToolTipManager* Manager(); - void ShowTip(BToolTip* tip, BPoint point); + void ShowTip(BToolTip* tip, BPoint point, + void* owner); void HideTip(); void SetShowDelay(bigtime_t time); diff --git a/headers/private/interface/ToolTipWindow.h b/headers/private/interface/ToolTipWindow.h index 51524e5149..22f8226248 100644 --- a/headers/private/interface/ToolTipWindow.h +++ b/headers/private/interface/ToolTipWindow.h @@ -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. */ #ifndef TOOL_TIP_WINDOW_H @@ -11,13 +11,19 @@ namespace BPrivate { + class ToolTipWindow : public BWindow { public: - ToolTipWindow(BToolTip* tip, BPoint where); + ToolTipWindow(BToolTip* tip, BPoint where, + void* owner); virtual void MessageReceived(BMessage* message); + +private: + void* fOwner; }; + } // namespace BPrivate diff --git a/src/kits/interface/ToolTipManager.cpp b/src/kits/interface/ToolTipManager.cpp index 105767bd71..6a57bfeb28 100644 --- a/src/kits/interface/ToolTipManager.cpp +++ b/src/kits/interface/ToolTipManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2009-2012, Axel Dörfler, axeld@pinc-software.de. * Copyright 2009, Stephan Aßmus . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -285,12 +285,13 @@ ToolTipView::ResetWindowFrame(BPoint where) // #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", B_BORDERED_WINDOW_LOOK, kMenuWindowFeel, 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)); @@ -323,6 +324,7 @@ ToolTipWindow::MessageReceived(BMessage* message) BMessage reply(B_REPLY); reply.AddPointer("current", tip); + reply.AddPointer("owner", fOwner); if (message->SendReply(&reply) == B_OK) tip->AcquireReference(); @@ -363,36 +365,30 @@ BToolTipManager::Manager() } -/*static*/ void -BToolTipManager::_InitSingleton() -{ - sDefaultInstance = new BToolTipManager(); -} - - void -BToolTipManager::ShowTip(BToolTip* tip, BPoint point) +BToolTipManager::ShowTip(BToolTip* tip, BPoint point, void* owner) { BToolTip* current = NULL; + void* currentOwner = NULL; BMessage reply; - if (fWindow.SendMessage(kMsgCurrentToolTip, &reply) == B_OK) + if (fWindow.SendMessage(kMsgCurrentToolTip, &reply) == B_OK) { reply.FindPointer("current", (void**)¤t); + reply.FindPointer("owner", ¤tOwner); + } + // Release reference from the message if (current != NULL) current->ReleaseReference(); - if (current == tip) { + if (current == tip || currentOwner == owner) { fWindow.SendMessage(kMsgShowToolTip); return; } fWindow.SendMessage(kMsgHideToolTip); - if (current != NULL) - current->ReleaseReference(); - if (tip != NULL) { - BWindow* window = new BPrivate::ToolTipWindow(tip, point); + BWindow* window = new BPrivate::ToolTipWindow(tip, point, owner); window->Show(); fWindow = BMessenger(window); @@ -459,3 +455,10 @@ BToolTipManager::BToolTipManager() BToolTipManager::~BToolTipManager() { } + + +/*static*/ void +BToolTipManager::_InitSingleton() +{ + sDefaultInstance = new BToolTipManager(); +} diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index b6333c65d4..4d34a389be 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -4817,10 +4817,6 @@ BView::DoLayout() void BView::SetToolTip(const char* text) { - // TODO: temporary work-around for bug #5669 - HideToolTip(); - SetToolTip(static_cast(NULL)); - if (text == NULL || text[0] == '\0') return; @@ -4858,12 +4854,10 @@ BView::ShowToolTip(BToolTip* tip) if (tip == NULL) return; - fVisibleToolTip = tip; - BPoint where; GetMouse(&where, NULL, false); - BToolTipManager::Manager()->ShowTip(tip, ConvertToScreen(where)); + BToolTipManager::Manager()->ShowTip(tip, ConvertToScreen(where), this); } @@ -4871,17 +4865,12 @@ void BView::HideToolTip() { BToolTipManager::Manager()->HideTip(); - fVisibleToolTip = NULL; } bool BView::GetToolTipAt(BPoint point, BToolTip** _tip) { - if (fVisibleToolTip != NULL) { - *_tip = fVisibleToolTip; - return true; - } if (fToolTip != NULL) { *_tip = fToolTip; return true; @@ -5038,7 +5027,6 @@ BView::_InitData(BRect frame, const char* name, uint32 resizingMode, fLayoutData = new LayoutData; fToolTip = NULL; - fVisibleToolTip = NULL; } diff --git a/src/tests/kits/interface/ToolTipTest.cpp b/src/tests/kits/interface/ToolTipTest.cpp index 90f98801f3..262e523112 100644 --- a/src/tests/kits/interface/ToolTipTest.cpp +++ b/src/tests/kits/interface/ToolTipTest.cpp @@ -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. */ #include #include +#include #include #include +#include #include #include @@ -18,9 +20,9 @@ class CustomToolTip : public BToolTip { public: - CustomToolTip() + CustomToolTip(const char* text) { - fView = new BStringView("", "Custom tool tip!"); + fView = new BStringView("", text); fView->SetFont(be_bold_font); 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 { public: Window(); @@ -204,22 +252,44 @@ Window::Window() simple->SetToolTip("This is a really\nsimple 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"); 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()); - BView* immediate = new ImmediateView("3", "Immediate Tool Tip (sticky)"); + BView* immediate = new ImmediateView("5", "Immediate Tool Tip (sticky)"); - BLayoutBuilder::Group<>(this, B_VERTICAL) - .Add(simple) - .Add(custom) - .Add(changing) - .Add(mouse) - .Add(immediate); + BView* pulseString = new PulseStringView("pulseString", + "Periodically changing tool tip text"); + + BView* pulseToolTip = new PulseToolTipView("pulseToolTip", + "Periodically changing tool tip"); + + 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() - : BApplication("application/x-vnd.haiku-tooltiptest") + : + BApplication("application/x-vnd.haiku-tooltiptest") { }