mirror of https://github.com/aseprite/aseprite.git
Improve StatusBar tooltips, add app.tip
This commit is contained in:
parent
6d89a6bc15
commit
25371727df
|
|
@ -34,10 +34,10 @@
|
||||||
#include "app/tools/tool_loop_manager.h"
|
#include "app/tools/tool_loop_manager.h"
|
||||||
#include "app/tx.h"
|
#include "app/tx.h"
|
||||||
#include "app/ui/context_bar.h"
|
#include "app/ui/context_bar.h"
|
||||||
#include "app/ui/doc_view.h"
|
|
||||||
#include "app/ui/editor/editor.h"
|
#include "app/ui/editor/editor.h"
|
||||||
#include "app/ui/editor/tool_loop_impl.h"
|
#include "app/ui/editor/tool_loop_impl.h"
|
||||||
#include "app/ui/main_window.h"
|
#include "app/ui/main_window.h"
|
||||||
|
#include "app/ui/status_bar.h"
|
||||||
#include "app/ui/timeline/timeline.h"
|
#include "app/ui/timeline/timeline.h"
|
||||||
#include "app/ui_context.h"
|
#include "app/ui_context.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
|
|
@ -498,6 +498,30 @@ int App_useTool(lua_State* L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int App_tip(lua_State* L)
|
||||||
|
{
|
||||||
|
const auto* ctx = App::instance()->context();
|
||||||
|
if (!ctx || !ctx->isUIAvailable() || !StatusBar::instance())
|
||||||
|
return 0; // No UI to show the tooltip
|
||||||
|
|
||||||
|
if (!lua_isstring(L, 1))
|
||||||
|
return luaL_error(L, "app.tip() message parameter must be a string");
|
||||||
|
|
||||||
|
const std::string message = lua_tostring(L, 1);
|
||||||
|
if (message.empty())
|
||||||
|
return luaL_error(L, "app.tip() message cannot be empty");
|
||||||
|
|
||||||
|
int duration = 2000;
|
||||||
|
if (lua_isinteger(L, 2)) {
|
||||||
|
const int durationInput = lua_tointeger(L, 2);
|
||||||
|
if (durationInput > 0 && durationInput < 30000) // Reasonable limits
|
||||||
|
duration = lua_tointeger(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBar::instance()->showTip(duration, message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int App_get_events(lua_State* L)
|
int App_get_events(lua_State* L)
|
||||||
{
|
{
|
||||||
push_app_events(L);
|
push_app_events(L);
|
||||||
|
|
@ -820,6 +844,7 @@ const luaL_Reg App_methods[] = {
|
||||||
{ "alert", App_alert },
|
{ "alert", App_alert },
|
||||||
{ "refresh", App_refresh },
|
{ "refresh", App_refresh },
|
||||||
{ "useTool", App_useTool },
|
{ "useTool", App_useTool },
|
||||||
|
{ "tip", App_tip },
|
||||||
{ nullptr, nullptr }
|
{ nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -549,7 +549,10 @@ private:
|
||||||
|
|
||||||
class StatusBar::CustomizedTipWindow : public ui::TipWindow {
|
class StatusBar::CustomizedTipWindow : public ui::TipWindow {
|
||||||
public:
|
public:
|
||||||
CustomizedTipWindow(const std::string& text) : ui::TipWindow(text) {}
|
CustomizedTipWindow(const std::string& text) : ui::TipWindow(text)
|
||||||
|
{
|
||||||
|
setClickBehavior(ClickBehavior::CloseOnClick);
|
||||||
|
}
|
||||||
|
|
||||||
void setInterval(int msecs)
|
void setInterval(int msecs)
|
||||||
{
|
{
|
||||||
|
|
@ -557,9 +560,11 @@ public:
|
||||||
m_timer.reset(new ui::Timer(msecs, this));
|
m_timer.reset(new ui::Timer(msecs, this));
|
||||||
else
|
else
|
||||||
m_timer->setInterval(msecs);
|
m_timer->setInterval(msecs);
|
||||||
|
m_originalInterval = msecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTimer() { m_timer->start(); }
|
void startTimer() const { m_timer->start(); }
|
||||||
|
int originalInterval() const { return m_originalInterval; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(Message* msg) override
|
bool onProcessMessage(Message* msg) override
|
||||||
|
|
@ -569,12 +574,18 @@ protected:
|
||||||
closeWindow(nullptr);
|
closeWindow(nullptr);
|
||||||
m_timer->stop();
|
m_timer->stop();
|
||||||
break;
|
break;
|
||||||
|
case kMouseEnterMessage: m_timer->stop(); break;
|
||||||
|
case kMouseLeaveMessage:
|
||||||
|
m_timer->setInterval(m_originalInterval);
|
||||||
|
m_timer->start();
|
||||||
|
return true; // Avoid PopupWindow closing us.
|
||||||
}
|
}
|
||||||
return ui::TipWindow::onProcessMessage(msg);
|
return ui::TipWindow::onProcessMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ui::Timer> m_timer;
|
std::unique_ptr<ui::Timer> m_timer;
|
||||||
|
int m_originalInterval = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Use a ui::TipWindow with rounded borders, when we add support
|
// TODO Use a ui::TipWindow with rounded borders, when we add support
|
||||||
|
|
@ -797,13 +808,22 @@ bool StatusBar::setStatusText(int msecs, const std::string& msg)
|
||||||
void StatusBar::showTip(int msecs, const std::string& msg)
|
void StatusBar::showTip(int msecs, const std::string& msg)
|
||||||
{
|
{
|
||||||
ASSERT(msecs > 0);
|
ASSERT(msecs > 0);
|
||||||
|
|
||||||
if (m_tipwindow == NULL) {
|
if (m_tipwindow == NULL) {
|
||||||
m_tipwindow = new CustomizedTipWindow(msg);
|
m_tipwindow = new CustomizedTipWindow(msg);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (m_tipwindow->isVisible() && m_tipwindow->text() != msg) {
|
||||||
|
// If the tip window is still visible, append the text on top so
|
||||||
|
// the old message is still readable (unless it's the exact same text)
|
||||||
|
m_tipwindow->setText(m_tipwindow->text() + "\n" + msg);
|
||||||
|
|
||||||
|
// Always use the longest interval to give the user more time to read.
|
||||||
|
msecs = m_tipwindow->originalInterval() > msecs ? m_tipwindow->originalInterval() : msecs;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
m_tipwindow->setText(msg);
|
m_tipwindow->setText(msg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_tipwindow->setInterval(msecs);
|
m_tipwindow->setInterval(msecs);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,13 @@ bool PopupWindow::onProcessMessage(Message* msg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ClickBehavior::CloseOnClick: {
|
||||||
|
if (bounds().contains(mouseMsg->position())) {
|
||||||
|
closeWindow(nullptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ public:
|
||||||
enum class ClickBehavior {
|
enum class ClickBehavior {
|
||||||
DoNothingOnClick,
|
DoNothingOnClick,
|
||||||
CloseOnClickInOtherWindow,
|
CloseOnClickInOtherWindow,
|
||||||
CloseOnClickOutsideHotRegion
|
CloseOnClickOutsideHotRegion,
|
||||||
|
CloseOnClick
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EnterBehavior {
|
enum class EnterBehavior {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue