* Added a basic tool tip API, and implementation.

* The BView API can probably be regarded as good enough; the implementation
  might need to be improved over time (also, some things as archivability
  aren't fully implemented yet). The ToolTip.h header should get public once
  finalized.
* Added new B_MOUSE_IDLE message that is sent to a BView after a certain
  time has passed (BToolTipManager::ShowDelay()).
* Added small test app (ToolTipTest) that shows what is already working.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32078 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-08-03 14:47:41 +00:00
parent 360495a3bf
commit 8318af01b9
16 changed files with 1011 additions and 16 deletions

View File

@ -44,6 +44,7 @@ enum {
B_MOUSE_DOWN = '_MDN',
B_MOUSE_MOVED = '_MMV',
B_MOUSE_ENTER_EXIT = '_MEX',
B_MOUSE_IDLE = '_MSI',
B_MOUSE_UP = '_MUP',
B_MOUSE_WHEEL_CHANGED = '_MWC',
B_OPEN_IN_WORKSPACE = '_OWS',

View File

@ -282,8 +282,8 @@ enum color_which {
B_MENU_SELECTED_ITEM_TEXT_COLOR = 8,
B_MENU_SELECTED_BORDER_COLOR = 9,
B_TOOLTIP_BACKGROUND_COLOR = 20,
B_TOOLTIP_TEXT_COLOR = 21,
B_TOOL_TIP_BACKGROUND_COLOR = 20,
B_TOOL_TIP_TEXT_COLOR = 21,
B_SUCCESS_COLOR = 100,
B_FAILURE_COLOR = 101,

View File

@ -124,6 +124,7 @@ class BScrollView;
class BShape;
class BShelf;
class BString;
class BToolTip;
class BWindow;
struct _array_data_;
struct _array_hdr_;
@ -503,7 +504,6 @@ public:
virtual void DrawAfterChildren(BRect r);
// layout related
virtual BSize MinSize();
@ -542,6 +542,19 @@ public:
protected:
virtual void DoLayout();
public:
// tool tip support
void SetToolTip(const char* text);
void SetToolTip(BToolTip* tip);
BToolTip* ToolTip() const;
void ShowToolTip(BToolTip* tip = NULL);
void HideToolTip();
protected:
virtual bool GetToolTipAt(BPoint point, BToolTip** _tip);
private:
void _Layout(bool force, BLayoutContext* context);
@ -556,7 +569,6 @@ private:
friend class BTabView;
friend class BWindow;
virtual void _ReservedView11();
virtual void _ReservedView12();
virtual void _ReservedView13();
virtual void _ReservedView14();
@ -653,8 +665,10 @@ private:
uint32 fMouseEventOptions;
LayoutData* fLayoutData;
BToolTip* fToolTip;
BToolTip* fVisibleToolTip;
uint32 _reserved[7];
uint32 _reserved[5];
};

View File

@ -347,7 +347,7 @@ private:
BView* fTopView;
BView* fFocus;
BView* fLastMouseMovedView;
uint32 _unused1;
BMessageRunner* fIdleMouseRunner;
BMenuBar* fKeyMenuBar;
BButton* fDefaultButton;
BList fShortcuts;

View File

@ -20,7 +20,8 @@ enum {
PERFORM_CODE_GET_HEIGHT_FOR_WIDTH = 1005,
PERFORM_CODE_SET_LAYOUT = 1006,
PERFORM_CODE_INVALIDATE_LAYOUT = 1007,
PERFORM_CODE_DO_LAYOUT = 1008
PERFORM_CODE_DO_LAYOUT = 1008,
PERFORM_CODE_GET_TOOL_TIP_AT = 1009
// support kit
};

View File

@ -45,5 +45,10 @@ struct perform_data_invalidate_layout {
bool descendants;
};
struct perform_data_get_tool_tip_at {
BPoint point;
BToolTip** tool_tip;
bool return_value;
};
#endif /* _BINARY_COMPATIBILITY_INTERFACE_H_ */

View File

@ -0,0 +1,73 @@
/*
* Copyright 2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _TOOL_TIP_H
#define _TOOL_TIP_H
#include <Alignment.h>
#include <Archivable.h>
#include <Point.h>
#include <Referenceable.h>
class BView;
class BTextView;
class BToolTip : public BArchivable, public BReferenceable {
public:
BToolTip();
BToolTip(BMessage* archive);
virtual ~BToolTip();
virtual status_t Archive(BMessage* archive,
bool deep = true) const;
virtual BView* View() const = 0;
virtual void SetSticky(bool enable);
bool IsSticky() const;
virtual void SetMouseRelativeLocation(BPoint location);
BPoint MouseRelativeLocation() const;
virtual void SetAlignment(BAlignment alignment);
BAlignment Alignment() const;
private:
BToolTip(const BToolTip& other);
BToolTip& operator=(const BToolTip &other);
void _InitData();
private:
bool fIsSticky;
BPoint fRelativeLocation;
BAlignment fAlignment;
};
class BTextToolTip : public BToolTip {
public:
BTextToolTip(const char* text);
BTextToolTip(BMessage* archive);
virtual ~BTextToolTip();
static BTextToolTip* Instantiate(BMessage* archive);
virtual status_t Archive(BMessage* archive,
bool deep = true) const;
virtual BView* View() const;
const char* Text() const;
void SetText(const char* text);
private:
void _InitData(const char* text);
private:
BTextView* fTextView;
};
#endif // _TOOL_TIP_H

View File

@ -0,0 +1,41 @@
/*
* Copyright 2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _TOOL_TIP_MANAGER_H
#define _TOOL_TIP_MANAGER_H
#include <Messenger.h>
#include <Point.h>
class BToolTip;
class BToolTipManager {
public:
static BToolTipManager* Manager();
void ShowTip(BToolTip* tip, BPoint point);
void HideTip();
void SetShowDelay(bigtime_t time);
bigtime_t ShowDelay() const;
void SetHideDelay(bigtime_t time);
bigtime_t HideDelay() const;
private:
BToolTipManager();
virtual ~BToolTipManager();
BMessenger fWindow;
bigtime_t fShowDelay;
bigtime_t fHideDelay;
static BToolTipManager* sDefaultInstance;
};
#endif // _TOOL_TIP_MANAGER_H

View File

@ -0,0 +1,24 @@
/*
* Copyright 2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef TOOL_TIP_WINDOW_H
#define TOOL_TIP_WINDOW_H
#include <Window.h>
namespace BPrivate {
class ToolTipWindow : public BWindow {
public:
ToolTipWindow(BToolTip* tip, BPoint where);
virtual void MessageReceived(BMessage* message);
};
} // namespace BPrivate
#endif // TOOL_TIP_WINDOW_H

View File

@ -122,6 +122,8 @@ MergeObject <libbe>interface_kit.o :
TextControl.cpp
TextInput.cpp
TextView.cpp
ToolTip.cpp
ToolTipManager.cpp
TwoDimensionalLayout.cpp
View.cpp
ViewLayoutItem.cpp

View File

@ -0,0 +1,175 @@
/*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <ToolTip.h>
#include <new>
#include <Message.h>
#include <TextView.h>
BToolTip::BToolTip()
{
_InitData();
}
BToolTip::BToolTip(BMessage* archive)
{
_InitData();
bool sticky;
if (archive->FindBool("sticky", &sticky) == B_OK)
fIsSticky = sticky;
// TODO!
}
BToolTip::~BToolTip()
{
}
status_t
BToolTip::Archive(BMessage* archive, bool deep) const
{
status_t status = BArchivable::Archive(archive, deep);
if (fIsSticky)
status = archive->AddBool("sticky", fIsSticky);
// TODO!
return status;
}
void
BToolTip::SetSticky(bool enable)
{
fIsSticky = enable;
}
bool
BToolTip::IsSticky() const
{
return fIsSticky;
}
void
BToolTip::SetMouseRelativeLocation(BPoint location)
{
fRelativeLocation = location;
}
BPoint
BToolTip::MouseRelativeLocation() const
{
return fRelativeLocation;
}
void
BToolTip::SetAlignment(BAlignment alignment)
{
fAlignment = alignment;
}
BAlignment
BToolTip::Alignment() const
{
return fAlignment;
}
void
BToolTip::_InitData()
{
fIsSticky = false;
fRelativeLocation = BPoint(20, 20);
fAlignment = BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM);
}
// #pragma mark -
BTextToolTip::BTextToolTip(const char* text)
{
_InitData(text);
}
BTextToolTip::BTextToolTip(BMessage* archive)
{
// TODO!
}
BTextToolTip::~BTextToolTip()
{
delete fTextView;
}
/*static*/ BTextToolTip*
BTextToolTip::Instantiate(BMessage* archive)
{
if (!validate_instantiation(archive, "BTextToolTip"))
return NULL;
return new(std::nothrow) BTextToolTip(archive);
}
status_t
BTextToolTip::Archive(BMessage* archive, bool deep) const
{
status_t status = BToolTip::Archive(archive, deep);
// TODO!
return status;
}
BView*
BTextToolTip::View() const
{
return fTextView;
}
const char*
BTextToolTip::Text() const
{
return fTextView->Text();
}
void
BTextToolTip::SetText(const char* text)
{
fTextView->SetText(text);
}
void
BTextToolTip::_InitData(const char* text)
{
fTextView = new BTextView("tool tip text");
fTextView->SetText(text);
fTextView->MakeEditable(false);
fTextView->SetViewColor(ui_color(B_TOOL_TIP_BACKGROUND_COLOR));
rgb_color color = ui_color(B_TOOL_TIP_TEXT_COLOR);
fTextView->SetFontAndColor(NULL, 0, &color);
fTextView->SetWordWrap(false);
}

View File

@ -0,0 +1,264 @@
/*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <ToolTipManager.h>
#include <ToolTipWindow.h>
#include <Autolock.h>
#include <LayoutBuilder.h>
#include <MessageRunner.h>
#include <ToolTip.h>
BToolTipManager* BToolTipManager::sDefaultInstance;
static BLocker sLock("tool tip manager");
static const uint32 kMsgHideToolTip = 'hide';
static const uint32 kMsgShowToolTip = 'show';
static const uint32 kMsgCurrentToolTip = 'curr';
static const uint32 kMsgCloseToolTip = 'clos';
namespace BPrivate {
class ToolTipView : public BView {
public:
ToolTipView(BToolTip* tip)
:
BView("tool tip", B_WILL_DRAW),
fToolTip(tip),
fHidden(false)
{
fToolTip->AcquireReference();
SetViewColor(ui_color(B_TOOL_TIP_BACKGROUND_COLOR));
BGroupLayout* layout = new BGroupLayout(B_VERTICAL);
layout->SetInsets(5, 5, 5, 5);
SetLayout(layout);
AddChild(fToolTip->View());
}
virtual ~ToolTipView()
{
fToolTip->ReleaseReference();
}
virtual void AttachedToWindow()
{
SetEventMask(B_POINTER_EVENTS, 0);
}
virtual void DetachedFromWindow()
{
RemoveChild(fToolTip->View());
// don't delete this one!
}
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
if (fToolTip->IsSticky()) {
// TODO: move window with mouse!
Window()->MoveTo(
ConvertToScreen(where) + fToolTip->MouseRelativeLocation());
} else if (transit == B_ENTERED_VIEW) {
// close instantly if the user managed to enter
Window()->Quit();
} else {
// close with the preferred delay in case the mouse just moved
HideTip();
}
}
void HideTip()
{
if (fHidden)
return;
BMessage quit(kMsgCloseToolTip);
BMessageRunner::StartSending(Window(), &quit,
BToolTipManager::Manager()->HideDelay(), 1);
fHidden = true;
}
void ShowTip()
{
fHidden = false;
}
BToolTip* Tip() const { return fToolTip; }
bool IsTipHidden() const { return fHidden; }
private:
BToolTip* fToolTip;
bool fHidden;
};
ToolTipWindow::ToolTipWindow(BToolTip* tip, BPoint where)
:
BWindow(BRect(0, 0, 250, 10), "tool tip", B_BORDERED_WINDOW_LOOK,
B_FLOATING_APP_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE
| B_AUTO_UPDATE_SIZE_LIMITS | B_AVOID_FRONT | B_AVOID_FOCUS)
{
MoveTo(where + tip->MouseRelativeLocation());
// TODO: take alignment into account!
SetLayout(new BGroupLayout(B_VERTICAL));
AddChild(new ToolTipView(tip));
BSize size = ChildAt(0)->PreferredSize();
ResizeTo(size.width, size.height);
//AddChild(BLayoutBuilder::Group<>(B_VERTICAL).Add(new ToolTipView(tip)));
}
void
ToolTipWindow::MessageReceived(BMessage* message)
{
ToolTipView* view = static_cast<ToolTipView*>(ChildAt(0));
switch (message->what) {
case kMsgHideToolTip:
view->HideTip();
break;
case kMsgCurrentToolTip:
{
BToolTip* tip = view->Tip();
BMessage reply(B_REPLY);
reply.AddPointer("current", tip);
if (message->SendReply(&reply) == B_OK)
tip->AcquireReference();
break;
}
case kMsgShowToolTip:
view->ShowTip();
break;
case kMsgCloseToolTip:
if (view->IsTipHidden())
Quit();
break;
default:
BWindow::MessageReceived(message);
}
}
} // namespace BPrivate
// #pragma mark -
/*static*/ BToolTipManager*
BToolTipManager::Manager()
{
BAutolock _(sLock);
if (sDefaultInstance == NULL)
sDefaultInstance = new BToolTipManager();
return sDefaultInstance;
}
void
BToolTipManager::ShowTip(BToolTip* tip, BPoint point)
{
BToolTip* current = NULL;
BMessage reply;
if (fWindow.SendMessage(kMsgCurrentToolTip, &reply) == B_OK)
reply.FindPointer("current", (void**)&current);
if (current != NULL)
current->ReleaseReference();
if (current == tip) {
fWindow.SendMessage(kMsgShowToolTip);
return;
}
fWindow.SendMessage(kMsgHideToolTip);
if (current != NULL)
current->ReleaseReference();
if (tip != NULL) {
BWindow* window = new BPrivate::ToolTipWindow(tip, point);
window->Show();
fWindow = BMessenger(window);
}
}
void
BToolTipManager::HideTip()
{
fWindow.SendMessage(kMsgHideToolTip);
}
void
BToolTipManager::SetShowDelay(bigtime_t time)
{
// between 10ms and 3s
if (time < 10000)
time = 10000;
else if (time > 3000000)
time = 3000000;
fShowDelay = time;
}
bigtime_t
BToolTipManager::ShowDelay() const
{
return fShowDelay;
}
void
BToolTipManager::SetHideDelay(bigtime_t time)
{
// between 0 and 0.5s
if (time < 0)
time = 0;
else if (time > 500000)
time = 500000;
fHideDelay = time;
}
bigtime_t
BToolTipManager::HideDelay() const
{
return fHideDelay;
}
BToolTipManager::BToolTipManager()
:
fShowDelay(750000),
fHideDelay(50000)
{
}
BToolTipManager::~BToolTipManager()
{
}

View File

@ -54,6 +54,8 @@
#include <ServerProtocol.h>
#include <ServerProtocolStructs.h>
#include <ShapePrivate.h>
#include <ToolTip.h>
#include <ToolTipManager.h>
#include <TokenSpace.h>
#include <ViewPrivate.h>
@ -579,6 +581,9 @@ BView::~BView()
RemoveSelf();
if (fToolTip != NULL)
fToolTip->ReleaseReference();
// TODO: see about BShelf! must I delete it here? is it deleted by
// the window?
@ -4171,6 +4176,18 @@ BView::MessageReceived(BMessage* msg)
FrameMoved(fParentOffset);
break;
case B_MOUSE_IDLE:
{
BPoint where;
if (msg->FindPoint("be:view_where", &where) != B_OK)
break;
BToolTip* tip;
if (GetToolTipAt(where, &tip))
ShowToolTip(tip);
break;
}
case B_MOUSE_WHEEL_CHANGED:
{
BScrollBar* horizontal = ScrollBar(B_HORIZONTAL);
@ -4339,6 +4356,14 @@ BView::Perform(perform_code code, void* _data)
BView::DoLayout();
return B_OK;
}
case PERFORM_CODE_GET_TOOL_TIP_AT:
{
perform_data_get_tool_tip_at* data
= (perform_data_get_tool_tip_at*)_data;
data->return_value
= BView::GetToolTipAt(data->point, data->tool_tip);
return B_OK;
}
}
return BHandler::Perform(code, _data);
@ -4612,6 +4637,74 @@ BView::DoLayout()
}
void
BView::SetToolTip(const char* text)
{
SetToolTip(new BTextToolTip(text));
}
void
BView::SetToolTip(BToolTip* tip)
{
if (fToolTip == tip)
return;
if (fToolTip != NULL)
fToolTip->ReleaseReference();
fToolTip = tip;
if (fToolTip != NULL)
fToolTip->AcquireReference();
}
BToolTip*
BView::ToolTip() const
{
return fToolTip;
}
void
BView::ShowToolTip(BToolTip* tip)
{
if (tip == NULL)
return;
fVisibleToolTip = tip;
BPoint where;
GetMouse(&where, NULL, false);
BToolTipManager::Manager()->ShowTip(tip, ConvertToScreen(where));
}
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;
}
*_tip = NULL;
return false;
}
void
BView::_Layout(bool force, BLayoutContext* context)
{
@ -4715,6 +4808,9 @@ BView::_InitData(BRect frame, const char* name, uint32 resizingMode,
fMouseEventOptions = 0;
fLayoutData = new LayoutData;
fToolTip = NULL;
fVisibleToolTip = NULL;
}
@ -5494,12 +5590,23 @@ _ReservedView10__5BView(BView* view)
}
void BView::_ReservedView11(){}
void BView::_ReservedView12(){}
void BView::_ReservedView13(){}
void BView::_ReservedView14(){}
void BView::_ReservedView15(){}
void BView::_ReservedView16(){}
extern "C" bool
_ReservedView11__5BView(BView* view, BPoint point, BToolTip** _toolTip)
{
// GetToolTipAt()
perform_data_get_tool_tip_at data;
data.point = point;
data.tool_tip = _toolTip;
view->Perform(PERFORM_CODE_GET_TOOL_TIP_AT, &data);
return data.return_value;
}
void BView::_ReservedView12() {}
void BView::_ReservedView13() {}
void BView::_ReservedView14() {}
void BView::_ReservedView15() {}
void BView::_ReservedView16() {}
BView::BView(const BView& other)

