Skip to content

Commit

Permalink
tooltips beginning
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Ivanov committed Jul 23, 2014
1 parent e649453 commit 4d6b9e7
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Demo/VisualStudio/tb_static.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<ClCompile Include="..\..\src\tb\tb_tab_container.cpp" />
<ClCompile Include="..\..\src\tb\tb_tempbuffer.cpp" />
<ClCompile Include="..\..\src\tb\tb_toggle_container.cpp" />
<ClCompile Include="..\..\src\tb\tb_tooltips.cpp" />
<ClCompile Include="..\..\src\tb\tb_value.cpp" />
<ClCompile Include="..\..\src\tb\tb_widgets.cpp" />
<ClCompile Include="..\..\src\tb\tb_widgets_common.cpp" />
Expand All @@ -86,6 +87,7 @@
<ClCompile Include="..\..\src\tb\utf8\utf8.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\tb\tb_tooltips.h" />
<ClInclude Include="..\..\tbanimation\tb_animation_utils.h" />
<ClInclude Include="..\..\src\tb\addons\tbimage\tb_image_manager.h" />
<ClInclude Include="..\..\src\tb\addons\tbimage\tb_image_widget.h" />
Expand Down
6 changes: 6 additions & 0 deletions Demo/VisualStudio/tb_static.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@
<ClCompile Include="..\..\src\tb\tb_font_renderer_stb.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\tb\tb_tooltips.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\tb\tb_language.h">
Expand Down Expand Up @@ -434,6 +437,9 @@
<ClInclude Include="..\..\src\tb\animation\tb_widget_animation.h">
<Filter>Source Files\animation</Filter>
</ClInclude>
<ClInclude Include="..\..\src\tb\tb_tooltips.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\integration.txt" />
Expand Down
1 change: 1 addition & 0 deletions Demo/demo01/ui_resources/test_textwindow.tb.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ TBLayout: axis: y, distribution: available
TBButton: id: redo
TBSkinImage: skin: arrow.right
TBButton: text: Clear, id: clear
desc Click for <color #f44>remove</color> all text
TBLayout
gravity left right
distribution-position right bottom
Expand Down
6 changes: 6 additions & 0 deletions resources/default_skin/skin.tb.txt
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,9 @@ elements
bitmap focus_r4.png
cut 11
expand 4
TBTooltip
text-color #fefefe
bitmap slider_handle.png
cut 13
expand 5
padding 1 10
4 changes: 4 additions & 0 deletions src/tb/tb_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "tb_font_renderer.h"
#include "tb_addon.h"
#include "tb_system.h"
#include "tb_tooltips.h"
#include "animation/tb_animation.h"

namespace tb {
Expand All @@ -29,6 +30,8 @@ bool tb_core_init(TBRenderer *renderer, const char *lng_file)
g_font_manager = new TBFontManager();
g_tb_skin = new TBSkin();
g_widgets_reader = TBWidgetsReader::Create();
g_tooltip_mng = new TBTooltipManager();

return TBInitAddons();
}

Expand All @@ -40,6 +43,7 @@ void tb_core_shutdown()
delete g_tb_skin;
delete g_font_manager;
delete g_tb_lng;
delete g_tooltip_mng;
}

bool tb_core_is_initialized()
Expand Down
2 changes: 2 additions & 0 deletions src/tb/tb_popup_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class TBPopupWindow : public TBWindow, private TBWidgetListener
virtual TBWidget *GetEventDestination() { return m_target.Get(); }

virtual bool OnEvent(const TBWidgetEvent &ev);

const TBWidgetSafePointer& GetTargetWidget() { return m_target; }
private:
TBWidgetSafePointer m_target;
// TBWidgetListener
Expand Down
191 changes: 191 additions & 0 deletions src/tb/tb_tooltips.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#include <math.h>

#include "tb_widgets_listener.h"
#include "tb_tooltips.h"
#include "tb_language.h"

using namespace tb;

tb::TBTooltipManager* tb::g_tooltip_mng = nullptr;

unsigned int TBTooltipManager::tooltip_point_offset_y = 20;
unsigned int TBTooltipManager::tooltip_show_delay_ms = 700;
unsigned int TBTooltipManager::tooltip_show_duration_ms = 5000;
unsigned int TBTooltipManager::tooltip_hide_point_dist = 40;


namespace {

const TBID messageShow = TBIDC("TBTooltipManager.show");
const TBID messageHide = TBIDC("TBTooltipManager.hide");

class TTMsgParam: public TBTypedObject
{
public:
TTMsgParam(TBWidget* hovered) : m_hovered(hovered){}

TBWidget* m_hovered;
};

}


