Skip to content

Commit

Permalink
ui: vastly improve online help
Browse files Browse the repository at this point in the history
- Add help and information for Faust, LV2, VST3 etc
- Refactor wigets so that there's only one way to set help on widgets
- Make F1 open help of what's under the cursor in the browser whenever possible
  • Loading branch information
jcelerier committed Dec 16, 2024
1 parent 0ce6f62 commit ace0a5e
Show file tree
Hide file tree
Showing 69 changed files with 714 additions and 286 deletions.
84 changes: 82 additions & 2 deletions src/lib/core/application/SafeQApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "SafeQApplication.hpp"

#include <score/graphics/GraphicsItem.hpp>
#include <score/tools/Debug.hpp>
#include <score/tools/std/Invoke.hpp>

#include <QDebug>
#include <QDesktopServices>
#include <QFileInfo>
#include <QFileOpenEvent>
#include <QGraphicsView>
#include <QThread>

#include <wobjectimpl.h>
Expand Down Expand Up @@ -55,12 +58,87 @@ void SafeQApplication::DebugOutput(
fflush(out_file);
}

#if !defined(SCORE_DEBUG)
Q_GLOBAL_STATIC(QUrl, g_next_help_url_to_open);
Q_GLOBAL_STATIC(QTimer, g_next_help_url_to_open_timer);
static void open_help_url(const QUrl& u)
{
if(g_next_help_url_to_open.isDestroyed())
return;

*g_next_help_url_to_open = u;
g_next_help_url_to_open_timer->stop();
g_next_help_url_to_open_timer->setSingleShot(true);
QObject::disconnect(&*g_next_help_url_to_open_timer, &QTimer::timeout, qApp, nullptr);
QObject::connect(&*g_next_help_url_to_open_timer, &QTimer::timeout, qApp, [] {
QDesktopServices::openUrl(*g_next_help_url_to_open);
});

g_next_help_url_to_open_timer->start(15);
}

static void open_help_url(QGraphicsItem* item)
{
if(!item)
return;

if(auto url = getItemHelpUrl(item->type()); !url.isEmpty())
{
open_help_url(url);
}
else if(auto data = item->data(0xF1); data.isValid())
{
open_help_url(data.toUrl());
}
else
{
open_help_url(item->parentItem());
}
}

static void process_help_event(QObject* receiver, QEvent* event)
{
if(auto res = receiver->property("help_url"); res.isValid())
{
auto url = res.value<QUrl>();
open_help_url(url);
}
else if(auto gv = qobject_cast<QGraphicsView*>(receiver))
{
auto pos = QCursor::pos();
auto pt = gv->viewport()->mapFromGlobal(pos);
open_help_url(gv->itemAt(pt));
}
else if(auto gs = qobject_cast<QGraphicsScene*>(receiver))
{
auto pos = QCursor::pos();
auto gvs = gs->views();
if(!gvs.empty())
{
auto gv = gvs[0];
auto pt = gv->mapFromGlobal(pos);
open_help_url(gv->itemAt(pt));
}
}
else
{
open_help_url(QUrl("https://ossia.io/score-docs"));
}
}

bool SafeQApplication::notify(QObject* receiver, QEvent* event)
{
#if !defined(SCORE_DEBUG)
try
{
#endif
if(event->type() == QEvent::KeyPress)
{
auto ev = (QKeyEvent*)(event);
if(ev->key() == Qt::Key_F1)
process_help_event(receiver, event);
}
return QApplication::notify(receiver, event);
#if !defined(SCORE_DEBUG)
}
catch(std::exception& e)
{
Expand Down Expand Up @@ -92,8 +170,8 @@ bool SafeQApplication::notify(QObject* receiver, QEvent* event)
}

return false;
}
#endif
}

bool SafeQApplication::event(QEvent* ev)
{
Expand All @@ -110,6 +188,8 @@ bool SafeQApplication::event(QEvent* ev)
fileOpened(loadString);
return true;
}
case QEvent::HelpRequest:
return QApplication::event(ev);
default:
return QApplication::event(ev);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/core/application/SafeQApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ class SCORE_LIB_BASE_EXPORT SafeQApplication final : public QApplication
score::information(QApplication::activeWindow(), "", str);
}

bool notify(QObject* receiver, QEvent* event) override;
#endif

bool notify(QObject* receiver, QEvent* event) override;
bool event(QEvent* ev) override;

void fileOpened(const QString& opened)
Expand Down
9 changes: 5 additions & 4 deletions src/lib/core/messages/MessagesPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "MessagesPanel.hpp"

#include <score/tools/Bind.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/application/SafeQApplication.hpp>

