renamed keynav to navigation

This commit is contained in:
Igor Korsukov 2021-04-19 11:58:33 +02:00 committed by pereverzev+v
parent 56a65a2cdd
commit ba573e4a71
62 changed files with 1066 additions and 613 deletions

View File

@ -71,7 +71,7 @@ DockPage {
{ "name": "vst", "title": "VST" },
{ "name": "plugins", "title": "Plugins" },
{ "name": "autobot", "title": "Autobot" },
{ "name": "keynav", "title": "KeyNav" }
{ "name": "navigation", "title": "KeyNav" }
]
onSelected: {
@ -102,7 +102,7 @@ DockPage {
case "vst": currentComp = vstComponent; break
case "plugins": currentComp = pluginsComp; break
case "autobot": currentComp = autobotComp; break
case "keynav": currentComp = keynavComp; break
case "navigation": currentComp = keynavComp; break
}
}

View File

@ -37,7 +37,7 @@ Rectangle {
border.color: "#75507b"
border.width: keynavsec.active ? 4 : 0
KeyNavigationSection {
NavigationSection {
id: keynavsec
onActiveChanged: {
console.debug("KeyNavSection.qml active: " + keynavsec.active)

View File

@ -45,7 +45,7 @@ Rectangle {
root.clicked(info)
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavsec
onActiveChanged: {
@ -62,8 +62,8 @@ Rectangle {
FlatButton {
id: btn1
keynav.subsection: keynavsec
keynav.order: 1
navigation.panel: keynavsec
navigation.order: 1
anchors.verticalCenter: parent.verticalCenter
height: 24
width: 24
@ -73,8 +73,8 @@ Rectangle {
FlatButton {
id: btn2
keynav.subsection: keynavsec
keynav.order: 2
navigation.panel: keynavsec
navigation.order: 2
anchors.verticalCenter: parent.verticalCenter
height: 24
width: 24
@ -84,8 +84,8 @@ Rectangle {
FlatButton {
id: btn3
keynav.subsection: keynavsec
keynav.order: 3
navigation.panel: keynavsec
navigation.order: 3
anchors.verticalCenter: parent.verticalCenter
height: 24
width: 24

View File

@ -30,7 +30,7 @@ Rectangle {
width: radioButtonList.contentWidth
height: radioButtonList.contentHeight
property alias keynav: keynavSub
property alias navigation: keynavSub
property var currentUri: "musescore://home"
property var items: [
@ -58,7 +58,7 @@ Rectangle {
root.selected(uri)
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "MainToolBar"
}
@ -78,9 +78,9 @@ Rectangle {
spacing: 0
leftPadding: 12
keynav.name: modelData["title"]
keynav.subsection: keynavSub
keynav.order: model.index
navigation.name: modelData["title"]
navigation.panel: keynavSub
navigation.order: model.index
checked: modelData["uri"] === root.currentUri
title: modelData["title"]

View File

@ -44,28 +44,28 @@ DockPage {
property NotationPageModel pageModel: NotationPageModel {}
property KeyNavigationSection keynavNoteInputSec: KeyNavigationSection {
property NavigationSection keynavNoteInputSec: NavigationSection {
name: "NoteInputSection"
order: 2
}
property KeyNavigationSection keynavLeftPanelSec: KeyNavigationSection {
property NavigationSection keynavLeftPanelSec: NavigationSection {
name: "LeftPanel"
order: 3
}
property KeyNavigationSection keynavRightPanelSec: KeyNavigationSection {
property NavigationSection keynavRightPanelSec: NavigationSection {
name: "RightPanel"
order: 4
}
property KeyNavigationSubSection keynavLeftPanelTabsSubSec: KeyNavigationSubSection {
property NavigationPanel keynavLeftPanelTabsSubSec: NavigationPanel {
name: "LeftPanelTabs"
section: keynavLeftPanelSec
order: 1
}
property KeyNavigationSubSection keynavRightPanelTabsSubSec: KeyNavigationSubSection {
property NavigationPanel keynavRightPanelTabsSubSec: NavigationPanel {
name: "RightPanelTabs"
section: keynavRightPanelSec
order: 1
@ -124,8 +124,8 @@ DockPage {
content: NoteInputBar {
color: notationNoteInputBar.color
orientation: notationNoteInputBar.orientation
keynav.section: keynavNoteInputSec
keynav.order: 1
navigation.section: keynavNoteInputSec
navigation.order: 1
}
}
@ -153,10 +153,10 @@ DockPage {
notationPage.pageModel.isPalettePanelVisible = false
}
property KeyNavigationControl keynavTab: KeyNavigationControl {
property NavigationControl keynavTab: NavigationControl {
name: "PaletteTab"
order: 1 //! TODO Needs order from DockPanel
subsection: notationPage.keynavPanelTabSubSec(palettePanel.area)
panel: notationPage.keynavPanelTabSubSec(palettePanel.area)
onActiveChanged: {
if (active) {
palettePanel.forceActiveFocus()
@ -192,10 +192,10 @@ DockPage {
notationPage.pageModel.isInstrumentsPanelVisible = false
}
property KeyNavigationControl keynavTab: KeyNavigationControl {
property NavigationControl keynavTab: NavigationControl {
name: "InstrumentsTab"
order: 2 //! TODO Needs order from DockPanel
subsection: notationPage.keynavPanelTabSubSec(instrumentsPanel.area)
panel: notationPage.keynavPanelTabSubSec(instrumentsPanel.area)
onActiveChanged: {
if (active) {
instrumentsPanel.forceActiveFocus()
@ -232,10 +232,10 @@ DockPage {
notationPage.pageModel.isInspectorPanelVisible = false
}
property KeyNavigationControl keynavTab: KeyNavigationControl {
property NavigationControl keynavTab: NavigationControl {
name: "InspectorTab"
order: 3 //! TODO Needs order from DockPanel
subsection: notationPage.keynavPanelTabSubSec(inspectorPanel.area)
panel: notationPage.keynavPanelTabSubSec(inspectorPanel.area)
onActiveChanged: {
if (active) {
inspectorPanel.forceActiveFocus()

View File

@ -84,8 +84,7 @@ DockWindow {
property AppMenuModel appMenuModel: AppMenuModel {}
property StartupModel startupModel: StartupModel {}
property KeyNavigationSection topToolKeyNavSec: KeyNavigationSection {
id: keynavSec
property NavigationSection topToolNavSec: NavigationSection {
name: "TopTool"
order: 1
}
@ -114,12 +113,12 @@ DockWindow {
content: MainToolBar {
color: dockWindow.color
keynav.section: topToolKeyNavSec
keynav.order: 1
navigation.section: topToolNavSec
navigation.order: 1
currentUri: dockWindow.currentPageUri
keynav.onActiveChanged: {
if (keynav.active) {
navigation.onActiveChanged: {
if (navigation.active) {
mainToolBar.forceActiveFocus()
}
}
@ -145,11 +144,11 @@ DockWindow {
id: notationToolBarContent
color: dockWindow.color
keynav.section: topToolKeyNavSec
keynav.order: 2
keynav.enabled: notationToolBar.visible
navigation.section: topToolNavSec
navigation.order: 2
navigation.enabled: notationToolBar.visible
onActiveFocusRequested: {
if (keynav.active) {
if (navigation.active) {
notationToolBar.forceActiveFocus()
}
}
@ -181,9 +180,9 @@ DockWindow {
id: playbackToolBarContent
color: dockWindow.color
keynav.section: topToolKeyNavSec
keynav.order: 3
keynav.enabled: dockWindow.isNotationPage
navigation.section: topToolNavSec
navigation.order: 3
navigation.enabled: dockWindow.isNotationPage
floating: playbackToolBar.floating

View File

@ -55,7 +55,7 @@ DockPage {
case "vst": root.central = vstComponent; break
case "plugins": root.central = pluginsComp; break
case "autobot": root.central = autobotComp; break
case "keynav": root.central = keynavComp; break
case "navigation": root.central = keynavComp; break
}
}
@ -89,7 +89,7 @@ DockPage {
{ "name": "vst", "title": "VST" },
{ "name": "plugins", "title": "Plugins" },
{ "name": "autobot", "title": "Autobot" },
{ "name": "keynav", "title": "KeyNav" }
{ "name": "navigation", "title": "KeyNav" }
]
onSelected: {

View File

@ -47,7 +47,7 @@ DockPage {
property NotationPageModel pageModel: NotationPageModel {}
property KeyNavigationSection noteInputKeyNavSec: KeyNavigationSection {
property NavigationSection noteInputKeyNavSec: NavigationSection {
id: keynavSec
name: "NoteInputSection"
order: 2

View File

@ -22,11 +22,11 @@
<seq>Shift+`</seq>
</SC>
<SC>
<key>nav-next-subsection</key>
<key>nav-next-panel</key>
<seq>Tab</seq>
</SC>
<SC>
<key>nav-prev-subsection</key>
<key>nav-prev-panel</key>
<seq>Shift+Tab</seq>
</SC>
<SC>

View File

@ -22,11 +22,11 @@
<seq>Shift+`</seq>
</SC>
<SC>
<key>nav-next-subsection</key>
<key>nav-next-panel</key>
<seq>Tab</seq>
</SC>
<SC>
<key>nav-prev-subsection</key>
<key>nav-prev-panel</key>
<seq>Shift+Tab</seq>
</SC>
<SC>

View File

@ -60,8 +60,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/iuiactionsregister.h
${CMAKE_CURRENT_LIST_DIR}/iuiactionsmodule.h
${CMAKE_CURRENT_LIST_DIR}/iuicontextresolver.h
${CMAKE_CURRENT_LIST_DIR}/ikeynavigation.h
${CMAKE_CURRENT_LIST_DIR}/ikeynavigationcontroller.h
${CMAKE_CURRENT_LIST_DIR}/inavigation.h
${CMAKE_CURRENT_LIST_DIR}/inavigationcontroller.h
${CMAKE_CURRENT_LIST_DIR}/internal/interactiveuriregister.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/interactiveuriregister.h
@ -74,10 +74,10 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/iplatformtheme.h
${CMAKE_CURRENT_LIST_DIR}/internal/uiactionsregister.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/uiactionsregister.h
${CMAKE_CURRENT_LIST_DIR}/internal/keynavigationcontroller.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/keynavigationcontroller.h
${CMAKE_CURRENT_LIST_DIR}/internal/keynavigationuiactions.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/keynavigationuiactions.h
${CMAKE_CURRENT_LIST_DIR}/internal/navigationcontroller.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/navigationcontroller.h
${CMAKE_CURRENT_LIST_DIR}/internal/navigationuiactions.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/navigationuiactions.h
${PLATFORM_THEME_SRC}
${CMAKE_CURRENT_LIST_DIR}/view/interactiveprovider.cpp
@ -100,18 +100,18 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/view/widgetdialog.h
${CMAKE_CURRENT_LIST_DIR}/view/abstractmenumodel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/abstractmenumodel.h
${CMAKE_CURRENT_LIST_DIR}/view/abstractkeynavigation.cpp
${CMAKE_CURRENT_LIST_DIR}/view/abstractkeynavigation.h
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationsection.cpp
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationsection.h
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationsubsection.cpp
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationsubsection.h
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationpopuppanel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationpopuppanel.h
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationcontrol.cpp
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationcontrol.h
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationevent.cpp
${CMAKE_CURRENT_LIST_DIR}/view/keynavigationevent.h
${CMAKE_CURRENT_LIST_DIR}/view/abstractnavigation.cpp
${CMAKE_CURRENT_LIST_DIR}/view/abstractnavigation.h
${CMAKE_CURRENT_LIST_DIR}/view/navigationsection.cpp
${CMAKE_CURRENT_LIST_DIR}/view/navigationsection.h
${CMAKE_CURRENT_LIST_DIR}/view/navigationpanel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/navigationpanel.h
${CMAKE_CURRENT_LIST_DIR}/view/navigationpopuppanel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/navigationpopuppanel.h
${CMAKE_CURRENT_LIST_DIR}/view/navigationcontrol.cpp
${CMAKE_CURRENT_LIST_DIR}/view/navigationcontrol.h
${CMAKE_CURRENT_LIST_DIR}/view/navigationevent.cpp
${CMAKE_CURRENT_LIST_DIR}/view/navigationevent.h
${CMAKE_CURRENT_LIST_DIR}/dev/interactivetestsmodel.cpp
${CMAKE_CURRENT_LIST_DIR}/dev/interactivetestsmodel.h

View File

@ -23,10 +23,10 @@
using namespace mu::ui;
AbstractKeyNavDevItem::AbstractKeyNavDevItem(IKeyNavigation* keynav)
AbstractKeyNavDevItem::AbstractKeyNavDevItem(INavigation* keynav)
: m_keynav(keynav)
{
m_keynav->indexChanged().onReceive(this, [this](const IKeyNavigation::Index&) {
m_keynav->indexChanged().onReceive(this, [this](const INavigation::Index&) {
emit indexChanged();
});

View File

@ -23,7 +23,7 @@
#define MU_UI_ABSTRACTKEYNAVDEVITEM_H
#include <QObject>
#include "ui/ikeynavigation.h"
#include "ui/inavigation.h"
#include "async/asyncable.h"
namespace mu::ui {
@ -36,7 +36,7 @@ class AbstractKeyNavDevItem : public QObject, public async::Asyncable
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
public:
explicit AbstractKeyNavDevItem(IKeyNavigation* keynav);
explicit AbstractKeyNavDevItem(INavigation* keynav);
QString name() const;
QVariant index() const;
@ -50,7 +50,7 @@ signals:
private:
IKeyNavigation* m_keynav = nullptr;
INavigation* m_keynav = nullptr;
};
}

View File

@ -23,7 +23,7 @@
using namespace mu::ui;
KeyNavDevControl::KeyNavDevControl(IKeyNavigationControl* control)
KeyNavDevControl::KeyNavDevControl(INavigationControl* control)
: AbstractKeyNavDevItem(control), m_control(control)
{
}

View File

@ -31,7 +31,7 @@ class KeyNavDevControl : public AbstractKeyNavDevItem
Q_OBJECT
public:
KeyNavDevControl(IKeyNavigationControl* control);
KeyNavDevControl(INavigationControl* control);
Q_INVOKABLE void forceActive();
Q_INVOKABLE void trigger();
@ -39,7 +39,7 @@ public:
signals:
private:
IKeyNavigationControl* m_control = nullptr;
INavigationControl* m_control = nullptr;
};
}

View File

@ -66,11 +66,11 @@ void KeyNavDevModel::reload()
qDeleteAll(m_memstore);
m_memstore.clear();
const std::set<IKeyNavigationSection*>& sectionsSet = keynavController()->sections();
QList<IKeyNavigationSection*> sectionsList = toQList(sectionsSet);
const std::set<INavigationSection*>& sectionsSet = navigationController()->sections();
QList<INavigationSection*> sectionsList = toQList(sectionsSet);
sortByIndex(sectionsList);
for (IKeyNavigationSection* s : sectionsList) {
for (INavigationSection* s : sectionsList) {
m_sections << toWrap(s);
}
@ -78,38 +78,38 @@ void KeyNavDevModel::reload()
emit afterReload();
}
QVariant KeyNavDevModel::toWrap(IKeyNavigationSection* s)
QVariant KeyNavDevModel::toWrap(INavigationSection* s)
{
KeyNavDevSection* qs = new KeyNavDevSection(s);
m_memstore.append(qs);
QVariantList subVarList;
const std::set<IKeyNavigationSubSection*>& subsectionsSet = s->subsections();
QList<IKeyNavigationSubSection*> subsectionsList = toQList(subsectionsSet);
const std::set<INavigationPanel*>& subsectionsSet = s->panels();
QList<INavigationPanel*> subsectionsList = toQList(subsectionsSet);
sortByIndex(subsectionsList);
for (IKeyNavigationSubSection* sub : subsectionsList) {
for (INavigationPanel* sub : subsectionsList) {
subVarList << toWrap(sub);
}
qs->setSubsections(subVarList);
s->subsectionsListChanged().onNotify(this, [this]() {
s->panelsListChanged().onNotify(this, [this]() {
m_reloadDelayer.start();
});
return QVariant::fromValue(qs);
}
QVariant KeyNavDevModel::toWrap(IKeyNavigationSubSection* sub)
QVariant KeyNavDevModel::toWrap(INavigationPanel* sub)
{
KeyNavDevSubSection* qsub = new KeyNavDevSubSection(sub);
m_memstore.append(qsub);
QVariantList conVarList;
const std::set<IKeyNavigationControl*>& controlsSet = sub->controls();
QList<IKeyNavigationControl*> controlsList = toQList(controlsSet);
const std::set<INavigationControl*>& controlsSet = sub->controls();
QList<INavigationControl*> controlsList = toQList(controlsSet);
sortByIndex(controlsList);
for (IKeyNavigationControl* ctrl : controlsList) {
for (INavigationControl* ctrl : controlsList) {
conVarList << toWrap(ctrl);
}
@ -122,7 +122,7 @@ QVariant KeyNavDevModel::toWrap(IKeyNavigationSubSection* sub)
return QVariant::fromValue(qsub);
}
QVariant KeyNavDevModel::toWrap(IKeyNavigationControl* ctrl)
QVariant KeyNavDevModel::toWrap(INavigationControl* ctrl)
{
KeyNavDevControl* qc = new KeyNavDevControl(ctrl);
m_memstore.append(qc);

View File

@ -25,7 +25,7 @@
#include <QObject>
#include <QTimer>
#include "modularity/ioc.h"
#include "ui/ikeynavigationcontroller.h"
#include "ui/inavigationcontroller.h"
#include "async/asyncable.h"
namespace mu::ui {
@ -36,7 +36,7 @@ class KeyNavDevModel : public QObject, public async::Asyncable
Q_PROPERTY(QVariantList sections READ sections NOTIFY sectionsChanged)
INJECT(ui, IKeyNavigationController, keynavController)
INJECT(ui, INavigationController, navigationController)
public:
explicit KeyNavDevModel(QObject* parent = nullptr);
@ -51,9 +51,9 @@ signals:
private:
QVariant toWrap(IKeyNavigationSection* s);
QVariant toWrap(IKeyNavigationSubSection* sub);
QVariant toWrap(IKeyNavigationControl* ctrl);
QVariant toWrap(INavigationSection* s);
QVariant toWrap(INavigationPanel* sub);
QVariant toWrap(INavigationControl* ctrl);
QVariantList m_sections;
mutable QList<AbstractKeyNavDevItem*> m_memstore;

View File

@ -23,7 +23,7 @@
using namespace mu::ui;
KeyNavDevSection::KeyNavDevSection(IKeyNavigationSection* section)
KeyNavDevSection::KeyNavDevSection(INavigationSection* section)
: AbstractKeyNavDevItem(section), m_section(section)
{
}

View File

@ -31,7 +31,7 @@ class KeyNavDevSection : public AbstractKeyNavDevItem
Q_PROPERTY(QVariantList subsections READ subsections NOTIFY subsectionsChanged)
public:
explicit KeyNavDevSection(IKeyNavigationSection* section);
explicit KeyNavDevSection(INavigationSection* section);
QVariantList subsections() const;
@ -42,7 +42,7 @@ signals:
void subsectionsChanged();
private:
IKeyNavigationSection* m_section = nullptr;
INavigationSection* m_section = nullptr;
QVariantList m_subsections;
};
}

View File

@ -23,14 +23,14 @@
using namespace mu::ui;
KeyNavDevSubSection::KeyNavDevSubSection(IKeyNavigationSubSection* subsection)
KeyNavDevSubSection::KeyNavDevSubSection(INavigationPanel* subsection)
: AbstractKeyNavDevItem(subsection), m_subsection(subsection)
{
}
QString KeyNavDevSubSection::direction() const
{
using Direction = IKeyNavigationSubSection::Direction;
using Direction = INavigationPanel::Direction;
switch (m_subsection->direction()) {
case Direction::Horizontal: return QString("Horizontal");
case Direction::Vertical: return QString("Vertical");

View File

@ -32,7 +32,7 @@ class KeyNavDevSubSection : public AbstractKeyNavDevItem
Q_PROPERTY(QVariantList controls READ controls NOTIFY controlsChanged)
public:
explicit KeyNavDevSubSection(IKeyNavigationSubSection* subsection);
explicit KeyNavDevSubSection(INavigationPanel* subsection);
QString direction() const;
QVariantList controls() const;
@ -44,7 +44,7 @@ signals:
void controlsChanged();
private:
IKeyNavigationSubSection* m_subsection = nullptr;
INavigationPanel* m_subsection = nullptr;
QVariantList m_controls;
};
}

View File

@ -19,8 +19,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_IKEYNAVIGATION_H
#define MU_UI_IKEYNAVIGATION_H
#ifndef MU_UI_INAVIGATION_H
#define MU_UI_INAVIGATION_H
#include <tuple>
#include <memory>
@ -30,21 +30,21 @@
#include "async/notification.h"
namespace mu::ui {
class IKeyNavigationSection;
class IKeyNavigationSubSection;
class IKeyNavigationControl;
class INavigationSection;
class INavigationPanel;
class INavigationControl;
using SubSectionControl = std::tuple<IKeyNavigationSubSection*, IKeyNavigationControl*>;
using SectionSubSectionControl = std::tuple<IKeyNavigationSection*, IKeyNavigationSubSection*, IKeyNavigationControl*>;
using PanelControl = std::tuple<INavigationPanel*, INavigationControl*>;
using SectionPanelControl = std::tuple<INavigationSection*, INavigationPanel*, INavigationControl*>;
class IKeyNavigation
class INavigation
{
public:
virtual ~IKeyNavigation() = default;
virtual ~INavigation() = default;
struct Event
{
//! NOTE Please sync with view/KeyNavigationEvent::Type
//! NOTE Please sync with view/NavigationEvent::Type
enum Type {
Undefined = 0,
Left,
@ -88,21 +88,21 @@ public:
virtual void onEvent(EventPtr e) = 0;
};
class IKeyNavigationControl : public IKeyNavigation
class INavigationControl : public INavigation
{
public:
virtual ~IKeyNavigationControl() = default;
virtual ~INavigationControl() = default;
virtual void trigger() = 0;
virtual async::Channel<IKeyNavigationControl*> forceActiveRequested() const = 0;
virtual async::Channel<INavigationControl*> forceActiveRequested() const = 0;
};
class IKeyNavigationSubSection : public IKeyNavigation
class INavigationPanel : public INavigation
{
public:
virtual ~IKeyNavigationSubSection() = default;
virtual ~INavigationPanel() = default;
//! NOTE Please sync with view/KeyNavigationSubSection::Direction
//! NOTE Please sync with view/NavigationPanel::Direction
enum class Direction {
Horizontal = 0,
Vertical,
@ -110,20 +110,20 @@ public:
};
virtual Direction direction() const = 0;
virtual const std::set<IKeyNavigationControl*>& controls() const = 0;
virtual const std::set<INavigationControl*>& controls() const = 0;
virtual async::Notification controlsListChanged() const = 0;
virtual async::Channel<SubSectionControl> forceActiveRequested() const = 0;
virtual async::Channel<PanelControl> forceActiveRequested() const = 0;
};
class IKeyNavigationSection : public IKeyNavigation
class INavigationSection : public INavigation
{
public:
virtual ~IKeyNavigationSection() = default;
virtual ~INavigationSection() = default;
virtual const std::set<IKeyNavigationSubSection*>& subsections() const = 0;
virtual async::Notification subsectionsListChanged() const = 0;
virtual async::Channel<SectionSubSectionControl> forceActiveRequested() const = 0;
virtual const std::set<INavigationPanel*>& panels() const = 0;
virtual async::Notification panelsListChanged() const = 0;
virtual async::Channel<SectionPanelControl> forceActiveRequested() const = 0;
};
}
#endif // MU_UI_IKEYNAVIGATION_H
#endif // MU_UI_INAVIGATION_H

View File

@ -19,25 +19,25 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_IKEYNAVIGATIONCONTROLLER_H
#define MU_UI_IKEYNAVIGATIONCONTROLLER_H
#ifndef MU_UI_INAVIGATIONCONTROLLER_H
#define MU_UI_INAVIGATIONCONTROLLER_H
#include "modularity/imoduleexport.h"
#include "ikeynavigation.h"
#include "inavigation.h"
namespace mu::ui {
class IKeyNavigationController : MODULE_EXPORT_INTERFACE
class INavigationController : MODULE_EXPORT_INTERFACE
{
INTERFACE_ID(IKeyNavigationController)
INTERFACE_ID(INavigationController)
public:
virtual ~IKeyNavigationController() = default;
virtual ~INavigationController() = default;
virtual void reg(IKeyNavigationSection* s) = 0;
virtual void unreg(IKeyNavigationSection* s) = 0;
virtual void reg(INavigationSection* section) = 0;
virtual void unreg(INavigationSection* section) = 0;
virtual const std::set<IKeyNavigationSection*>& sections() const = 0;
virtual const std::set<INavigationSection*>& sections() const = 0;
};
}
#endif // MU_UI_IKEYNAVIGATIONCONTROLLER_H
#endif // MU_UI_INAVIGATIONCONTROLLER_H

View File

@ -19,7 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "keynavigationcontroller.h"
#include "navigationcontroller.h"
#include <algorithm>
#include <limits>
@ -30,12 +30,12 @@ using namespace mu::ui;
static const mu::UriQuery DEV_SHOW_CONTROLS_URI("musescore://devtools/keynav/controls?sync=false&modal=false");
using MoveDirection = KeyNavigationController::MoveDirection;
using Event = IKeyNavigation::Event;
using MoveDirection = NavigationController::MoveDirection;
using Event = INavigation::Event;
// algorithms
template<class T>
static T* findNearestEnabled(const std::set<T*>& set, const IKeyNavigation::Index& currentIndex, MoveDirection direction)
static T* findNearestEnabled(const std::set<T*>& set, const INavigation::Index& currentIndex, MoveDirection direction)
{
T* ret = nullptr;
for (T* v : set) {
@ -141,7 +141,7 @@ static T* findNearestEnabled(const std::set<T*>& set, const IKeyNavigation::Inde
}
template<class T>
static T* firstEnabled(const std::set<T*>& set, const IKeyNavigation::Index& currentIndex, MoveDirection direction)
static T* firstEnabled(const std::set<T*>& set, const INavigation::Index& currentIndex, MoveDirection direction)
{
if (set.empty()) {
return nullptr;
@ -161,11 +161,11 @@ static T* firstEnabled(const std::set<T*>& set)
return nullptr;
}
return findNearestEnabled<T>(set, IKeyNavigation::Index(), MoveDirection::First);
return findNearestEnabled<T>(set, INavigation::Index(), MoveDirection::First);
}
template<class T>
static T* lastEnabled(const std::set<T*>& set, const IKeyNavigation::Index& currentIndex, MoveDirection direction)
static T* lastEnabled(const std::set<T*>& set, const INavigation::Index& currentIndex, MoveDirection direction)
{
if (set.empty()) {
return nullptr;
@ -185,11 +185,11 @@ static T* lastEnabled(const std::set<T*>& set)
return nullptr;
}
return findNearestEnabled<T>(set, IKeyNavigation::Index(), MoveDirection::Last);
return findNearestEnabled<T>(set, INavigation::Index(), MoveDirection::Last);
}
template<class T>
static T* nextEnabled(const std::set<T*>& set, const IKeyNavigation::Index& currentIndex,
static T* nextEnabled(const std::set<T*>& set, const INavigation::Index& currentIndex,
MoveDirection direction = MoveDirection::Right)
{
if (set.empty()) {
@ -204,7 +204,7 @@ static T* nextEnabled(const std::set<T*>& set, const IKeyNavigation::Index& curr
}
template<class T>
static T* prevEnabled(const std::set<T*>& set, const IKeyNavigation::Index& currentIndex, MoveDirection direction = MoveDirection::Left)
static T* prevEnabled(const std::set<T*>& set, const INavigation::Index& currentIndex, MoveDirection direction = MoveDirection::Left)
{
if (set.empty()) {
return nullptr;
@ -231,123 +231,123 @@ static T* findActive(const std::set<T*>& set)
return nullptr;
}
void KeyNavigationController::init()
void NavigationController::init()
{
dispatcher()->reg(this, "nav-dev-show-controls", this, &KeyNavigationController::devShowControls);
dispatcher()->reg(this, "nav-dev-show-controls", this, &NavigationController::devShowControls);
dispatcher()->reg(this, "nav-next-section", this, &KeyNavigationController::goToNextSection);
dispatcher()->reg(this, "nav-prev-section", this, &KeyNavigationController::goToPrevSection);
dispatcher()->reg(this, "nav-next-subsection", this, &KeyNavigationController::goToNextSubSection);
dispatcher()->reg(this, "nav-prev-subsection", this, &KeyNavigationController::goToPrevSubSection);
dispatcher()->reg(this, "nav-next-section", this, &NavigationController::goToNextSection);
dispatcher()->reg(this, "nav-prev-section", this, &NavigationController::goToPrevSection);
dispatcher()->reg(this, "nav-next-panel", this, &NavigationController::goToNextPanel);
dispatcher()->reg(this, "nav-prev-panel", this, &NavigationController::goToPrevPanel);
dispatcher()->reg(this, "nav-trigger-control", this, &KeyNavigationController::doTriggerControl);
dispatcher()->reg(this, "nav-trigger-control", this, &NavigationController::doTriggerControl);
dispatcher()->reg(this, "nav-right", this, &KeyNavigationController::onRight);
dispatcher()->reg(this, "nav-left", this, &KeyNavigationController::onLeft);
dispatcher()->reg(this, "nav-up", this, &KeyNavigationController::onUp);
dispatcher()->reg(this, "nav-down", this, &KeyNavigationController::onDown);
dispatcher()->reg(this, "nav-escape", this, &KeyNavigationController::onEscape);
dispatcher()->reg(this, "nav-right", this, &NavigationController::onRight);
dispatcher()->reg(this, "nav-left", this, &NavigationController::onLeft);
dispatcher()->reg(this, "nav-up", this, &NavigationController::onUp);
dispatcher()->reg(this, "nav-down", this, &NavigationController::onDown);
dispatcher()->reg(this, "nav-escape", this, &NavigationController::onEscape);
dispatcher()->reg(this, "nav-first-control", this, &KeyNavigationController::goToFirstControl); // typically Home key
dispatcher()->reg(this, "nav-last-control", this, &KeyNavigationController::goToLastControl); // typically End key
dispatcher()->reg(this, "nav-nextrow-control", this, &KeyNavigationController::goToNextRowControl); // typically PageDown key
dispatcher()->reg(this, "nav-prevrow-control", this, &KeyNavigationController::goToPrevRowControl); // typically PageUp key
dispatcher()->reg(this, "nav-first-control", this, &NavigationController::goToFirstControl); // typically Home key
dispatcher()->reg(this, "nav-last-control", this, &NavigationController::goToLastControl); // typically End key
dispatcher()->reg(this, "nav-nextrow-control", this, &NavigationController::goToNextRowControl); // typically PageDown key
dispatcher()->reg(this, "nav-prevrow-control", this, &NavigationController::goToPrevRowControl); // typically PageUp key
}
void KeyNavigationController::reg(IKeyNavigationSection* s)
void NavigationController::reg(INavigationSection* section)
{
//! TODO add check on valid state
m_sections.insert(s);
m_sections.insert(section);
s->forceActiveRequested().onReceive(this, [this](const SectionSubSectionControl& ssc) {
section->forceActiveRequested().onReceive(this, [this](const SectionPanelControl& ssc) {
onForceActiveRequested(std::get<0>(ssc), std::get<1>(ssc), std::get<2>(ssc));
});
}
void KeyNavigationController::unreg(IKeyNavigationSection* s)
void NavigationController::unreg(INavigationSection* section)
{
m_sections.erase(s);
s->forceActiveRequested().resetOnReceive(this);
m_sections.erase(section);
section->forceActiveRequested().resetOnReceive(this);
}
const std::set<IKeyNavigationSection*>& KeyNavigationController::sections() const
const std::set<INavigationSection*>& NavigationController::sections() const
{
return m_sections;
}
void KeyNavigationController::devShowControls()
void NavigationController::devShowControls()
{
if (!interactive()->isOpened(DEV_SHOW_CONTROLS_URI.uri()).val) {
interactive()->open(DEV_SHOW_CONTROLS_URI);
}
}
void KeyNavigationController::doActivateSection(IKeyNavigationSection* s)
void NavigationController::doActivateSection(INavigationSection* s)
{
IF_ASSERT_FAILED(s) {
return;
}
for (IKeyNavigationSubSection* sub : s->subsections()) {
doDeactivateSubSection(sub);
for (INavigationPanel* sub : s->panels()) {
doDeactivatePanel(sub);
}
s->setActive(true);
LOGD() << "activated section: " << s->name() << ", order: " << s->index().order();
IKeyNavigationSubSection* firstSub = firstEnabled(s->subsections());
INavigationPanel* firstSub = firstEnabled(s->panels());
if (firstSub) {
doActivateSubSection(firstSub);
doActivatePanel(firstSub);
}
}
void KeyNavigationController::doDeactivateSection(IKeyNavigationSection* s)
void NavigationController::doDeactivateSection(INavigationSection* s)
{
IF_ASSERT_FAILED(s) {
return;
}
for (IKeyNavigationSubSection* sub : s->subsections()) {
doDeactivateSubSection(sub);
for (INavigationPanel* sub : s->panels()) {
doDeactivatePanel(sub);
}
s->setActive(false);
}
void KeyNavigationController::doActivateSubSection(IKeyNavigationSubSection* sub)
void NavigationController::doActivatePanel(INavigationPanel* sub)
{
IF_ASSERT_FAILED(sub) {
return;
}
for (IKeyNavigationControl* ctr : sub->controls()) {
for (INavigationControl* ctr : sub->controls()) {
doDeactivateControl(ctr);
}
sub->setActive(true);
LOGD() << "activated subsection: " << sub->name() << ", order: " << sub->index().order();
IKeyNavigationControl* firstCtr = firstEnabled(sub->controls());
INavigationControl* firstCtr = firstEnabled(sub->controls());
if (firstCtr) {
doActivateControl(firstCtr);
}
}
void KeyNavigationController::doDeactivateSubSection(IKeyNavigationSubSection* sub)
void NavigationController::doDeactivatePanel(INavigationPanel* sub)
{
IF_ASSERT_FAILED(sub) {
return;
}
for (IKeyNavigationControl* ctr : sub->controls()) {
for (INavigationControl* ctr : sub->controls()) {
ctr->setActive(false);
}
sub->setActive(false);
}
void KeyNavigationController::doActivateControl(IKeyNavigationControl* c)
void NavigationController::doActivateControl(INavigationControl* c)
{
IF_ASSERT_FAILED(c) {
return;
@ -357,7 +357,7 @@ void KeyNavigationController::doActivateControl(IKeyNavigationControl* c)
LOGD() << "activated control: " << c->name() << ", row: " << c->index().row << ", column: " << c->index().column;
}
void KeyNavigationController::doDeactivateControl(IKeyNavigationControl* c)
void NavigationController::doDeactivateControl(INavigationControl* c)
{
IF_ASSERT_FAILED(c) {
return;
@ -366,31 +366,31 @@ void KeyNavigationController::doDeactivateControl(IKeyNavigationControl* c)
c->setActive(false);
}
void KeyNavigationController::doActivateFirst()
void NavigationController::doActivateFirst()
{
if (m_sections.empty()) {
return;
}
IKeyNavigationSection* first = firstEnabled(m_sections);
INavigationSection* first = firstEnabled(m_sections);
if (first) {
doActivateSection(first);
}
}
void KeyNavigationController::doActivateLast()
void NavigationController::doActivateLast()
{
if (m_sections.empty()) {
return;
}
IKeyNavigationSection* last = lastEnabled(m_sections);
INavigationSection* last = lastEnabled(m_sections);
if (last) {
doActivateSection(last);
}
}
IKeyNavigationSection* KeyNavigationController::activeSection() const
INavigationSection* NavigationController::activeSection() const
{
if (m_sections.empty()) {
return nullptr;
@ -398,32 +398,32 @@ IKeyNavigationSection* KeyNavigationController::activeSection() const
return findActive(m_sections);
}
IKeyNavigationSubSection* KeyNavigationController::activeSubSection() const
INavigationPanel* NavigationController::activePanel() const
{
IKeyNavigationSection* activeSec = activeSection();
INavigationSection* activeSec = activeSection();
if (!activeSec) {
return nullptr;
}
return findActive(activeSec->subsections());
return findActive(activeSec->panels());
}
IKeyNavigationControl* KeyNavigationController::activeControl() const
INavigationControl* NavigationController::activeControl() const
{
IKeyNavigationSubSection* activeSub = activeSubSection();
INavigationPanel* activeSub = activePanel();
if (!activeSub) {
return nullptr;
}
return findActive(activeSub->controls());
}
void KeyNavigationController::goToNextSection()
void NavigationController::goToNextSection()
{
LOGI() << "====";
if (m_sections.empty()) {
return;
}
IKeyNavigationSection* activeSec = findActive(m_sections);
INavigationSection* activeSec = findActive(m_sections);
if (!activeSec) { // no any active
doActivateFirst();
return;
@ -431,7 +431,7 @@ void KeyNavigationController::goToNextSection()
doDeactivateSection(activeSec);
IKeyNavigationSection* nextSec = nextEnabled(m_sections, activeSec->index());
INavigationSection* nextSec = nextEnabled(m_sections, activeSec->index());
if (!nextSec) { // active is last
nextSec = firstEnabled(m_sections); // the first to be the next
}
@ -439,14 +439,14 @@ void KeyNavigationController::goToNextSection()
doActivateSection(nextSec);
}
void KeyNavigationController::goToPrevSection()
void NavigationController::goToPrevSection()
{
LOGI() << "====";
if (m_sections.empty()) {
return;
}
IKeyNavigationSection* activeSec = findActive(m_sections);
INavigationSection* activeSec = findActive(m_sections);
if (!activeSec) { // no any active
doActivateLast();
return;
@ -454,7 +454,7 @@ void KeyNavigationController::goToPrevSection()
doDeactivateSection(activeSec);
IKeyNavigationSection* prevSec = prevEnabled(m_sections, activeSec->index());
INavigationSection* prevSec = prevEnabled(m_sections, activeSec->index());
if (!prevSec) { // active is first
prevSec = lastEnabled(m_sections); // the last to be the prev
}
@ -462,77 +462,77 @@ void KeyNavigationController::goToPrevSection()
doActivateSection(prevSec);
}
void KeyNavigationController::goToNextSubSection()
void NavigationController::goToNextPanel()
{
LOGI() << "====";
IKeyNavigationSection* activeSec = activeSection();
INavigationSection* activeSec = activeSection();
if (!activeSec) {
doActivateFirst();
return;
}
IKeyNavigationSubSection* activeSubSec = findActive(activeSec->subsections());
INavigationPanel* activeSubSec = findActive(activeSec->panels());
if (!activeSubSec) { // no any active
IKeyNavigationSubSection* first = firstEnabled(activeSec->subsections());
INavigationPanel* first = firstEnabled(activeSec->panels());
if (first) {
doActivateSubSection(first);
doActivatePanel(first);
}
return;
}
doDeactivateSubSection(activeSubSec);
doDeactivatePanel(activeSubSec);
IKeyNavigationSubSection* nextSubSec = nextEnabled(activeSec->subsections(), activeSubSec->index());
INavigationPanel* nextSubSec = nextEnabled(activeSec->panels(), activeSubSec->index());
if (!nextSubSec) { // active is last
nextSubSec = firstEnabled(activeSec->subsections()); // the first to be the next
nextSubSec = firstEnabled(activeSec->panels()); // the first to be the next
}
doActivateSubSection(nextSubSec);
doActivatePanel(nextSubSec);
}
void KeyNavigationController::goToPrevSubSection()
void NavigationController::goToPrevPanel()
{
LOGI() << "====";
IKeyNavigationSection* activeSec = activeSection();
INavigationSection* activeSec = activeSection();
if (!activeSec) {
doActivateLast();
return;
}
IKeyNavigationSubSection* activeSubSec = findActive(activeSec->subsections());
INavigationPanel* activeSubSec = findActive(activeSec->panels());
if (!activeSubSec) { // no any active
IKeyNavigationSubSection* lastSub = lastEnabled(activeSec->subsections());
INavigationPanel* lastSub = lastEnabled(activeSec->panels());
if (lastSub) {
doActivateSubSection(lastSub);
doActivatePanel(lastSub);
}
return;
}
doDeactivateSubSection(activeSubSec);
doDeactivatePanel(activeSubSec);
IKeyNavigationSubSection* prevSubSec = prevEnabled(activeSec->subsections(), activeSubSec->index());
INavigationPanel* prevSubSec = prevEnabled(activeSec->panels(), activeSubSec->index());
if (!prevSubSec) { // active is first
prevSubSec = lastEnabled(activeSec->subsections()); // the last to be the prev
prevSubSec = lastEnabled(activeSec->panels()); // the last to be the prev
}
doActivateSubSection(prevSubSec);
doActivatePanel(prevSubSec);
}
void KeyNavigationController::onRight()
void NavigationController::onRight()
{
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigation::EventPtr e = Event::make(Event::Right);
INavigation::EventPtr e = Event::make(Event::Right);
activeSubSec->onEvent(e);
if (e->accepted) {
return;
}
IKeyNavigationControl* activeCtrl = findActive(activeSubSec->controls());
INavigationControl* activeCtrl = findActive(activeSubSec->controls());
if (activeCtrl) {
activeCtrl->onEvent(e);
if (e->accepted) {
@ -540,34 +540,34 @@ void KeyNavigationController::onRight()
}
}
IKeyNavigationSubSection::Direction direction = activeSubSec->direction();
INavigationPanel::Direction direction = activeSubSec->direction();
switch (direction) {
case IKeyNavigationSubSection::Direction::Horizontal: {
case INavigationPanel::Direction::Horizontal: {
goToControl(MoveDirection::Right, activeSubSec);
} break;
case IKeyNavigationSubSection::Direction::Vertical: {
case INavigationPanel::Direction::Vertical: {
// noop
} break;
case IKeyNavigationSubSection::Direction::Both: {
case INavigationPanel::Direction::Both: {
goToControl(MoveDirection::Right, activeSubSec);
} break;
}
}
void KeyNavigationController::onLeft()
void NavigationController::onLeft()
{
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigation::EventPtr e = Event::make(Event::Left);
INavigation::EventPtr e = Event::make(Event::Left);
activeSubSec->onEvent(e);
if (e->accepted) {
return;
}
IKeyNavigationControl* activeCtrl = findActive(activeSubSec->controls());
INavigationControl* activeCtrl = findActive(activeSubSec->controls());
if (activeCtrl) {
activeCtrl->onEvent(e);
if (e->accepted) {
@ -575,34 +575,34 @@ void KeyNavigationController::onLeft()
}
}
IKeyNavigationSubSection::Direction direction = activeSubSec->direction();
INavigationPanel::Direction direction = activeSubSec->direction();
switch (direction) {
case IKeyNavigationSubSection::Direction::Horizontal: {
case INavigationPanel::Direction::Horizontal: {
goToControl(MoveDirection::Left, activeSubSec);
} break;
case IKeyNavigationSubSection::Direction::Vertical: {
case INavigationPanel::Direction::Vertical: {
// noop
} break;
case IKeyNavigationSubSection::Direction::Both: {
case INavigationPanel::Direction::Both: {
goToControl(MoveDirection::Left, activeSubSec);
} break;
}
}
void KeyNavigationController::onDown()
void NavigationController::onDown()
{
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigation::EventPtr e = Event::make(Event::Down);
INavigation::EventPtr e = Event::make(Event::Down);
activeSubSec->onEvent(e);
if (e->accepted) {
return;
}
IKeyNavigationControl* activeCtrl = findActive(activeSubSec->controls());
INavigationControl* activeCtrl = findActive(activeSubSec->controls());
if (activeCtrl) {
activeCtrl->onEvent(e);
if (e->accepted) {
@ -610,34 +610,34 @@ void KeyNavigationController::onDown()
}
}
IKeyNavigationSubSection::Direction direction = activeSubSec->direction();
INavigationPanel::Direction direction = activeSubSec->direction();
switch (direction) {
case IKeyNavigationSubSection::Direction::Horizontal: {
case INavigationPanel::Direction::Horizontal: {
// noop
} break;
case IKeyNavigationSubSection::Direction::Vertical: {
case INavigationPanel::Direction::Vertical: {
goToControl(MoveDirection::Down, activeSubSec);
} break;
case IKeyNavigationSubSection::Direction::Both: {
case INavigationPanel::Direction::Both: {
goToControl(MoveDirection::Down, activeSubSec);
} break;
}
}
void KeyNavigationController::onUp()
void NavigationController::onUp()
{
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigation::EventPtr e = Event::make(Event::Up);
INavigation::EventPtr e = Event::make(Event::Up);
activeSubSec->onEvent(e);
if (e->accepted) {
return;
}
IKeyNavigationControl* activeCtrl = findActive(activeSubSec->controls());
INavigationControl* activeCtrl = findActive(activeSubSec->controls());
if (activeCtrl) {
activeCtrl->onEvent(e);
if (e->accepted) {
@ -645,68 +645,68 @@ void KeyNavigationController::onUp()
}
}
IKeyNavigationSubSection::Direction direction = activeSubSec->direction();
INavigationPanel::Direction direction = activeSubSec->direction();
switch (direction) {
case IKeyNavigationSubSection::Direction::Horizontal: {
case INavigationPanel::Direction::Horizontal: {
// noop
} break;
case IKeyNavigationSubSection::Direction::Vertical: {
case INavigationPanel::Direction::Vertical: {
goToControl(MoveDirection::Up, activeSubSec);
} break;
case IKeyNavigationSubSection::Direction::Both: {
case INavigationPanel::Direction::Both: {
goToControl(MoveDirection::Up, activeSubSec);
} break;
}
}
void KeyNavigationController::onEscape()
void NavigationController::onEscape()
{
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigation::EventPtr e = Event::make(Event::Escape);
INavigation::EventPtr e = Event::make(Event::Escape);
activeSubSec->onEvent(e);
if (e->accepted) {
return;
}
IKeyNavigationControl* activeCtrl = findActive(activeSubSec->controls());
INavigationControl* activeCtrl = findActive(activeSubSec->controls());
if (activeCtrl) {
activeCtrl->onEvent(e);
}
}
void KeyNavigationController::goToFirstControl()
void NavigationController::goToFirstControl()
{
LOGI() << "====";
goToControl(MoveDirection::First);
}
void KeyNavigationController::goToLastControl()
void NavigationController::goToLastControl()
{
LOGI() << "====";
goToControl(MoveDirection::Last);
}
void KeyNavigationController::goToNextRowControl()
void NavigationController::goToNextRowControl()
{
LOGI() << "====";
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigationControl* activeControl = findActive(activeSubSec->controls());
INavigationControl* activeControl = findActive(activeSubSec->controls());
if (activeControl) {
doDeactivateControl(activeControl);
}
IKeyNavigationControl* toControl = nullptr;
INavigationControl* toControl = nullptr;
if (activeControl) {
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.column = 0;
toControl = nextEnabled(activeSubSec->controls(), index, MoveDirection::Down);
if (!toControl) { // last row
@ -721,23 +721,23 @@ void KeyNavigationController::goToNextRowControl()
}
}
void KeyNavigationController::goToPrevRowControl()
void NavigationController::goToPrevRowControl()
{
LOGI() << "====";
IKeyNavigationSubSection* activeSubSec = activeSubSection();
INavigationPanel* activeSubSec = activePanel();
if (!activeSubSec) {
return;
}
IKeyNavigationControl* activeControl = findActive(activeSubSec->controls());
INavigationControl* activeControl = findActive(activeSubSec->controls());
if (activeControl) {
doDeactivateControl(activeControl);
}
IKeyNavigationControl* toControl = nullptr;
INavigationControl* toControl = nullptr;
if (activeControl) {
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.column = 0;
toControl = prevEnabled(activeSubSec->controls(), index, MoveDirection::Up);
if (!toControl) { // first row
@ -752,24 +752,24 @@ void KeyNavigationController::goToPrevRowControl()
}
}
void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigationSubSection* activeSubSec)
void NavigationController::goToControl(MoveDirection direction, INavigationPanel* activeSubSec)
{
LOGI() << "direction: " << direction;
if (!activeSubSec) {
activeSubSec = activeSubSection();
activeSubSec = activePanel();
}
if (!activeSubSec) {
return;
}
IKeyNavigationControl* activeControl = findActive(activeSubSec->controls());
INavigationControl* activeControl = findActive(activeSubSec->controls());
if (activeControl) {
doDeactivateControl(activeControl);
}
IKeyNavigationControl* toControl = nullptr;
INavigationControl* toControl = nullptr;
switch (direction) {
case MoveDirection::First: {
@ -780,11 +780,11 @@ void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigatio
} break;
case MoveDirection::Right: {
if (!activeControl) { // no any active
toControl = firstEnabled(activeSubSec->controls(), IKeyNavigation::Index(), direction);
toControl = firstEnabled(activeSubSec->controls(), INavigation::Index(), direction);
} else {
toControl = nextEnabled(activeSubSec->controls(), activeControl->index(), direction);
if (!toControl) { // active is last
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.column = -1;
toControl = firstEnabled(activeSubSec->controls(), index, direction); // the first to be the next
}
@ -792,11 +792,11 @@ void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigatio
} break;
case MoveDirection::Down: {
if (!activeControl) { // no any active
toControl = firstEnabled(activeSubSec->controls(), IKeyNavigation::Index(), direction);
toControl = firstEnabled(activeSubSec->controls(), INavigation::Index(), direction);
} else {
toControl = nextEnabled(activeSubSec->controls(), activeControl->index(), direction);
if (!toControl) { // active is last
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.row = -1;
toControl = firstEnabled(activeSubSec->controls(), index, direction); // the first to be the next
}
@ -804,11 +804,11 @@ void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigatio
} break;
case MoveDirection::Left: {
if (!activeControl) { // no any active
toControl = lastEnabled(activeSubSec->controls(), IKeyNavigation::Index(), direction);
toControl = lastEnabled(activeSubSec->controls(), INavigation::Index(), direction);
} else {
toControl = prevEnabled(activeSubSec->controls(), activeControl->index(), direction);
if (!toControl) { // active is first
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.column = std::numeric_limits<int>::max();
toControl = lastEnabled(activeSubSec->controls(), index, direction); // the last to be the next
}
@ -816,11 +816,11 @@ void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigatio
} break;
case MoveDirection::Up: {
if (!activeControl) { // no any active
toControl = lastEnabled(activeSubSec->controls(), IKeyNavigation::Index(), direction);
toControl = lastEnabled(activeSubSec->controls(), INavigation::Index(), direction);
} else {
toControl = prevEnabled(activeSubSec->controls(), activeControl->index(), direction);
if (!toControl) { // active is first
IKeyNavigation::Index index = activeControl->index();
INavigation::Index index = activeControl->index();
index.row = std::numeric_limits<int>::max();
toControl = lastEnabled(activeSubSec->controls(), index, direction); // the last to be the next
}
@ -833,10 +833,10 @@ void KeyNavigationController::goToControl(MoveDirection direction, IKeyNavigatio
}
}
void KeyNavigationController::doTriggerControl()
void NavigationController::doTriggerControl()
{
LOGI() << "====";
IKeyNavigationControl* activeCtrl= activeControl();
INavigationControl* activeCtrl= activeControl();
if (!activeCtrl) {
return;
}
@ -845,13 +845,13 @@ void KeyNavigationController::doTriggerControl()
activeCtrl->trigger();
}
void KeyNavigationController::onForceActiveRequested(IKeyNavigationSection* sec, IKeyNavigationSubSection* sub, IKeyNavigationControl* ctrl)
void NavigationController::onForceActiveRequested(INavigationSection* sec, INavigationPanel* sub, INavigationControl* ctrl)
{
if (m_sections.empty()) {
return;
}
IKeyNavigationSection* activeSec = findActive(m_sections);
INavigationSection* activeSec = findActive(m_sections);
if (activeSec && activeSec != sec) {
doDeactivateSection(activeSec);
}
@ -859,15 +859,15 @@ void KeyNavigationController::onForceActiveRequested(IKeyNavigationSection* sec,
sec->setActive(true);
LOGD() << "activated section: " << sec->name() << ", order: " << sec->index().order();
IKeyNavigationSubSection* activeSub = findActive(sec->subsections());
INavigationPanel* activeSub = findActive(sec->panels());
if (activeSub && activeSub != sub) {
doDeactivateSubSection(activeSub);
doDeactivatePanel(activeSub);
}
sub->setActive(true);
LOGD() << "activated subsection: " << sub->name() << ", order: " << sub->index().order();
IKeyNavigationControl* activeCtrl = findActive(sub->controls());
INavigationControl* activeCtrl = findActive(sub->controls());
if (activeCtrl && activeCtrl != ctrl) {
activeCtrl->setActive(false);
}

View File

@ -19,12 +19,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONCONTROLLER_H
#define MU_UI_KEYNAVIGATIONCONTROLLER_H
#ifndef MU_UI_NAVIGATIONCONTROLLER_H
#define MU_UI_NAVIGATIONCONTROLLER_H
#include <QList>
#include "../ikeynavigationcontroller.h"
#include "../inavigationcontroller.h"
#include "modularity/ioc.h"
#include "actions/iactionsdispatcher.h"
#include "actions/actionable.h"
@ -32,13 +32,13 @@
#include "global/iinteractive.h"
namespace mu::ui {
class KeyNavigationController : public IKeyNavigationController, public actions::Actionable, public async::Asyncable
class NavigationController : public INavigationController, public actions::Actionable, public async::Asyncable
{
INJECT(ui, actions::IActionsDispatcher, dispatcher)
INJECT(ui, framework::IInteractive, interactive)
public:
KeyNavigationController() = default;
NavigationController() = default;
enum MoveDirection {
First = 0,
@ -49,10 +49,10 @@ public:
Down
};
void reg(IKeyNavigationSection* s) override;
void unreg(IKeyNavigationSection* s) override;
void reg(INavigationSection* section) override;
void unreg(INavigationSection* section) override;
const std::set<IKeyNavigationSection*>& sections() const override;
const std::set<INavigationSection*>& sections() const override;
void init();
@ -62,15 +62,15 @@ private:
void goToNextSection();
void goToPrevSection();
void goToNextSubSection();
void goToPrevSubSection();
void goToNextPanel();
void goToPrevPanel();
void goToFirstControl();
void goToLastControl();
void goToNextRowControl();
void goToPrevRowControl();
void goToControl(MoveDirection direction, IKeyNavigationSubSection* activeSubSec = nullptr);
void goToControl(MoveDirection direction, INavigationPanel* activeSubSec = nullptr);
void onLeft();
void onRight();
@ -79,24 +79,24 @@ private:
void onEscape();
void doTriggerControl();
void onForceActiveRequested(IKeyNavigationSection* sec, IKeyNavigationSubSection* sub, IKeyNavigationControl* ctrl);
void onForceActiveRequested(INavigationSection* sec, INavigationPanel* sub, INavigationControl* ctrl);
void doActivateSection(IKeyNavigationSection* s);
void doDeactivateSection(IKeyNavigationSection* s);
void doActivateSubSection(IKeyNavigationSubSection* s);
void doDeactivateSubSection(IKeyNavigationSubSection* s);
void doActivateControl(IKeyNavigationControl* c);
void doDeactivateControl(IKeyNavigationControl* c);
void doActivateSection(INavigationSection* s);
void doDeactivateSection(INavigationSection* s);
void doActivatePanel(INavigationPanel* s);
void doDeactivatePanel(INavigationPanel* s);
void doActivateControl(INavigationControl* c);
void doDeactivateControl(INavigationControl* c);
void doActivateFirst();
void doActivateLast();
IKeyNavigationSection* activeSection() const;
IKeyNavigationSubSection* activeSubSection() const;
IKeyNavigationControl* activeControl() const;
INavigationSection* activeSection() const;
INavigationPanel* activePanel() const;
INavigationControl* activeControl() const;
std::set<IKeyNavigationSection*> m_sections;
std::set<INavigationSection*> m_sections;
};
}
#endif // MU_UI_KEYNAVIGATIONCONTROLLER_H
#endif // MU_UI_NAVIGATIONCONTROLLER_H

View File

@ -19,14 +19,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "keynavigationuiactions.h"
#include "navigationuiactions.h"
#include "context/uicontext.h"
using namespace mu::ui;
using namespace mu::actions;
const UiActionList KeyNavigationUiActions::m_actions = {
const UiActionList NavigationUiActions::m_actions = {
UiAction("nav-dev-show-controls",
mu::context::UiCtxAny
),
@ -36,10 +36,10 @@ const UiActionList KeyNavigationUiActions::m_actions = {
UiAction("nav-prev-section",
mu::context::UiCtxAny
),
UiAction("nav-next-subsection",
UiAction("nav-next-panel",
mu::context::UiCtxAny
),
UiAction("nav-prev-subsection",
UiAction("nav-prev-panel",
mu::context::UiCtxAny
),
UiAction("nav-right",
@ -74,28 +74,28 @@ const UiActionList KeyNavigationUiActions::m_actions = {
)
};
const UiActionList& KeyNavigationUiActions::actionsList() const
const UiActionList& NavigationUiActions::actionsList() const
{
return m_actions;
}
bool KeyNavigationUiActions::actionEnabled(const UiAction&) const
bool NavigationUiActions::actionEnabled(const UiAction&) const
{
return true;
}
mu::async::Channel<ActionCodeList> KeyNavigationUiActions::actionEnabledChanged() const
mu::async::Channel<ActionCodeList> NavigationUiActions::actionEnabledChanged() const
{
static async::Channel<ActionCodeList> ch;
return ch;
}
bool KeyNavigationUiActions::actionChecked(const UiAction&) const
bool NavigationUiActions::actionChecked(const UiAction&) const
{
return false;
}
mu::async::Channel<ActionCodeList> KeyNavigationUiActions::actionCheckedChanged() const
mu::async::Channel<ActionCodeList> NavigationUiActions::actionCheckedChanged() const
{
static async::Channel<ActionCodeList> ch;
return ch;

View File

@ -19,16 +19,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONUIACTIONS_H
#define MU_UI_KEYNAVIGATIONUIACTIONS_H
#ifndef MU_UI_NAVIGATIONUIACTIONS_H
#define MU_UI_NAVIGATIONUIACTIONS_H
#include "../iuiactionsmodule.h"
namespace mu::ui {
class KeyNavigationUiActions : public IUiActionsModule
class NavigationUiActions : public IUiActionsModule
{
public:
KeyNavigationUiActions() = default;
NavigationUiActions() = default;
const UiActionList& actionsList() const override;
bool actionEnabled(const UiAction& act) const override;
@ -42,4 +42,4 @@ private:
};
}
#endif // MU_UI_KEYNAVIGATIONUIACTIONS_H
#endif // MU_UI_NAVIGATIONUIACTIONS_H

View File

@ -115,7 +115,7 @@ Rectangle {
id: subitem
property var subsection: modelData
property var panel: modelData
anchors.left: parent.left
anchors.right: parent.right
@ -123,8 +123,8 @@ Rectangle {
Rectangle {
anchors.fill: parent
color: subitem.subsection.enabled ? "#729fcf" : "#eeeeec"
border.width: subitem.subsection.active ? 2 : 0
color: subitem.panel.enabled ? "#729fcf" : "#eeeeec"
border.width: subitem.panel.active ? 2 : 0
border.color: ui.theme.focusColor
}
@ -133,9 +133,9 @@ Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: 8
text: "subsection: " + subitem.subsection.name
+ ", " + root.formatIndex(subitem.subsection.index)
+ ", enabled: " + subitem.subsection.enabled
text: "panel: " + subitem.panel.name
+ ", " + root.formatIndex(subitem.panel.index)
+ ", enabled: " + subitem.panel.enabled
}
GridView {
@ -151,7 +151,7 @@ Rectangle {
cellHeight: 32
cellWidth: 68
model: subitem.subsection.controls
model: subitem.panel.controls
delegate: Rectangle {
property var control: modelData

View File

@ -29,8 +29,8 @@
#include "internal/uiconfiguration.h"
#include "internal/interactiveuriregister.h"
#include "internal/uiactionsregister.h"
#include "internal/keynavigationcontroller.h"
#include "internal/keynavigationuiactions.h"
#include "internal/navigationcontroller.h"
#include "internal/navigationuiactions.h"
#ifdef Q_OS_MAC
#include "internal/platform/macos/macosplatformtheme.h"
@ -44,11 +44,11 @@
#include "view/iconcodes.h"
#include "view/musicalsymbolcodes.h"
#include "view/qmldialog.h"
#include "view/keynavigationsection.h"
#include "view/keynavigationsubsection.h"
#include "view/keynavigationpopuppanel.h"
#include "view/keynavigationcontrol.h"
#include "view/keynavigationevent.h"
#include "view/navigationsection.h"
#include "view/navigationpanel.h"
#include "view/navigationpopuppanel.h"
#include "view/navigationcontrol.h"
#include "view/navigationevent.h"
#include "dev/interactivetestsmodel.h"
#include "dev/testdialog.h"
@ -63,8 +63,8 @@ using namespace mu::framework;
static std::shared_ptr<UiConfiguration> s_configuration = std::make_shared<UiConfiguration>();
static std::shared_ptr<UiActionsRegister> s_uiactionsRegister = std::make_shared<UiActionsRegister>();
static std::shared_ptr<KeyNavigationController> s_keyNavigationController = std::make_shared<KeyNavigationController>();
static std::shared_ptr<KeyNavigationUiActions> s_keyNavigationUiActions = std::make_shared<KeyNavigationUiActions>();
static std::shared_ptr<NavigationController> s_keyNavigationController = std::make_shared<NavigationController>();
static std::shared_ptr<NavigationUiActions> s_keyNavigationUiActions = std::make_shared<NavigationUiActions>();
#ifdef Q_OS_MAC
static std::shared_ptr<MacOSPlatformTheme> s_platformTheme = std::make_shared<MacOSPlatformTheme>();
@ -92,7 +92,7 @@ void UiModule::registerExports()
ioc()->registerExport<IInteractiveUriRegister>(moduleName(), new InteractiveUriRegister());
ioc()->registerExport<IPlatformTheme>(moduleName(), s_platformTheme);
ioc()->registerExport<IUiActionsRegister>(moduleName(), s_uiactionsRegister);
ioc()->registerExport<IKeyNavigationController>(moduleName(), s_keyNavigationController);
ioc()->registerExport<INavigationController>(moduleName(), s_keyNavigationController);
}
void UiModule::resolveImports()
@ -128,12 +128,12 @@ void UiModule::registerUiTypes()
qmlRegisterType<QmlDialog>("MuseScore.Ui", 1, 0, "QmlDialog");
qmlRegisterUncreatableType<AbstractKeyNavigation>("MuseScore.Ui", 1, 0, "AbstractKeyNavigation", "Cannot create a AbstractType");
qmlRegisterUncreatableType<KeyNavigationEvent>("MuseScore.Ui", 1, 0, "KeyNavigationEvent", "Cannot create a KeyNavigationEvent");
qmlRegisterType<KeyNavigationSection>("MuseScore.Ui", 1, 0, "KeyNavigationSection");
qmlRegisterType<KeyNavigationSubSection>("MuseScore.Ui", 1, 0, "KeyNavigationSubSection");
qmlRegisterType<KeyNavigationPopupPanel>("MuseScore.Ui", 1, 0, "KeyNavigationPopupPanel");
qmlRegisterType<KeyNavigationControl>("MuseScore.Ui", 1, 0, "KeyNavigationControl");
qmlRegisterUncreatableType<AbstractNavigation>("MuseScore.Ui", 1, 0, "AbstractNavigation", "Cannot create a AbstractType");
qmlRegisterUncreatableType<NavigationEvent>("MuseScore.Ui", 1, 0, "NavigationEvent", "Cannot create a KeyNavigationEvent");
qmlRegisterType<NavigationSection>("MuseScore.Ui", 1, 0, "NavigationSection");
qmlRegisterType<NavigationPanel>("MuseScore.Ui", 1, 0, "NavigationPanel");
qmlRegisterType<NavigationPopupPanel>("MuseScore.Ui", 1, 0, "NavigationPopupPanel");
qmlRegisterType<NavigationControl>("MuseScore.Ui", 1, 0, "NavigationControl");
qmlRegisterType<InteractiveTestsModel>("MuseScore.Ui", 1, 0, "InteractiveTestsModel");
qRegisterMetaType<TestDialog>("TestDialog");

View File

@ -19,18 +19,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "abstractkeynavigation.h"
#include "abstractnavigation.h"
#include "log.h"
using namespace mu::ui;
AbstractKeyNavigation::AbstractKeyNavigation(QObject* parent)
AbstractNavigation::AbstractNavigation(QObject* parent)
: QObject(parent)
{
}
void AbstractKeyNavigation::setName(QString name)
void AbstractNavigation::setName(QString name)
{
if (m_name == name) {
return;
@ -40,22 +40,22 @@ void AbstractKeyNavigation::setName(QString name)
emit nameChanged(m_name);
}
QString AbstractKeyNavigation::name() const
QString AbstractNavigation::name() const
{
return m_name;
}
const IKeyNavigation::Index& AbstractKeyNavigation::index() const
const INavigation::Index& AbstractNavigation::index() const
{
return m_index;
}
mu::async::Channel<IKeyNavigation::Index> AbstractKeyNavigation::indexChanged() const
mu::async::Channel<INavigation::Index> AbstractNavigation::indexChanged() const
{
return m_indexChanged;
}
void AbstractKeyNavigation::setOrder(int order)
void AbstractNavigation::setOrder(int order)
{
if (m_index.order() == order) {
return;
@ -69,12 +69,12 @@ void AbstractKeyNavigation::setOrder(int order)
}
}
int AbstractKeyNavigation::order() const
int AbstractNavigation::order() const
{
return m_index.order();
}
void AbstractKeyNavigation::setColumn(int column)
void AbstractNavigation::setColumn(int column)
{
if (m_index.column == column) {
return;
@ -88,12 +88,12 @@ void AbstractKeyNavigation::setColumn(int column)
}
}
int AbstractKeyNavigation::column() const
int AbstractNavigation::column() const
{
return m_index.column;
}
void AbstractKeyNavigation::setRow(int row)
void AbstractNavigation::setRow(int row)
{
if (m_index.row == row) {
return;
@ -107,12 +107,12 @@ void AbstractKeyNavigation::setRow(int row)
}
}
int AbstractKeyNavigation::row() const
int AbstractNavigation::row() const
{
return m_index.row;
}
void AbstractKeyNavigation::setEnabled(bool enabled)
void AbstractNavigation::setEnabled(bool enabled)
{
if (m_enabled == enabled) {
return;
@ -126,17 +126,17 @@ void AbstractKeyNavigation::setEnabled(bool enabled)
}
}
bool AbstractKeyNavigation::enabled() const
bool AbstractNavigation::enabled() const
{
return m_enabled;
}
mu::async::Channel<bool> AbstractKeyNavigation::enabledChanged() const
mu::async::Channel<bool> AbstractNavigation::enabledChanged() const
{
return m_enabledChanged;
}
void AbstractKeyNavigation::setActive(bool active)
void AbstractNavigation::setActive(bool active)
{
if (m_active == active) {
return;
@ -150,26 +150,26 @@ void AbstractKeyNavigation::setActive(bool active)
}
}
bool AbstractKeyNavigation::active() const
bool AbstractNavigation::active() const
{
return m_active;
}
mu::async::Channel<bool> AbstractKeyNavigation::activeChanged() const
mu::async::Channel<bool> AbstractNavigation::activeChanged() const
{
return m_activeChanged;
}
void AbstractKeyNavigation::onEvent(IKeyNavigation::EventPtr e)
void AbstractNavigation::onEvent(INavigation::EventPtr e)
{
KeyNavigationEvent ev(e);
NavigationEvent ev(e);
emit keyNavEvent(QVariant::fromValue(ev));
}
void AbstractKeyNavigation::classBegin()
void AbstractNavigation::classBegin()
{
}
void AbstractKeyNavigation::componentComplete()
void AbstractNavigation::componentComplete()
{
}

View File

@ -19,24 +19,24 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_ABSTRACTKEYNAVIGATION_H
#define MU_UI_ABSTRACTKEYNAVIGATION_H
#ifndef MU_UI_ABSTRACTNAVIGATION_H
#define MU_UI_ABSTRACTNAVIGATION_H
#include <QObject>
#include <QQmlParserStatus>
#include "../ikeynavigation.h"
#include "keynavigationevent.h"
#include "../inavigation.h"
#include "navigationevent.h"
namespace mu::ui {
class AbstractKeyNavigation : public QObject, public QQmlParserStatus
class AbstractNavigation : public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
// see IKeyNavigation::Index
// see INavigation::Index
Q_PROPERTY(int order READ order WRITE setOrder NOTIFY orderChanged)
Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged)
Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
@ -45,7 +45,7 @@ class AbstractKeyNavigation : public QObject, public QQmlParserStatus
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
public:
explicit AbstractKeyNavigation(QObject* parent = nullptr);
explicit AbstractNavigation(QObject* parent = nullptr);
int order() const;
int column() const;
@ -53,8 +53,8 @@ public:
QString name() const;
const IKeyNavigation::Index& index() const;
async::Channel<IKeyNavigation::Index> indexChanged() const;
const INavigation::Index& index() const;
async::Channel<INavigation::Index> indexChanged() const;
bool enabled() const;
async::Channel<bool> enabledChanged() const;
@ -62,7 +62,7 @@ public:
bool active() const;
async::Channel<bool> activeChanged() const;
void onEvent(IKeyNavigation::EventPtr e);
void onEvent(INavigation::EventPtr e);
// QQmlParserStatus
void classBegin() override;
@ -89,8 +89,8 @@ signals:
protected:
QString m_name;
IKeyNavigation::Index m_index;
async::Channel<IKeyNavigation::Index> m_indexChanged;
INavigation::Index m_index;
async::Channel<INavigation::Index> m_indexChanged;
bool m_enabled = true;
async::Channel<bool> m_enabledChanged;
@ -98,8 +98,8 @@ protected:
bool m_active = false;
async::Channel<bool> m_activeChanged;
KeyNavigationEvent* m_event = nullptr;
NavigationEvent* m_event = nullptr;
};
}
#endif // MU_UI_ABSTRACTKEYNAVIGATION_H
#endif // MU_UI_ABSTRACTNAVIGATION_H

View File

@ -0,0 +1,128 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "navigationcontrol.h"
#include "navigationpanel.h"
using namespace mu::ui;
NavigationControl::NavigationControl(QObject* parent)
: AbstractNavigation(parent)
{
}
NavigationControl::~NavigationControl()
{
if (m_panel) {
m_panel->removeControl(this);
}
}
QString NavigationControl::name() const
{
return AbstractNavigation::name();
}
const INavigation::Index& NavigationControl::index() const
{
return AbstractNavigation::index();
}
mu::async::Channel<INavigation::Index> NavigationControl::indexChanged() const
{
return AbstractNavigation::indexChanged();
}
bool NavigationControl::enabled() const
{
return AbstractNavigation::enabled();
}
mu::async::Channel<bool> NavigationControl::enabledChanged() const
{
return AbstractNavigation::enabledChanged();
}
bool NavigationControl::active() const
{
return AbstractNavigation::active();
}
void NavigationControl::setActive(bool arg)
{
AbstractNavigation::setActive(arg);
}
mu::async::Channel<bool> NavigationControl::activeChanged() const
{
return AbstractNavigation::activeChanged();
}
void NavigationControl::onEvent(EventPtr e)
{
AbstractNavigation::onEvent(e);
}
void NavigationControl::trigger()
{
emit triggered();
}
mu::async::Channel<INavigationControl*> NavigationControl::forceActiveRequested() const
{
return m_forceActiveRequested;
}
void NavigationControl::forceActive()
{
m_forceActiveRequested.send(this);
}
void NavigationControl::setPanel(NavigationPanel* panel)
{
if (m_panel == panel) {
return;
}
if (m_panel) {
m_panel->removeControl(this);
m_panel->disconnect(this);
}
m_panel = panel;
if (m_panel) {
m_panel->addControl(this);
connect(m_panel, &NavigationPanel::destroyed, this, &NavigationControl::onPanelDestroyed);
}
emit panelChanged(m_panel);
}
void NavigationControl::onPanelDestroyed()
{
m_panel = nullptr;
}
NavigationPanel* NavigationControl::panel() const
{
return m_panel;
}

View File

@ -19,27 +19,26 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONCONTROL_H
#define MU_UI_KEYNAVIGATIONCONTROL_H
#ifndef MU_UI_NAVIGATIONCONTROL_H
#define MU_UI_NAVIGATIONCONTROL_H
#include <QObject>
#include "abstractkeynavigation.h"
#include "../ikeynavigation.h"
#include "keynavigationsubsection.h"
#include "abstractnavigation.h"
#include "async/asyncable.h"
namespace mu::ui {
class KeyNavigationControl : public AbstractKeyNavigation, public IKeyNavigationControl, public async::Asyncable
class NavigationPanel;
class NavigationControl : public AbstractNavigation, public INavigationControl, public async::Asyncable
{
Q_OBJECT
Q_PROPERTY(KeyNavigationSubSection * subsection READ subsection WRITE setSubSection NOTIFY subsectionChanged)
Q_PROPERTY(mu::ui::NavigationPanel* panel READ panel WRITE setPanel NOTIFY panelChanged)
public:
explicit KeyNavigationControl(QObject* parent = nullptr);
~KeyNavigationControl() override;
explicit NavigationControl(QObject* parent = nullptr);
~NavigationControl() override;
KeyNavigationSubSection* subsection() const;
NavigationPanel* panel() const;
QString name() const override;
@ -56,25 +55,25 @@ public:
void onEvent(EventPtr e) override;
void trigger() override;
async::Channel<IKeyNavigationControl*> forceActiveRequested() const override;
async::Channel<INavigationControl*> forceActiveRequested() const override;
Q_INVOKABLE void forceActive();
public slots:
void setSubSection(KeyNavigationSubSection* subsection);
void setPanel(NavigationPanel* panel);
signals:
void subsectionChanged(KeyNavigationSubSection* subsection);
void panelChanged(NavigationPanel* panel);
void triggered();
private slots:
void onSubSectionDestroyed();
void onPanelDestroyed();
private:
KeyNavigationSubSection* m_subsection = nullptr;
async::Channel<IKeyNavigationControl*> m_forceActiveRequested;
NavigationPanel* m_panel = nullptr;
async::Channel<INavigationControl*> m_forceActiveRequested;
};
}
#endif // MU_UI_KEYNAVIGATIONCONTROL_H
#endif // MU_UI_NAVIGATIONCONTROL_H

View File

@ -19,23 +19,23 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "keynavigationevent.h"
#include "navigationevent.h"
#include "log.h"
using namespace mu::ui;
KeyNavigationEvent::KeyNavigationEvent(IKeyNavigation::EventPtr event)
NavigationEvent::NavigationEvent(INavigation::EventPtr event)
: m_event(event)
{
}
void KeyNavigationEvent::setEvent(IKeyNavigation::EventPtr event)
void NavigationEvent::setEvent(INavigation::EventPtr event)
{
m_event = event;
}
KeyNavigationEvent::Type KeyNavigationEvent::type() const
NavigationEvent::Type NavigationEvent::type() const
{
IF_ASSERT_FAILED(m_event) {
return Undefined;
@ -43,7 +43,7 @@ KeyNavigationEvent::Type KeyNavigationEvent::type() const
return static_cast<Type>(m_event->type);
}
void KeyNavigationEvent::setAccepted(bool accepted)
void NavigationEvent::setAccepted(bool accepted)
{
IF_ASSERT_FAILED(m_event) {
return;
@ -51,7 +51,7 @@ void KeyNavigationEvent::setAccepted(bool accepted)
m_event->accepted = accepted;
}
bool KeyNavigationEvent::accepted() const
bool NavigationEvent::accepted() const
{
IF_ASSERT_FAILED(m_event) {
return false;

View File

@ -19,23 +19,23 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONEVENT_H
#define MU_UI_KEYNAVIGATIONEVENT_H
#ifndef MU_UI_NAVIGATIONEVENT_H
#define MU_UI_NAVIGATIONEVENT_H
#include <QObject>
#include "ui/ikeynavigation.h"
#include "ui/inavigation.h"
namespace mu::ui {
class KeyNavigationEvent
class NavigationEvent
{
Q_GADGET
Q_PROPERTY(Type type READ type CONSTANT)
Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
public:
KeyNavigationEvent(IKeyNavigation::EventPtr event = nullptr);
NavigationEvent(INavigation::EventPtr event = nullptr);
//! NOTE Please sync with IKeyNavigation::Event::Type
//! NOTE Please sync with INavigation::Event::Type
enum Type {
Undefined = 0,
Left,
@ -46,16 +46,16 @@ public:
};
Q_ENUM(Type)
void setEvent(IKeyNavigation::EventPtr event);
void setEvent(INavigation::EventPtr event);
Type type() const;
bool accepted() const;
void setAccepted(bool accepted);
private:
IKeyNavigation::EventPtr m_event;
INavigation::EventPtr m_event;
};
}
Q_DECLARE_METATYPE(mu::ui::KeyNavigationEvent)
Q_DECLARE_METATYPE(mu::ui::NavigationEvent)
#endif // MU_UI_KEYNAVIGATIONEVENT_H
#endif // MU_UI_NAVIGATIONEVENT_H

View File

@ -0,0 +1,187 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "navigationpanel.h"
#include <algorithm>
#include "navigationsection.h"
#include "log.h"
using namespace mu::ui;
NavigationPanel::NavigationPanel(QObject* parent)
: AbstractNavigation(parent)
{
}
NavigationPanel::~NavigationPanel()
{
if (m_section) {
m_section->removePanel(this);
}
}
QString NavigationPanel::name() const
{
return AbstractNavigation::name();
}
const INavigation::Index& NavigationPanel::index() const
{
return AbstractNavigation::index();
}
mu::async::Channel<INavigation::Index> NavigationPanel::indexChanged() const
{
return AbstractNavigation::indexChanged();
}
bool NavigationPanel::enabled() const
{
return AbstractNavigation::enabled();
}
mu::async::Channel<bool> NavigationPanel::enabledChanged() const
{
return AbstractNavigation::enabledChanged();
}
bool NavigationPanel::active() const
{
return AbstractNavigation::active();
}
void NavigationPanel::setActive(bool arg)
{
AbstractNavigation::setActive(arg);
}
mu::async::Channel<bool> NavigationPanel::activeChanged() const
{
return AbstractNavigation::activeChanged();
}
void NavigationPanel::onEvent(EventPtr e)
{
AbstractNavigation::onEvent(e);
}
void NavigationPanel::setDirection(QmlDirection direction)
{
if (m_direction == direction) {
return;
}
m_direction = direction;
emit directionChanged(m_direction);
}
NavigationPanel::QmlDirection NavigationPanel::direction_property() const
{
return m_direction;
}
INavigationPanel::Direction NavigationPanel::direction() const
{
return static_cast<Direction>(m_direction);
}
const std::set<INavigationControl*>& NavigationPanel::controls() const
{
return m_controls;
}
mu::async::Notification NavigationPanel::controlsListChanged() const
{
return m_controlsListChanged;
}
mu::async::Channel<PanelControl> NavigationPanel::forceActiveRequested() const
{
return m_forceActiveRequested;
}
NavigationSection* NavigationPanel::section() const
{
return m_section;
}
void NavigationPanel::setSection(NavigationSection* section)
{
if (m_section == section) {
return;
}
if (m_section) {
m_section->removePanel(this);
m_section->disconnect(this);
}
m_section = section;
if (m_section) {
m_section->addPanel(this);
connect(m_section, &NavigationSection::destroyed, this, &NavigationPanel::onSectionDestroyed);
}
emit sectionChanged(m_section);
}
void NavigationPanel::onSectionDestroyed()
{
m_section = nullptr;
}
void NavigationPanel::componentComplete()
{
}
void NavigationPanel::addControl(NavigationControl* control)
{
IF_ASSERT_FAILED(control) {
return;
}
m_controls.insert(control);
control->forceActiveRequested().onReceive(this, [this](INavigationControl* c) {
m_forceActiveRequested.send(std::make_tuple(this, c));
});
if (m_controlsListChanged.isConnected()) {
m_controlsListChanged.notify();
}
}
void NavigationPanel::removeControl(NavigationControl* control)
{
IF_ASSERT_FAILED(control) {
return;
}
m_controls.erase(control);
control->forceActiveRequested().resetOnReceive(this);
if (m_controlsListChanged.isConnected()) {
m_controlsListChanged.notify();
}
}

View File

@ -19,28 +19,27 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONSUBSECTION_H
#define MU_UI_KEYNAVIGATIONSUBSECTION_H
#ifndef MU_UI_NAVIGATIONPANEL_H
#define MU_UI_NAVIGATIONPANEL_H
#include <QObject>
#include <QList>
#include "abstractkeynavigation.h"
#include "../ikeynavigation.h"
#include "keynavigationsection.h"
#include "abstractnavigation.h"
#include "navigationcontrol.h"
#include "async/asyncable.h"
namespace mu::ui {
class KeyNavigationControl;
class KeyNavigationSubSection : public AbstractKeyNavigation, public IKeyNavigationSubSection, public async::Asyncable
class NavigationSection;
class NavigationPanel : public AbstractNavigation, public INavigationPanel, public async::Asyncable
{
Q_OBJECT
Q_PROPERTY(KeyNavigationSection * section READ section WRITE setSection NOTIFY sectionChanged)
Q_PROPERTY(mu::ui::NavigationSection* section READ section WRITE setSection NOTIFY sectionChanged)
Q_PROPERTY(QmlDirection direction READ direction_property WRITE setDirection NOTIFY directionChanged)
public:
explicit KeyNavigationSubSection(QObject* parent = nullptr);
~KeyNavigationSubSection() override;
explicit NavigationPanel(QObject* parent = nullptr);
~NavigationPanel() override;
//! NOTE Please sync with IKeyNavigationSubSection::Direction
enum QmlDirection {
@ -67,36 +66,36 @@ public:
QmlDirection direction_property() const;
Direction direction() const override;
const std::set<IKeyNavigationControl*>& controls() const override;
const std::set<INavigationControl*>& controls() const override;
async::Notification controlsListChanged() const override;
async::Channel<SubSectionControl> forceActiveRequested() const override;
async::Channel<PanelControl> forceActiveRequested() const override;
KeyNavigationSection* section() const;
NavigationSection* section() const;
void componentComplete() override;
void addControl(KeyNavigationControl* control);
void removeControl(KeyNavigationControl* control);
void addControl(NavigationControl* control);
void removeControl(NavigationControl* control);
public slots:
void setSection(KeyNavigationSection* section);
void setSection(NavigationSection* section);
void setDirection(QmlDirection direction);
signals:
void sectionChanged(KeyNavigationSection* section);
void sectionChanged(NavigationSection* section);
void directionChanged(QmlDirection direction);
private slots:
void onSectionDestroyed();
private:
KeyNavigationSection* m_section = nullptr;
std::set<IKeyNavigationControl*> m_controls;
NavigationSection* m_section = nullptr;
std::set<INavigationControl*> m_controls;
async::Notification m_controlsListChanged;
async::Channel<SubSectionControl> m_forceActiveRequested;
async::Channel<PanelControl> m_forceActiveRequested;
QmlDirection m_direction = QmlDirection::Horizontal;
};
}
#endif // MU_UI_KEYNAVIGATIONSUBSECTION_H
#endif // MU_UI_NAVIGATIONPANEL_H

View File

@ -19,21 +19,21 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "keynavigationpopuppanel.h"
#include "navigationpopuppanel.h"
using namespace mu::ui;
KeyNavigationPopupPanel::KeyNavigationPopupPanel(QObject* parent)
: KeyNavigationSubSection(parent)
NavigationPopupPanel::NavigationPopupPanel(QObject* parent)
: NavigationPanel(parent)
{
}
KeyNavigationControl* KeyNavigationPopupPanel::parentControl() const
NavigationControl* NavigationPopupPanel::parentControl() const
{
return m_parentControl;
}
void KeyNavigationPopupPanel::setParentControl(KeyNavigationControl* parentControl)
void NavigationPopupPanel::setParentControl(NavigationControl* parentControl)
{
if (m_parentControl == parentControl) {
return;
@ -42,8 +42,8 @@ void KeyNavigationPopupPanel::setParentControl(KeyNavigationControl* parentContr
m_parentControl = parentControl;
emit parentControlChanged(m_parentControl);
if (m_parentControl && m_parentControl->subsection()) {
setSection(m_parentControl->subsection()->section());
if (m_parentControl && m_parentControl->panel()) {
setSection(m_parentControl->panel()->section());
} else {
setSection(nullptr);
}

View File

@ -19,33 +19,32 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONPOPUPPANEL_H
#define MU_UI_KEYNAVIGATIONPOPUPPANEL_H
#ifndef MU_UI_NAVIGATIONPOPUPPANEL_H
#define MU_UI_NAVIGATIONPOPUPPANEL_H
#include <QObject>
#include "keynavigationsubsection.h"
#include "keynavigationcontrol.h"
#include "navigationpanel.h"
namespace mu::ui {
class KeyNavigationPopupPanel : public KeyNavigationSubSection
class NavigationPopupPanel : public NavigationPanel
{
Q_OBJECT
Q_PROPERTY(KeyNavigationControl * parentControl READ parentControl WRITE setParentControl NOTIFY parentControlChanged)
Q_PROPERTY(NavigationControl * parentControl READ parentControl WRITE setParentControl NOTIFY parentControlChanged)
public:
explicit KeyNavigationPopupPanel(QObject* parent = nullptr);
explicit NavigationPopupPanel(QObject* parent = nullptr);
KeyNavigationControl* parentControl() const;
NavigationControl* parentControl() const;
public slots:
void setParentControl(KeyNavigationControl* parentControl);
void setParentControl(NavigationControl* parentControl);
signals:
void parentControlChanged(KeyNavigationControl* parentControl);
void parentControlChanged(NavigationControl* parentControl);
private:
KeyNavigationControl* m_parentControl = nullptr;
NavigationControl* m_parentControl = nullptr;
};
}
#endif // MU_UI_KEYNAVIGATIONPOPUPPANEL_H
#endif // MU_UI_NAVIGATIONPOPUPPANEL_H

View File

@ -0,0 +1,143 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "navigationsection.h"
#include <algorithm>
#include "log.h"
using namespace mu::ui;
NavigationSection::NavigationSection(QObject* parent)
: AbstractNavigation(parent)
{
}
NavigationSection::~NavigationSection()
{
navigationController()->unreg(this);
}
void NavigationSection::componentComplete()
{
//! NOTE Reg after set properties.
IF_ASSERT_FAILED(!m_name.isEmpty()) {
return;
}
IF_ASSERT_FAILED(order() > -1) {
return;
}
navigationController()->reg(this);
}
QString NavigationSection::name() const
{
return AbstractNavigation::name();
}
const INavigation::Index& NavigationSection::index() const
{
return AbstractNavigation::index();
}
mu::async::Channel<INavigation::Index> NavigationSection::indexChanged() const
{
return AbstractNavigation::indexChanged();
}
bool NavigationSection::enabled() const
{
return AbstractNavigation::enabled();
}
mu::async::Channel<bool> NavigationSection::enabledChanged() const
{
return AbstractNavigation::enabledChanged();
}
bool NavigationSection::active() const
{
return AbstractNavigation::active();
}
void NavigationSection::setActive(bool arg)
{
AbstractNavigation::setActive(arg);
}
mu::async::Channel<bool> NavigationSection::activeChanged() const
{
return AbstractNavigation::activeChanged();
}
void NavigationSection::onEvent(EventPtr e)
{
AbstractNavigation::onEvent(e);
}
void NavigationSection::addPanel(NavigationPanel* panel)
{
IF_ASSERT_FAILED(panel) {
return;
}
m_panels.insert(panel);
panel->forceActiveRequested().onReceive(this, [this](const PanelControl& subcon) {
m_forceActiveRequested.send(std::make_tuple(this, std::get<0>(subcon), std::get<1>(subcon)));
});
if (m_panelsListChanged.isConnected()) {
m_panelsListChanged.notify();
}
}
mu::async::Channel<SectionPanelControl> NavigationSection::forceActiveRequested() const
{
return m_forceActiveRequested;
}
void NavigationSection::removePanel(NavigationPanel* panel)
{
IF_ASSERT_FAILED(panel) {
return;
}
m_panels.erase(panel);
panel->forceActiveRequested().resetOnReceive(this);
if (m_panelsListChanged.isConnected()) {
m_panelsListChanged.notify();
}
}
const std::set<INavigationPanel*>& NavigationSection::panels() const
{
return m_panels;
}
mu::async::Notification NavigationSection::panelsListChanged() const
{
return m_panelsListChanged;
}

View File

@ -19,29 +19,28 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_KEYNAVIGATIONSECTION_H
#define MU_UI_KEYNAVIGATIONSECTION_H
#ifndef MU_UI_NAVIGATIONSECTION_H
#define MU_UI_NAVIGATIONSECTION_H
#include <QObject>
#include <QList>
#include "abstractkeynavigation.h"
#include "../ikeynavigation.h"
#include "abstractnavigation.h"
#include "navigationpanel.h"
#include "modularity/ioc.h"
#include "../ikeynavigationcontroller.h"
#include "../inavigationcontroller.h"
#include "async/asyncable.h"
namespace mu::ui {
class KeyNavigationSubSection;
class KeyNavigationSection : public AbstractKeyNavigation, public IKeyNavigationSection, public async::Asyncable
class NavigationSection : public AbstractNavigation, public INavigationSection, public async::Asyncable
{
Q_OBJECT
INJECT(ui, IKeyNavigationController, keyNavigationController)
INJECT(ui, INavigationController, navigationController)
public:
explicit KeyNavigationSection(QObject* parent = nullptr);
~KeyNavigationSection() override;
explicit NavigationSection(QObject* parent = nullptr);
~NavigationSection() override;
QString name() const override;
@ -57,22 +56,22 @@ public:
void onEvent(EventPtr e) override;
const std::set<IKeyNavigationSubSection*>& subsections() const override;
async::Notification subsectionsListChanged() const override;
const std::set<INavigationPanel*>& panels() const override;
async::Notification panelsListChanged() const override;
async::Channel<SectionSubSectionControl> forceActiveRequested() const override;
async::Channel<SectionPanelControl> forceActiveRequested() const override;
void componentComplete() override;
void addSubSection(KeyNavigationSubSection* s);
void removeSubSection(KeyNavigationSubSection* s);
void addPanel(NavigationPanel* panel);
void removePanel(NavigationPanel* panel);
private:
std::set<IKeyNavigationSubSection*> m_subsections;
async::Notification m_subsectionsListChanged;
async::Channel<SectionSubSectionControl> m_forceActiveRequested;
std::set<INavigationPanel*> m_panels;
async::Notification m_panelsListChanged;
async::Channel<SectionPanelControl> m_forceActiveRequested;
};
}
#endif // MU_UI_KEYNAVIGATIONSECTION_H
#endif // MU_UI_NAVIGATIONSECTION_H

View File

@ -72,7 +72,7 @@ FocusableControl {
}
}
keynav.onTriggered: {
navigation.onTriggered: {
if (root.isClickOnKeyNavTriggered) {
root.clicked()
}

View File

@ -31,7 +31,7 @@ FocusScope {
property alias mouseArea: mouseAreaItem
property alias pressAndHoldInterval: mouseAreaItem.pressAndHoldInterval
property alias keynav: keynavItem
property alias navigation: keynavItem
function insureActiveFocus() {
if (!root.activeFocus) {
@ -43,7 +43,7 @@ FocusScope {
}
}
KeyNavigationControl {
NavigationControl {
id: keynavItem
name: root.objectName
enabled: root.enabled

View File

@ -38,7 +38,7 @@ RadioDelegate {
property var normalStateFont: ui.theme.tabFont
property var selectedStateFont: ui.theme.tabBoldFont
property alias keynav: keynavCtrl
property alias navigation: keynavCtrl
height: 48
@ -52,7 +52,7 @@ RadioDelegate {
}
}
KeyNavigationControl {
NavigationControl {
id: keynavCtrl
name: root.objectName

View File

@ -43,13 +43,13 @@ StyledPopupView {
animationEnabled: false //! NOTE disabled - because trouble with simultaneous opening of submenu
keynav.name: "StyledMenu"
keynav.direction: KeyNavigationSubSection.Vertical
navigation.name: "StyledMenu"
navigation.direction: NavigationPanel.Vertical
function focusOnFirstItem() {
var loader = view.itemAtIndex(0)
if (loader && loader.item) {
loader.item.keynav.forceActive()
loader.item.navigation.forceActive()
}
}
@ -57,7 +57,7 @@ StyledPopupView {
for (var i = 0; i < view.count; ++i) {
var loader = view.itemAtIndex(i)
if (loader && loader.item && loader.item.isSelected) {
loader.item.keynav.forceActive()
loader.item.navigation.forceActive()
return true
}
}
@ -121,9 +121,9 @@ StyledPopupView {
StyledMenuItem {
id: item
keynav.subsection: root.keynav
keynav.column: 0
keynav.row: model.index
navigation.panel: root.navigation
navigation.column: 0
navigation.row: model.index
iconAndCheckMarkMode: {
if (prv.hasItemsWithIconAndCheckable) {

View File

@ -53,13 +53,13 @@ ListItemBlank {
ShowBoth
}
keynav.onActiveChanged: {
navigation.onActiveChanged: {
if (prv.hasSubMenu) {
if (keynav.active) {
if (navigation.active) {
prv.showSubMenu()
} else {
Qt.callLater(function() {
if (prv.showedSubMenu && !prv.showedSubMenu.keynav.active) {
if (prv.showedSubMenu && !prv.showedSubMenu.navigation.active) {
prv.closeSubMenu()
}
})
@ -67,7 +67,7 @@ ListItemBlank {
}
}
keynav.onKeyNavEvent: {
navigation.onKeyNavEvent: {
switch (event.type) {
case KeyNavigationEvent.Right:
//! NOTE Go to submenu if shown
@ -78,14 +78,14 @@ ListItemBlank {
break;
case KeyNavigationEvent.Left:
//! NOTE Go to parent item if present
if (keynav.subsection.parentControl) {
if (navigation.panel.parentControl) {
event.accepted = true
root.keynav.subsection.parentControl.forceActive()
root.navigation.panel.parentControl.forceActive()
}
}
}
keynav.onTriggered: root.clicked()
navigation.onTriggered: root.clicked()
QtObject {
id: prv
@ -113,8 +113,8 @@ ListItemBlank {
menu.x = root.width
menu.y = 0
menu.keynav.parentControl = root.keynav
menu.keynav.name = root.keynav.name+"SubMenu"
menu.navigation.parentControl = root.navigation
menu.navigation.name = root.navigation.name+"SubMenu"
menu.model = modelData.subitems
@ -200,8 +200,8 @@ ListItemBlank {
}
onHovered: {
if (isHovered && !root.keynav.active) {
root.keynav.forceActive()
if (isHovered && !root.navigation.active) {
root.navigation.forceActive()
}
if (!prv.hasSubMenu) {

View File

@ -46,8 +46,8 @@ Loader {
menu.parent = loader.parent
if (keynavParentControl) {
menu.keynav.parentControl = keynavParentControl
menu.keynav.name = keynavParentControl.name+"PopupMenu"
menu.navigation.parentControl = keynavParentControl
menu.navigation.name = keynavParentControl.name+"PopupMenu"
}
menu.model = model
menu.open()

View File

@ -47,7 +47,7 @@ PopupView {
property bool animationEnabled: true
property alias keynav: keynavPanel
property alias navigation: keynavPanel
property bool isDoActiveParentOnClose: true
closePolicy: PopupView.CloseOnPressOutsideParent
@ -55,14 +55,14 @@ PopupView {
x: parent.width / 2
y: opensUpward ? (-height) : (parent.height - root.padding)
property KeyNavigationPopupPanel keynavPanel: KeyNavigationPopupPanel {
property NavigationPopupPanel keynavPanel: NavigationPopupPanel {
id: keynavPanel
enabled: root.isOpened
order: {
var pctrl = keynavPanel.parentControl;
if (pctrl) {
if (pctrl.subsection) {
return pctrl.subsection.order + 1
if (pctrl.panel) {
return pctrl.panel.order + 1
}
}
return -1
@ -71,8 +71,8 @@ PopupView {
section: {
var pctrl = keynavPanel.parentControl;
if (pctrl) {
if (pctrl.subsection) {
return pctrl.subsection.section
if (pctrl.panel) {
return pctrl.panel.section
}
}
return null

View File

@ -36,7 +36,7 @@ Item {
id: root
property KeyNavigationSection keynavSection: null
property NavigationSection keynavSection: null
Rectangle {
id: background
@ -54,11 +54,11 @@ Item {
}
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavTreeSub
name: "InstrumentsTree"
section: root.keynavSection
direction: KeyNavigationSubSection.Both
direction: NavigationPanel.Both
enabled: root.visible
order: 3
}
@ -79,9 +79,9 @@ Item {
Layout.leftMargin: contentColumn.sideMargin
Layout.rightMargin: contentColumn.sideMargin
keynav.section: root.keynavSection
keynav.enabled: root.visible
keynav.order: 2
navigation.section: root.keynavSection
navigation.enabled: root.visible
navigation.order: 2
isMovingUpAvailable: instrumentTreeModel.isMovingUpAvailable
isMovingDownAvailable: instrumentTreeModel.isMovingDownAvailable

View File

@ -88,7 +88,7 @@ StyledPopupView {
FlatButton {
width: parent.width
keynav.subsection: root.keynav
navigation.panel: root.navigation
text: qsTrc("instruments", "Replace instrument")
onClicked: {

View File

@ -33,7 +33,7 @@ RowLayout {
property bool isRemovingAvailable: false
property bool isAddingAvailable: value
property alias keynav: keynavSub
property alias navigation: keynavSub
signal addRequested()
signal moveUpRequested()
@ -50,7 +50,7 @@ RowLayout {
}
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "InstrumentsHeader"
}
@ -58,8 +58,8 @@ RowLayout {
FlatButton {
Layout.fillWidth: true
keynav.subsection: keynavSub
keynav.order: 1
navigation.panel: keynavSub
navigation.order: 1
text: qsTrc("instruments", "Add")
@ -73,8 +73,8 @@ RowLayout {
FlatButton {
Layout.preferredWidth: width
keynav.subsection: keynavSub
keynav.order: 2
navigation.panel: keynavSub
navigation.order: 2
enabled: root.isMovingUpAvailable
@ -88,8 +88,8 @@ RowLayout {
FlatButton {
Layout.preferredWidth: width
keynav.subsection: keynavSub
keynav.order: 3
navigation.panel: keynavSub
navigation.order: 3
enabled: root.isMovingDownAvailable
@ -103,8 +103,8 @@ RowLayout {
FlatButton {
Layout.preferredWidth: width
keynav.subsection: keynavSub
keynav.order: 4
navigation.panel: keynavSub
navigation.order: 4
enabled: root.isRemovingAvailable

View File

@ -31,7 +31,7 @@ Item {
property bool isHighlighted: false
property int keynavRow: 0
property KeyNavigationSubSection keynavSubSection: null
property NavigationPanel keynavSubSection: null
Rectangle {
anchors.fill: parent
@ -45,10 +45,10 @@ Item {
signal clicked()
KeyNavigationControl {
NavigationControl {
id: keynavItem
name: "InstrumentsTreeItemControl"
subsection: root.keynavSubSection
panel: root.keynavSubSection
row: root.keynavRow
column: 0
enabled: visible
@ -85,9 +85,9 @@ Item {
height: width
objectName: "InstrumentsAddStaffBtn"
keynav.subsection: root.keynavSubSection
keynav.row: root.keynavRow
keynav.column: 1
navigation.panel: root.keynavSubSection
navigation.row: root.keynavRow
navigation.column: 1
icon: IconCode.PLUS
}

View File

@ -38,7 +38,7 @@ Item {
property var type: InstrumentTreeItemType.UNDEFINED
property int keynavRow: 0
property KeyNavigationSubSection keynavSubSection: null
property NavigationPanel keynavSubSection: null
property int sideMargin: 0
@ -98,10 +98,10 @@ Item {
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
KeyNavigationControl {
NavigationControl {
id: keynavItem
name: "ItemInstrumentsTree"
subsection: root.keynavSubSection
panel: root.keynavSubSection
row: root.keynavRow
column: 0
enabled: visible
@ -227,8 +227,8 @@ Item {
Component {
id: instrumentSettingsComp
InstrumentSettingsPopup {
keynav.name: "InstrumentSettingsPopup"
keynav.parentControl: keynavItem
navigation.name: "InstrumentSettingsPopup"
navigation.parentControl: keynavItem
onClosed: {
prv.resetOpenedPopup()
popupLoader.sourceComponent = null
@ -239,8 +239,8 @@ Item {
Component {
id: staffSettingsComp
StaffSettingsPopup {
keynav.name: "StaffSettingsPopup"
keynav.parentControl: keynavItem
navigation.name: "StaffSettingsPopup"
navigation.parentControl: keynavItem
onClosed: {
prv.resetOpenedPopup()
popupLoader.sourceComponent = null
@ -260,9 +260,9 @@ Item {
Layout.preferredWidth: width
objectName: "VisibleBtnInstrument"
keynav.subsection: root.keynavSubSection
keynav.row: root.keynavRow
keynav.column: 1
navigation.panel: root.keynavSubSection
navigation.row: root.keynavRow
navigation.column: 1
normalStateColor: "transparent"
pressedStateColor: ui.theme.accentColor
@ -291,9 +291,9 @@ Item {
objectName: "ExpandBtnInstrument"
enabled: expandButton.visible
keynav.subsection: root.keynavSubSection
keynav.row: root.keynavRow
keynav.column: 2
navigation.panel: root.keynavSubSection
navigation.row: root.keynavRow
navigation.column: 2
normalStateColor: "transparent"
pressedStateColor: ui.theme.accentColor
@ -342,9 +342,9 @@ Item {
objectName: "SettingsBtnInstrument"
enabled: root.visible
keynav.subsection: root.keynavSubSection
keynav.row: root.keynavRow
keynav.column: 3
navigation.panel: root.keynavSubSection
navigation.row: root.keynavRow
navigation.column: 3
pressedStateColor: ui.theme.accentColor

View File

@ -138,7 +138,7 @@ StyledPopupView {
FlatButton {
width: parent.width
keynav.subsection: root.keynav
navigation.panel: root.navigation
text: qsTrc("instruments", "Create a linked staff")

View File

@ -27,7 +27,7 @@ import MuseScore.UiComponents 1.0
Rectangle {
id: root
property alias keynav: keynavSub
property alias navigation: keynavSub
signal activeFocusRequested()
@ -35,7 +35,7 @@ Rectangle {
toolbarModel.load()
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "NotationToolBar"
onActiveChanged: {
@ -73,10 +73,10 @@ Rectangle {
enabled: model.enabled
textFont: ui.theme.tabFont
keynav.subsection: keynavSub
keynav.name: model.title
keynav.order: model.index
keynav.enabled: model.enabled
navigation.panel: keynavSub
navigation.name: model.title
navigation.order: model.index
navigation.enabled: model.enabled
normalStateColor: "transparent"
orientation: Qt.Horizontal

View File

@ -31,7 +31,7 @@ Rectangle {
property alias orientation: gridView.orientation
property alias keynav: keynavSub
property alias navigation: keynavSub
QtObject {
id: privatesProperties
@ -39,7 +39,7 @@ Rectangle {
property bool isHorizontal: orientation === Qt.Horizontal
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "NoteInputBar"
}
@ -83,11 +83,11 @@ Rectangle {
iconFont: ui.theme.toolbarIconsFont
keynav.subsection: keynavSub
keynav.name: hint
keynav.order: Boolean(item) ? item.orderRole : 0
navigation.panel: keynavSub
navigation.name: hint
navigation.order: Boolean(item) ? item.orderRole : 0
isClickOnKeyNavTriggered: false
keynav.onTriggered: {
navigation.onTriggered: {
if (hasSubitems && item.showSubitemsByPressAndHoldRole) {
btn.pressAndHold()
} else {
@ -102,7 +102,7 @@ Rectangle {
onClicked: {
if (menuLoader.isMenuOpened() || (hasSubitems && !item.showSubitemsByPressAndHoldRole)) {
menuLoader.toggleOpened(item.subitemsRole, btn.keynav)
menuLoader.toggleOpened(item.subitemsRole, btn.navigation)
return
}
@ -114,7 +114,7 @@ Rectangle {
return
}
menuLoader.toggleOpened(item.subitemsRole, btn.keynav)
menuLoader.toggleOpened(item.subitemsRole, btn.navigation)
}
Canvas {
@ -157,8 +157,8 @@ Rectangle {
icon: IconCode.CONFIGURE
iconFont: ui.theme.toolbarIconsFont
normalStateColor: "transparent"
keynav.subsection: keynavSub
keynav.order: 100
navigation.panel: keynavSub
navigation.order: 100
onClicked: {
api.launcher.open("musescore://notation/noteinputbar/customise")

View File

@ -33,7 +33,7 @@ Rectangle {
id: palettesWidget
property KeyNavigationSection keynavSection: null
property NavigationSection keynavSection: null
readonly property PaletteWorkspace paletteWorkspace: paletteRootModel.paletteWorkspace
@ -71,8 +71,8 @@ Rectangle {
rightMargin: 12
}
keynav.section: palettesWidget.keynavSection
keynav.order: 2
navigation.section: palettesWidget.keynavSection
navigation.order: 2
onAddCustomPaletteRequested: paletteTree.insertCustomPalette(0, paletteName);
}
@ -95,9 +95,9 @@ Rectangle {
paletteWorkspace: palettesWidget.paletteWorkspace
backgroundColor: palettesWidget.color
keynav.section: palettesWidget.keynavSection
keynav.order: 5
keynav.enabled: paletteTree.visible
navigation.section: palettesWidget.keynavSection
navigation.order: 5
navigation.enabled: paletteTree.visible
filter: palettesWidgetHeader.searchText
enableAnimations: !palettesWidgetHeader.searching

View File

@ -53,7 +53,7 @@ GridView {
property bool enableAnimations: true
property KeyNavigationSubSection keynavSubSection: null
property NavigationPanel keynavSubSection: null
property int keynavRow: 0
property int keynavCol: 1
@ -173,11 +173,11 @@ GridView {
anchors.fill: parent
keynav.subsection: paletteView.keynavSubSection
navigation.panel: paletteView.keynavSubSection
//! NOTE Just Up/Down navigation now
keynav.row: paletteView.ncells + paletteView.keynavRow
keynav.column: 1
keynav.enabled: paletteView.visible
navigation.row: paletteView.ncells + paletteView.keynavRow
navigation.column: 1
navigation.enabled: paletteView.visible
onActiveFocusChanged: {
if (activeFocus) {
@ -504,17 +504,17 @@ GridView {
width: paletteView.cellWidth
height: paletteView.cellHeight
keynav.subsection: paletteView.keynavSubSection
navigation.panel: paletteView.keynavSubSection
//! NOTE Please, don't remove (igor.korsukov@gmail.com)
//keynav.row: paletteCell.cellRow + paletteView.keynavRow
//keynav.column: paletteCell.cellCol + paletteView.keynavCol
//navigation.row: paletteCell.cellRow + paletteView.keynavRow
//navigation.column: paletteCell.cellCol + paletteView.keynavCol
//! NOTE Just Up/Down navigation now
keynav.row: model.index + paletteView.keynavRow
keynav.column: 1
keynav.enabled: paletteView.visible
keynav.onTriggered: paletteCell.doClicked()
navigation.row: model.index + paletteView.keynavRow
navigation.column: 1
navigation.enabled: paletteView.visible
navigation.onTriggered: paletteCell.doClicked()
IconView {
anchors.fill: parent

View File

@ -37,7 +37,7 @@ ListView {
property var paletteModel: Boolean(paletteWorkspace) ? paletteWorkspace.mainPaletteModel : null
property PaletteController paletteController: paletteWorkspace ? paletteWorkspace.mainPaletteController : null
property alias keynav: keynavTree
property alias navigation: keynavTree
// Scroll palettes list when dragging a palette close to the list's border
property bool itemDragged: false
@ -59,10 +59,10 @@ ListView {
Accessible.name: qsTrc("palette", "Palettes Tree, contains %n palette(s)", "", count)
KeyNavigationSubSection {
NavigationPanel {
id: keynavTree
name: "PalettesTree"
direction: KeyNavigationSubSection.Both
direction: NavigationPanel.Both
onActiveChanged: {
if (active) {
paletteTree.forceActiveFocus()
@ -305,13 +305,13 @@ ListView {
visible: !control.Drag.active
isSelected: control.selected
keynav.name: "PaletteTreeItem"
keynav.subsection: keynavTree
keynav.row: control.keynavRow
keynav.column: 0
navigation.name: "PaletteTreeItem"
navigation.panel: keynavTree
navigation.row: control.keynavRow
navigation.column: 0
enabled: control.visible
keynav.onActiveChanged: {
if (keynav.active && !control.selected) {
navigation.onActiveChanged: {
if (navigation.active && !control.selected) {
control.doItemClicked()
}
paletteTree.positionViewAtIndex(control.rowIndex, ListView.Contain);

View File

@ -39,7 +39,7 @@ Item {
property alias popupMaxHeight: palettePopup.maxHeight
property alias keynav: keynavSub
property alias navigation: keynavSub
signal addCustomPaletteRequested(var paletteName)
@ -60,7 +60,7 @@ Item {
}
}
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "PalettesHeader"
onActiveChanged: {
@ -76,8 +76,8 @@ Item {
anchors.right: searchTextButton.left
anchors.rightMargin: 8
objectName: "AddPalettesBtn"
keynav.subsection: keynavSub
keynav.order: 1
navigation.panel: keynavSub
navigation.order: 1
enabled: !searchTextInput.visible
text: qsTrc("palette", "Add Palettes")
onClicked: {
@ -89,8 +89,8 @@ Item {
id: searchTextButton
anchors.right: parent.right
objectName: "SearchPalettesBtn"
keynav.subsection: keynavSub
keynav.order: 2
navigation.panel: keynavSub
navigation.order: 2
enabled: !searchTextInput.visible
icon: IconCode.SEARCH
onClicked: {
@ -103,10 +103,10 @@ Item {
width: parent.width
//! TODO Move to SearchField inside
KeyNavigationControl {
NavigationControl {
id: keynavSearchField
name: "SearchPalettesField"
subsection: keynavSub
panel: keynavSub
order: 3
enabled: searchTextInput.visible
onActiveChanged: {
@ -116,10 +116,10 @@ Item {
}
}
KeyNavigationControl {
NavigationControl {
id: keynavSearchFieldClose
name: "SearchPalettesFieldClose"
subsection: keynavSub
panel: keynavSub
order: 4
enabled: searchTextInput.visible && searchTextInput.clearTextButtonVisible
onTriggered: toggleSearch()
@ -127,7 +127,7 @@ Item {
onVisibleChanged: {
if (!searchTextInput.visible) {
morePalettesButton.keynav.forceActive()
morePalettesButton.navigation.forceActive()
}
}

View File

@ -40,7 +40,7 @@ Item {
property PaletteWorkspace paletteWorkspace
property var modelIndex: null
property KeyNavigationSubSection keynavSubsection: null
property NavigationPanel keynavSubsection: null
property int keynavRow: 0
signal toggleExpandRequested()
@ -73,9 +73,9 @@ Item {
normalStateColor: "transparent"
enabled: paletteExpandArrow.visible
keynav.subsection: paletteHeader.keynavSubsection
keynav.row: paletteHeader.keynavRow
keynav.column: 1
navigation.panel: paletteHeader.keynavSubsection
navigation.row: paletteHeader.keynavRow
navigation.column: 1
onClicked: paletteHeader.toggleExpandRequested()
}
@ -111,9 +111,9 @@ Item {
normalStateColor: "transparent"
enabled: deleteButton.visible
keynav.subsection: paletteHeader.keynavSubsection
keynav.row: paletteHeader.keynavRow
keynav.column: 2
navigation.panel: paletteHeader.keynavSubsection
navigation.row: paletteHeader.keynavRow
navigation.column: 2
onClicked: {
hideSelectedElementsRequested()
@ -129,9 +129,9 @@ Item {
visible: paletteHeader.expanded || paletteHeader.hovered || paletteHeaderMenu.visible
enabled: paletteHeaderMenuButton.visible
keynav.subsection: paletteHeader.keynavSubsection
keynav.row: paletteHeader.keynavRow
keynav.column: 3
navigation.panel: paletteHeader.keynavSubsection
navigation.row: paletteHeader.keynavRow
navigation.column: 3
icon: IconCode.MENU_THREE_DOTS
normalStateColor: "transparent"

View File

@ -33,10 +33,10 @@ import "internal"
Rectangle {
id: root
property alias keynav: keynavSub
property alias navigation: keynavSub
property bool floating: false
KeyNavigationSubSection {
NavigationPanel {
id: keynavSub
name: "PlaybackToolBar"
}
@ -102,14 +102,14 @@ Rectangle {
? ui.theme.accentColor : "transparent"
accentButton: modelData.checked || menuLoader.isMenuOpened()
keynav.subsection: keynavSub
keynav.name: modelData.hint
keynav.order: modelData.index
keynav.enabled: playbackModel.isPlayAllowed
navigation.panel: keynavSub
navigation.name: modelData.hint
navigation.order: modelData.index
navigation.enabled: playbackModel.isPlayAllowed
onClicked: {
if (menuLoader.isMenuOpened() || hasSubitems) {
menuLoader.toggleOpened(modelData.subitems, btn.keynav)
menuLoader.toggleOpened(modelData.subitems, btn.navigation)
return
}