TBTooltipWindow::TBTooltipWindow (TBWidget* target)
:TBPopupWindow(target)
{
SetSkinBg("", WIDGET_INVOKE_INFO_NO_CALLBACKS);
SetSettings(WINDOW_SETTINGS_NONE);
m_content.SetSkinBg(TBIDC("TBTooltip"), WIDGET_INVOKE_INFO_NO_CALLBACKS);
m_content.SetIsFocusable(false);
m_content.SetStyling(true);
m_content.SetGravity(WIDGET_GRAVITY_ALL);
m_content.SetReadOnly(true);
m_content.SetMultiline(true);
m_content.SetText(target->GetDescription());
m_content.SetAdaptToContentSize(true);
AddChild(&m_content);
}

TBTooltipWindow::~TBTooltipWindow ()
{
RemoveChild(&m_content);
}

bool TBTooltipWindow::Show (int mouse_x, int mouse_y)
{
m_offset_x = mouse_x;
m_offset_y = mouse_y;

GetTargetWidget().Get()->GetParentRoot()->AddChild(this);
SetRect(GetAlignedRect(m_offset_x, mouse_y));
return true;
}


TBRect TBTooltipWindow::GetAlignedRect (int x, int y)
{
TBWidget *root = GetParentRoot();

SizeConstraints sc(root->GetRect().w, root->GetRect().h);

PreferredSize ps = GetPreferredSize(sc);

TBPoint pos(x, y);
int w = MIN(ps.pref_w, root->GetRect().w);
int h = MIN(ps.pref_h, root->GetRect().h);

x = pos.x + w > root->GetRect().w ? pos.x - w : pos.x;
y = pos.y;
if (pos.y + h > root->GetRect().h)
y = pos.y - TBTooltipManager::tooltip_point_offset_y - h;

return TBRect(x, y, w, h);
}


//////////////////////////////////////////////////////////////////////////

TBTooltipManager::TBTooltipManager ()
:m_tooltip(nullptr), m_last_tipped_widget(nullptr)
{
TBWidgetListener::AddGlobalListener(this);
}

TBTooltipManager::~TBTooltipManager ()
{
TBWidgetListener::RemoveGlobalListener(this);
}

bool TBTooltipManager::OnWidgetInvokeEvent (TBWidget *widget, const TBWidgetEvent &ev)
{
if (ev.type == EVENT_TYPE_POINTER_MOVE && !TBWidget::captured_widget)
{
TBWidget* tipped_widget = GetTippedWidget();
if (m_last_tipped_widget != tipped_widget && tipped_widget)
{
TBMessageData* msg_data = new TBMessageData();
msg_data->v1.SetObject(new TTMsgParam(tipped_widget));
PostMessageDelayed(messageShow, msg_data, tooltip_show_delay_ms);

}else if (m_last_tipped_widget == tipped_widget && tipped_widget && m_tooltip)
{
int x = TBWidget::pointer_move_widget_x;
int y = TBWidget::pointer_move_widget_y;
tipped_widget->ConvertToRoot(x, y);
y += tooltip_point_offset_y;
TBPoint tt_point = m_tooltip->GetOffsetPoint();
if (abs(tt_point.x - x) > (int)tooltip_hide_point_dist || abs(tt_point.y - y) > (int)tooltip_hide_point_dist)
{
KillToolTip();
DeleteShowMessages();
}
}else if (!tipped_widget)
{
KillToolTip();
DeleteShowMessages();
}
m_last_tipped_widget = tipped_widget;
}else// if (ev.type == EVENT_TYPE_POINTER_DOWN || ev.type == EVENT_TYPE_POINTER_UP)
{
KillToolTip();
DeleteShowMessages();
}

return false;
}

void TBTooltipManager::KillToolTip ()
{
if (m_tooltip)
{
m_tooltip->Close();
m_tooltip = nullptr;
}
}

void TBTooltipManager::DeleteShowMessages ()
{
TBMessage* msg;
while((msg = GetMessageByID(messageShow)) != nullptr)
DeleteMessage(msg);
}

TBWidget* TBTooltipManager::GetTippedWidget ()
{
TBWidget* current = TBWidget::hovered_widget;
while(current && current->GetDescription().IsEmpty())
current = current->GetParent();
return current;
}