Expand Down Expand Up @@ -145,10 +146,10 @@ MessagesPanelDelegate::MessagesPanelDelegate(const score::GUIApplicationContext&
{
qInstallMessageHandler(LogToMessagePanel);
m_widget->setModel(m_itemModel);
m_widget->setStatusTip(
QObject::tr("This panel displays all warnings, errors and logs. \n"
"It is generally a good place to look first if something \n"
"is not behaving as it should"));
score::setHelp(
m_widget, QObject::tr("This panel displays all warnings, errors and logs. \n"
"It is generally a good place to look first if something \n"
"is not behaving as it should"));
m_widget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
connect(
m_widget, &QListView::customContextMenuRequested, this, [this](const QPoint& pos) {
Expand Down
14 changes: 8 additions & 6 deletions src/lib/core/presenter/CoreApplicationPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <score/actions/Menu.hpp>
#include <score/plugins/documentdelegate/DocumentDelegateFactory.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/presenter/CoreActions.hpp>
#include <core/settings/Settings.hpp>
Expand Down Expand Up @@ -280,15 +281,15 @@ GUIElements CoreApplicationPlugin::makeGUIElements()
////// About /////
{
auto about_act = new QAction(m_presenter.view());
about_act->setStatusTip(tr("About ossia score"));
score::setHelp(about_act, tr("About ossia score"));
connect(about_act, &QAction::triggered, this, &CoreApplicationPlugin::about);
e.actions.add<Actions::About>(about_act);
about->addAction(about_act);
}

{
auto website_act = new QAction(m_presenter.view());
website_act->setStatusTip(tr("Open link to ossia website https://ossia.io/"));
score::setHelp(website_act, tr("Open link to ossia website https://ossia.io/"));
connect(website_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://ossia.io/"));
});
Expand All @@ -298,16 +299,17 @@ GUIElements CoreApplicationPlugin::makeGUIElements()

{
auto doc_act = new QAction(m_presenter.view());
doc_act->setStatusTip(
tr("Open link to documentation https://ossia.io/score-docs"));
score::setHelp(
doc_act, tr("Open link to documentation https://ossia.io/score-docs"));
connect(doc_act, &QAction::triggered, this, &CoreApplicationPlugin::help);
e.actions.add<Actions::Documentation>(doc_act);
about->addAction(doc_act);
}

{
auto issues_act = new QAction(m_presenter.view());
issues_act->setStatusTip(tr("Report issues on the Github ossia score repository"));
score::setHelp(
issues_act, tr("Report issues on the Github ossia score repository"));
connect(issues_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://github.com/ossia/score/issues"));
});
Expand All @@ -317,7 +319,7 @@ GUIElements CoreApplicationPlugin::makeGUIElements()

{
auto forum_act = new QAction(m_presenter.view());
forum_act->setStatusTip(tr("Open link to ossia forum https://forum.ossia.io"));
score::setHelp(forum_act, tr("Open link to ossia forum https://forum.ossia.io"));
connect(forum_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://forum.ossia.io"));
});
Expand Down
9 changes: 5 additions & 4 deletions src/lib/core/undo/Panel/UndoPanelDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "UndoPanelDelegate.hpp"

#include <score/widgets/HelpInteraction.hpp>
#include <score/widgets/MarginLess.hpp>

#include <core/document/Document.hpp>
Expand All @@ -17,10 +18,10 @@ UndoPanelDelegate::UndoPanelDelegate(const GUIApplicationContext& ctx)
{
m_widget->setLayout(new score::MarginLess<QVBoxLayout>);
m_widget->setObjectName("HistoryExplorer");
m_widget->setStatusTip(
QObject::tr("This panel shows the history of edits to your scenario. \n"
"This list of possible \"Undo\" and \"Redo\" \n"
"allows you to navigate through your past actions"));
score::setHelp(
m_widget, QObject::tr("This panel shows the history of edits to your scenario. \n"
"This list of possible \"Undo\" and \"Redo\" \n"
"allows you to navigate through your past actions"));
}

UndoPanelDelegate::~UndoPanelDelegate() { }
Expand Down
5 changes: 3 additions & 2 deletions src/lib/core/undo/UndoApplicationPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <score/plugins/application/GUIApplicationPlugin.hpp>
#include <score/tools/Bind.hpp>
#include <score/tools/ForEach.hpp>
#include <score/widgets/HelpInteraction.hpp>
#include <score/widgets/SetIcons.hpp>

#include <core/command/CommandStack.hpp>
Expand All @@ -26,7 +27,7 @@ score::UndoApplicationPlugin::UndoApplicationPlugin(
m_undoAction->setShortcut(QKeySequence::Undo);
m_undoAction->setEnabled(false);
m_undoAction->setText(QObject::tr("Nothing to undo"));
m_undoAction->setToolTip(QObject::tr("Undo (Ctrl+Z)"));
score::setHelp(m_undoAction, QObject::tr("Undo (Ctrl+Z)"));

setIcons(
m_undoAction, QStringLiteral(":/icons/prev_on.png"),
Expand All @@ -41,7 +42,7 @@ score::UndoApplicationPlugin::UndoApplicationPlugin(
m_redoAction->setShortcut(QKeySequence::Redo);
m_redoAction->setEnabled(false);
m_redoAction->setText(QObject::tr("Nothing to redo"));
m_redoAction->setToolTip(QObject::tr("Redo (Ctrl+Shift+Z)"));
score::setHelp(m_redoAction, QObject::tr("Redo (Ctrl+Shift+Z)"));

setIcons(
m_redoAction, QStringLiteral(":/icons/next_on.png"),
Expand Down
4 changes: 3 additions & 1 deletion src/lib/core/view/FixedTabWidget.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "FixedTabWidget.hpp"

#include <score/widgets/HelpInteraction.hpp>

#include <QActionGroup>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
Expand Down Expand Up @@ -135,7 +137,7 @@ QAction* FixedTabWidget::addAction(QWidget* widg, const PanelStatus& v)
btn->setShortcut(v.shortcut);
btn->setIcon(v.icon);

btn->setToolTip(v.prettyName);
score::setHelp(btn, v.prettyName);
btn->setWhatsThis(widg->whatsThis());
btn->setStatusTip(widg->statusTip());

Expand Down
29 changes: 12 additions & 17 deletions src/lib/core/view/HelperPanelDelegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,26 @@ namespace score
class HelperPanelDelegate : public PanelDelegate
{
public:
struct FasterLabel : QLabel
{
QSize sizeHint() const override { return {180, 200}; }
QSize minimumSizeHint() const override { return {180, 100}; }
int heightForWidth(int) const override { return 200; }
};

HelperPanelDelegate(const score::GUIApplicationContext& ctx)
: PanelDelegate{ctx}
{
widg = new QWidget;
widg->setContentsMargins(3, 2, 3, 2);
widg = status = new FasterLabel;
widg->setContentsMargins(3, 5, 3, 2);
widg->setMinimumHeight(100);
widg->setMaximumHeight(100);
widg->setMaximumHeight(200);
widg->setMinimumWidth(180);

auto l = new QVBoxLayout{widg};

struct FasterLabel : QLabel
{
QSize sizeHint() const override { return {180, 100}; }
QSize minimumSizeHint() const override { return {180, 100}; }
int heightForWidth(int) const override { return 100; }
};

status = new FasterLabel;
status->setAlignment(Qt::AlignTop);
status->setTextFormat(Qt::RichText);
status->setText("<i>Remember those quiet evenings</i>");
status->setText("<i>Do the words need changing?</i>");
status->setWordWrap(true);

l->addWidget(status);
l->addStretch(12);
}

QWidget* widget() override { return widg; }
Expand Down
9 changes: 6 additions & 3 deletions src/lib/core/view/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,7 @@ void View::resizeEvent(QResizeEvent* e)

bool score::View::event(QEvent* event)
{
if(event->type() == QEvent::StatusTip)
{
auto tip = ((QStatusTipEvent*)event)->tip();
auto display = [this](QString tip) {
auto idx = tip.indexOf(QChar('\n'));
if(idx != -1)
{
Expand All @@ -464,6 +462,11 @@ bool score::View::event(QEvent* event)
}
tip.replace(QChar('\n'), "<br/>");
m_status->setText(tip);
};

if(event->type() == QEvent::StatusTip)
{
display(((QStatusTipEvent*)event)->tip());
}

return QMainWindow::event(event);
Expand Down
1 change: 1 addition & 0 deletions src/lib/score/actions/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <score/actions/ActionManager.hpp>
#include <score/selection/SelectionStack.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/presenter/DocumentManager.hpp>

Expand Down
20 changes: 20 additions & 0 deletions src/lib/score/graphics/GraphicsItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@
#include <QGraphicsView>
#include <QGuiApplication>

using item_help = ossia::hash_map<int, std::pair<QString, QUrl>>;
#if QT_VERSION > QT_VERSION_CHECK(6, 3, 0)
#include <QApplicationStatic>
Q_APPLICATION_STATIC(item_help, g_itemHelpRegistry);
#else
Q_GLOBAL_STATIC(item_help, g_itemHelpRegistry);
#endif

void registerItemHelp(int itemType, QString tooltip, QUrl url) noexcept
{
auto& val = *g_itemHelpRegistry;
val[itemType] = std::pair<QString, QUrl>{tooltip, url};
}

QUrl getItemHelpUrl(int itemType) noexcept
{
auto& val = *g_itemHelpRegistry;
return val[itemType].second;
}

void deleteGraphicsObject(QGraphicsObject* item)
{
if(item)
Expand Down
Loading

0 comments on commit ace0a5e

Please sign in to comment.