View File

@ -43,6 +43,8 @@
#include <PortLink.h>
#include <ServerProtocol.h>
#include <TokenSpace.h>
#include <ToolTipManager.h>
#include <ToolTipWindow.h>
#include <tracker_private.h>
#include <WindowPrivate.h>
@ -1209,6 +1211,21 @@ FrameMoved(origin);
msg->FindPoint("be:view_where", &where);
msg->FindInt32("buttons", (int32*)&buttons);
delete fIdleMouseRunner;
if (transit != B_EXITED_VIEW && transit != B_OUTSIDE_VIEW) {
// Start new idle runner
BMessage idle(B_MOUSE_IDLE);
idle.AddPoint("be:view_where", where);
fIdleMouseRunner = new BMessageRunner(
BMessenger(NULL, this), &idle,
BToolTipManager::Manager()->ShowDelay(), 1);
} else {
fIdleMouseRunner = NULL;
if (dynamic_cast<BPrivate::ToolTipWindow*>(this) == NULL)
BToolTipManager::Manager()->HideTip();
}
BMessage* dragMessage = NULL;
if (msg->HasMessage("be:drag_message")) {
dragMessage = new BMessage();
@ -2595,6 +2612,7 @@ BWindow::_InitData(BRect frame, const char* title, window_look look,
fTopView = NULL;
fFocus = NULL;
fLastMouseMovedView = NULL;
fIdleMouseRunner = NULL;
fKeyMenuBar = NULL;
fDefaultButton = NULL;
@ -3089,6 +3107,7 @@ BWindow::_DetermineTarget(BMessage* message, BHandler* target)
case B_MOUSE_UP:
case B_MOUSE_MOVED:
case B_MOUSE_WHEEL_CHANGED:
case B_MOUSE_IDLE:
// is there a token of the view that is currently under the mouse?
int32 token;
if (message->FindInt32("_view_token", &token) == B_OK) {
@ -3183,7 +3202,8 @@ BWindow::_UnpackMessage(unpack_cookie& cookie, BMessage** _message,
// message directly (but not to the focus view)
for (int32 token; !cookie.tokens_scanned
&& cookie.message->FindInt32("_token", cookie.index, &token) == B_OK;
&& cookie.message->FindInt32("_token", cookie.index, &token)
== B_OK;
cookie.index++) {
// focus view is preferred and should get its message directly
if (token == cookie.focus_token) {
@ -3294,7 +3314,8 @@ BWindow::_SanitizeMessage(BMessage* message, BHandler* target, bool usePreferred
viewUnderMouse = _FindView(token);
// add transit information
uint32 transit = _TransitForMouseMoved(view, viewUnderMouse);;
uint32 transit
= _TransitForMouseMoved(view, viewUnderMouse);
message->AddInt32("be:transit", transit);
if (usePreferred)

View File

@ -3,7 +3,7 @@ SubDir HAIKU_TOP src tests kits interface ;
SetSubDirSupportedPlatformsBeOSCompatible ;
AddSubDirSupportedPlatforms libbe_test ;
UsePrivateHeaders interface ;
UsePrivateHeaders interface shared ;
# Let Jam know where to find some of our source files
SEARCH_SOURCE += [ FDirName $(SUBDIR) balert ] ;
@ -90,6 +90,11 @@ SimpleTest StatusBarTest :
: be $(TARGET_LIBSUPC++)
;
SimpleTest ToolTipTest :
ToolTipTest.cpp
: be $(TARGET_LIBSUPC++)
;
SimpleTest GetMouseTest :
GetMouseTest.cpp
: be $(TARGET_LIBSUPC++)

View File

@ -0,0 +1,262 @@
/*
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <Application.h>
#include <Box.h>
#include <LayoutBuilder.h>
#include <MessageRunner.h>
#include <StringView.h>
#include <Window.h>
#include <ToolTip.h>
#include <stdio.h>
class CustomToolTip : public BToolTip {
public:
CustomToolTip()
{
fView = new BStringView("", "Custom tool tip!");
fView->SetFont(be_bold_font);
fView->SetHighColor(255, 0, 0);
}
virtual ~CustomToolTip()
{
delete fView;
}
virtual BView* View() const
{
return fView;
}
private:
BStringView* fView;
};
class ChangingView : public BStringView {
public:
ChangingView()
:
BStringView("changing", ""),
fNumber(0)
{
}
virtual ~ChangingView()
{
}
virtual void AttachedToWindow()
{
BStringView::AttachedToWindow();
BMessage update('updt');
fRunner = new BMessageRunner(this, &update, 100000);
}
virtual void DetachedFromWindow()
{
delete fRunner;
}
virtual void MessageReceived(BMessage* message)
{
if (message->what == 'updt') {
char text[42];
snprintf(text, sizeof(text), "%d", ++fNumber);
SetText(text);
}
}
private:
BMessageRunner* fRunner;
int fNumber;
};
class ChangingToolTip : public BToolTip {
public:
ChangingToolTip()
{
fView = new ChangingView();
fView->SetFont(be_bold_font);
}
virtual ~ChangingToolTip()
{
delete fView;
}
virtual BView* View() const
{
return fView;
}
private:
BStringView* fView;
};
class MouseView : public BStringView {
public:
MouseView()
:
BStringView("mouse", "x:y")
{
}
virtual ~MouseView()
{
}
virtual void AttachedToWindow()
{
BStringView::AttachedToWindow();
SetEventMask(B_POINTER_EVENTS, 0);
}
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
ConvertToScreen(&where);
char text[42];
snprintf(text, sizeof(text), "%g:%g", where.x, where.y);
SetText(text);
}
};
class MouseToolTip : public BToolTip {
public:
MouseToolTip()
{
fView = new MouseView();
SetSticky(true);
}
virtual ~MouseToolTip()
{
delete fView;
}
virtual BView* View() const
{
return fView;
}
private:
BStringView* fView;
};
class ImmediateView : public BStringView {
public:
ImmediateView(const char* name, const char* label)
:
BStringView(name, label)
{
SetToolTip("Easy but immediate!");
ToolTip()->SetSticky(true);
}
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
if (transit == B_ENTERED_VIEW)
ShowToolTip(ToolTip());
}
};
class Window : public BWindow {
public:
Window();
virtual bool QuitRequested();
};
class Application : public BApplication {
public:
Application();
virtual void ReadyToRun();
};
// #pragma mark -
Window::Window()
:
BWindow(BRect(100, 100, 520, 430), "ToolTip-Test",
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
{
BView* simple = new BStringView("1", "Simple Tool Tip");
simple->SetToolTip("This is a really\nsimple tool tip!");
BView* custom = new BStringView("2", "Custom Tool Tip");
custom->SetToolTip(new CustomToolTip());
BView* changing = new BStringView("3", "Changing Tool Tip");
changing->SetToolTip(new ChangingToolTip());
BView* mouse = new BStringView("3", "Mouse Tool Tip");
mouse->SetToolTip(new MouseToolTip());
BView* immediate = new ImmediateView("3", "Immediate Tool Tip");
BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(simple)
.Add(custom)
.Add(changing)
.Add(mouse)
.Add(immediate);
}
bool
Window::QuitRequested()
{
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
// #pragma mark -
Application::Application()
: BApplication("application/x-vnd.haiku-tooltiptest")
{
}
void
Application::ReadyToRun()
{
BWindow *window = new Window();
window->Show();
}
// #pragma mark -
int
main(int argc, char **argv)
{
Application app;
app.Run();
return 0;
}