* 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:
parent
360495a3bf
commit
8318af01b9
@ -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',
|
||||
|
@ -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,
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
@ -347,7 +347,7 @@ private:
|
||||
BView* fTopView;
|
||||
BView* fFocus;
|
||||
BView* fLastMouseMovedView;
|
||||
uint32 _unused1;
|
||||
BMessageRunner* fIdleMouseRunner;
|
||||
BMenuBar* fKeyMenuBar;
|
||||
BButton* fDefaultButton;
|
||||
BList fShortcuts;
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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_ */
|
||||
|
73
headers/private/interface/ToolTip.h
Normal file
73
headers/private/interface/ToolTip.h
Normal 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
|
41
headers/private/interface/ToolTipManager.h
Normal file
41
headers/private/interface/ToolTipManager.h
Normal 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
|
24
headers/private/interface/ToolTipWindow.h
Normal file
24
headers/private/interface/ToolTipWindow.h
Normal 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
|
@ -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
|
||||
|
175
src/kits/interface/ToolTip.cpp
Normal file
175
src/kits/interface/ToolTip.cpp
Normal 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);
|
||||
}
|
||||
|
264
src/kits/interface/ToolTipManager.cpp
Normal file
264
src/kits/interface/ToolTipManager.cpp
Normal 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**)¤t);
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
@ -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,7 +5590,18 @@ _ReservedView10__5BView(BView* view)
|
||||
}
|
||||
|
||||
|
||||
void BView::_ReservedView11(){}
|
||||
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() {}
|
||||
|
@ -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)
|
||||
|
@ -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++)
|
||||
|
262
src/tests/kits/interface/ToolTipTest.cpp
Normal file
262
src/tests/kits/interface/ToolTipTest.cpp
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user