void TBTooltipManager::OnMessageReceived (TBMessage *msg)
{
if (msg->message == messageShow)
{
TBWidget* tipped_widget = GetTippedWidget();
TTMsgParam* param = static_cast<TTMsgParam*>(msg->data->v1.GetObject());
if (tipped_widget == param->m_hovered)
{
KillToolTip();

m_tooltip = new TBTooltipWindow(tipped_widget);

int x = TBWidget::pointer_move_widget_x;
int y = TBWidget::pointer_move_widget_y;
tipped_widget->ConvertToRoot(x, y);
y += tooltip_point_offset_y;

m_tooltip->Show(x, y);

TBMessageData* msg_data = new TBMessageData();
msg_data->v1.SetObject(new TTMsgParam(m_tooltip));
PostMessageDelayed(messageHide, msg_data, tooltip_show_duration_ms);
}
}else if (msg->message == messageHide)
{
TTMsgParam* param = static_cast<TTMsgParam*>(msg->data->v1.GetObject());
if (m_tooltip == param->m_hovered)
KillToolTip();
}
}

61 changes: 61 additions & 0 deletions src/tb/tb_tooltips.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef TB_TOOLTIPS_H
#define TB_TOOLTIPS_H

#include "tb_widgets_listener.h"
#include "tb_popup_window.h"
#include "tb_editfield.h"

namespace tb {

/** TBTooltipWindow implements functional of tooltip popup, based on TBPopupWindow and contains TBEditField as content viewer*/
class TBTooltipWindow : public TBPopupWindow
{
public:
TBOBJECT_SUBCLASS(TBTooltipWindow, TBPopupWindow);

TBTooltipWindow(TBWidget* target);
virtual ~TBTooltipWindow();

bool Show(int mouse_x, int mouse_y);

TBPoint GetOffsetPoint() const { return TBPoint(m_offset_x, m_offset_y); }

private:
int m_offset_x;
int m_offset_y;

TBRect GetAlignedRect(int x, int y);

TBEditField m_content;
};

/** TBTooltipManager implements logic for show/hiode tooltips*/
class TBTooltipManager : private TBWidgetListener, public TBMessageHandler
{
public:
TBTooltipManager();
virtual ~TBTooltipManager();

static unsigned int tooltip_point_offset_y; ///< offset by Y of tooltip point
static unsigned int tooltip_show_delay_ms; ///< delay in ms before tooltip will be shown
static unsigned int tooltip_show_duration_ms; ///< tooltip display duration
static unsigned int tooltip_hide_point_dist; /// distance by X or Y which used to hide tooltip

private:

virtual bool OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev);
virtual void OnMessageReceived(TBMessage *msg);
void KillToolTip();

void DeleteShowMessages();
TBWidget* GetTippedWidget();

TBTooltipWindow* m_tooltip;
TBWidget* m_last_tipped_widget;
};

extern TBTooltipManager* g_tooltip_mng;

}

#endif
9 changes: 8 additions & 1 deletion src/tb/tb_widgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,13 @@ class TBWidget : public TBTypedObject, public TBLinkOf<TBWidget>
/** Get the text of this widget. Implemented by most widgets (that has text). */
TBStr GetText() { TBStr str; GetText(str); return str; }

/** Connect this widget to a widget value.
/** Get the description string of this widget. Used for tooltips. */
virtual TBStr GetDescription() { return m_desc_str; }

/** Set the description string for this widget. Used for tooltips. */
virtual void SetDescription (const char*desc) { m_desc_str = desc; }

/** Connect this widget to a widget value.
When this widget invoke EVENT_TYPE_CHANGED, it will automatically update the
connected widget value, and any other widgets that may be connected to it.
Expand Down Expand Up @@ -959,6 +965,7 @@ class TBWidget : public TBTypedObject, public TBLinkOf<TBWidget>
LayoutParams *m_layout_params; ///< Layout params, or nullptr.
TBScroller *m_scroller;
TBLongClickTimer *m_long_click_timer;
TBStr m_desc_str;
union {
struct {
uint16 is_group_root : 1;
Expand Down
2 changes: 2 additions & 0 deletions src/tb/tb_widgets_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ bool TBWidgetsReader::CreateWidget(TBWidget *target, TBNode *node, WIDGET_Z add_
new_widget->SetLayoutParams(layout_params);
}

new_widget->SetDescription(node->GetValueString("desc", nullptr));

// Add the new widget to the hiearchy
target->GetContentRoot()->AddChild(new_widget, add_child_z);

Expand Down

0 comments on commit 4d6b9e7

Please sign in to comment.