diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d
index 6d5b257d..89ba5b06 100644
--- a/src/dlangui/core/events.d
+++ b/src/dlangui/core/events.d
@@ -215,6 +215,22 @@ class Action {
return null;
return _accelerators[0].label;
}
+ /// returns tooltip text for action
+ @property dstring tooltipText() {
+ dchar[] buf;
+ // strip out & characters
+ foreach(ch; label) {
+ if (ch != '&')
+ buf ~= ch;
+ }
+ dstring accel = acceleratorText;
+ if (accel.length > 0) {
+ buf ~= " (";
+ buf ~= accel;
+ buf ~= ")";
+ }
+ return cast(dstring)buf;
+ }
/// adds one more accelerator
Action addAccelerator(uint keyCode, uint keyFlags = 0) {
_accelerators ~= Accelerator(keyCode, keyFlags);
diff --git a/src/dlangui/core/i18n.d b/src/dlangui/core/i18n.d
index 1ee09d57..bd268e44 100644
--- a/src/dlangui/core/i18n.d
+++ b/src/dlangui/core/i18n.d
@@ -126,6 +126,12 @@ struct UIString {
_value = null;
return this;
}
+
+ /// returns true if string is empty: neither resource nor string is assigned
+ bool empty() const {
+ return _value.length == 0 && _id.length == 0;
+ }
+
/** Default conversion to dstring */
alias value this;
}
diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d
index 5eef61e1..1d265cec 100644
--- a/src/dlangui/platforms/common/platform.d
+++ b/src/dlangui/platforms/common/platform.d
@@ -252,17 +252,18 @@ class Window {
_tooltip.timerId = setTimer(ownerWidget, delay);
}
+ /// call when tooltip timer is expired
private bool onTooltipTimer() {
_tooltip.timerId = 0;
if (isChild(_tooltip.ownerWidget)) {
- Widget w = _tooltip.ownerWidget.createTooltip();
+ Widget w = _tooltip.ownerWidget.createTooltip(_lastMouseX, _lastMouseY, _tooltip.alignment, _tooltip.x, _tooltip.y);
if (w)
showTooltip(w, _tooltip.ownerWidget, _tooltip.alignment, _tooltip.x, _tooltip.y);
}
return false;
}
- /// hide tooltip if shown
+ /// hide tooltip if shown and cancel tooltip timer if set
void hideTooltip() {
if (_tooltip.popup) {
destroy(_tooltip.popup);
@@ -270,6 +271,8 @@ class Window {
if (_mainWidget)
_mainWidget.invalidate();
}
+ if (_tooltip.timerId)
+ cancelTimer(_tooltip.timerId);
}
/// show tooltip immediately
@@ -506,6 +509,7 @@ class Window {
/// dispatch keyboard event
bool dispatchKeyEvent(KeyEvent event) {
bool res = false;
+ hideTooltip();
PopupWidget modal = modalPopup();
if (event.action == KeyAction.KeyDown || event.action == KeyAction.KeyUp) {
_keyboardModifiers = event.flags;
@@ -783,12 +787,18 @@ class Window {
return false;
}
+ private int _lastMouseX;
+ private int _lastMouseY;
/// dispatch mouse event to window content widgets
bool dispatchMouseEvent(MouseEvent event) {
// ignore events if there is no root
if (_mainWidget is null)
return false;
+ if (event.action == MouseAction.Move) {
+ _lastMouseX = event.x;
+ _lastMouseY = event.y;
+ }
hideTooltip();
PopupWidget modal = modalPopup();
diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d
index 997e0282..e054e92d 100644
--- a/src/dlangui/widgets/styles.d
+++ b/src/dlangui/widgets/styles.d
@@ -144,6 +144,10 @@ immutable string STYLE_TAB_UP_BUTTON_DARK = "TAB_UP_BUTTON_DARK";
/// standard style id for tab control tab button text in dock frame
immutable string STYLE_TAB_UP_BUTTON_DARK_TEXT = "TAB_UP_BUTTON_DARK_TEXT";
+/// standard style id for tooltip popup
+immutable string STYLE_TOOLTIP = "TOOLTIP";
+
+
/// standard style id for toolbars layout
immutable string STYLE_TOOLBAR_HOST = "TOOLBAR_HOST";
/// standard style id for toolbars
diff --git a/src/dlangui/widgets/toolbars.d b/src/dlangui/widgets/toolbars.d
index 7c1f937c..a6351940 100644
--- a/src/dlangui/widgets/toolbars.d
+++ b/src/dlangui/widgets/toolbars.d
@@ -67,6 +67,7 @@ class ToolBarImageButton : ImageButton {
styleId = STYLE_TOOLBAR_BUTTON;
focusable = false;
}
+ mixin ActionTooltipSupport;
}
/// separator for toolbars
@@ -85,6 +86,7 @@ class ToolBarComboBox : ComboBox {
if (items.length > 0)
selectedItemIndex = 0;
}
+ mixin ActionTooltipSupport;
}
/// Layout with buttons
diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d
index e6e6c8a1..9b4da932 100644
--- a/src/dlangui/widgets/widget.d
+++ b/src/dlangui/widgets/widget.d
@@ -683,15 +683,16 @@ class Widget {
}
/// returns true if widget has tooltip to show
- bool hasTooltip() {
+ @property bool hasTooltip() {
return false;
}
- /// will be called from window once tooltip request timer expired
- Widget createTooltip() {
+ /// will be called from window once tooltip request timer expired; if null is returned, popup will not be shown; you can change alignment and position of popup here
+ Widget createTooltip(int mouseX, int mouseY, ref uint alignment, ref int x, ref int y) {
return null;
}
+
/// schedule tooltip
- void scheduleTooltip(long delay = 300, uint alignment = 2 /*PopupAlign.Below*/, int x = 0, int y = 0) {
+ protected void scheduleTooltip(long delay = 300, uint alignment = 2 /*PopupAlign.Below*/, int x = 0, int y = 0) {
if (auto w = window)
w.scheduleTooltip(this, delay, alignment, x, y);
}
@@ -1106,6 +1107,9 @@ class Widget {
return true;
}
}
+ if (event.action == MouseAction.Move && event.flags == 0 && hasTooltip) {
+ scheduleTooltip(200);
+ }
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Right) {
if (canShowPopupMenu(event.x, event.y)) {
showPopupMenu(event.x, event.y);
@@ -1553,3 +1557,21 @@ struct AnimationHelper {
return _timeElapsed >= _maxInterval;
}
}
+
+
+/// mixin this to widget class to support tooltips based on widget's action label
+mixin template ActionTooltipSupport() {
+ /// returns true if widget has tooltip to show
+ override @property bool hasTooltip() {
+ if (!_action || _action.labelValue.empty)
+ return false;
+ return true;
+ }
+ /// will be called from window once tooltip request timer expired; if null is returned, popup will not be shown; you can change alignment and position of popup here
+ override Widget createTooltip(int mouseX, int mouseY, ref uint alignment, ref int x, ref int y) {
+ Widget res = new TextWidget("tooltip", _action.tooltipText);
+ res.styleId = STYLE_TOOLTIP;
+ return res;
+ }
+}
+
diff --git a/views/res/mdpi/tooltip_background.9.png b/views/res/mdpi/tooltip_background.9.png
new file mode 100644
index 00000000..2fa29203
Binary files /dev/null and b/views/res/mdpi/tooltip_background.9.png differ
diff --git a/views/res/theme_default.xml b/views/res/theme_default.xml
index d8664e58..b5863fc1 100644
--- a/views/res/theme_default.xml
+++ b/views/res/theme_default.xml
@@ -300,6 +300,14 @@
layoutHeight="WRAP_CONTENT"
padding="1,1,1,1"
/>
+