Setting QML style and Material theme, variant.
parent
724f8bf3d8
commit
970305eee2
|
@ -158,6 +158,7 @@ in stdenv.mkDerivation {
|
|||
nixpkgs.fmt
|
||||
qt5.qmake
|
||||
qt5.qtbase
|
||||
qt5.qtquickcontrols2.dev
|
||||
qt5.qttools.dev
|
||||
] ++ lib.lists.optional withTests [
|
||||
nixpkgs.gtest.dev
|
||||
|
|
|
@ -22,6 +22,7 @@ import argparse
|
|||
import asyncio
|
||||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
import os.path
|
||||
import signal
|
||||
import sys
|
||||
|
@ -40,6 +41,7 @@ from . import ui_base
|
|||
from . import project
|
||||
from . import node_db
|
||||
from . import qml
|
||||
from . import qt_helper
|
||||
from . import ui_rc
|
||||
|
||||
logger = None # type: logging.Logger
|
||||
|
@ -57,6 +59,9 @@ class QEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
|
|||
class App(ui_base.PropertyContainer, QtCore.QObject):
|
||||
needsRestart, needsRestartChanged = ui_base.Property('needsRestart', bool)
|
||||
displayMultisampling, displayMultisamplingChanged = ui_base.Property('displayMultisampling', bool)
|
||||
displayStyle, displayStyleChanged = ui_base.Property('displayStyle', str)
|
||||
displayMaterialTheme, displayMaterialThemeChanged = ui_base.Property('displayMaterialTheme', str)
|
||||
displayMaterialVariant, displayMaterialVariantChanged = ui_base.Property('displayMaterialVariant', str)
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
@ -137,6 +142,12 @@ class App(ui_base.PropertyContainer, QtCore.QObject):
|
|||
with self.settingsGroup('display') as settings:
|
||||
self.displayMultisampling = (settings.value('multisampling', 'true') == 'true')
|
||||
self.displayMultisamplingChanged.connect(self.__displayMultisamplingChanged)
|
||||
self.displayStyle = settings.value('style', 'Material')
|
||||
self.displayStyleChanged.connect(self.__displayStyleChanged)
|
||||
self.displayMaterialTheme = settings.value('materialTheme', 'System')
|
||||
self.displayMaterialThemeChanged.connect(self.__displayMaterialThemeChanged)
|
||||
self.displayMaterialVariant = settings.value('materialVariant', 'Normal')
|
||||
self.displayMaterialVariantChanged.connect(self.__displayMaterialVariantChanged)
|
||||
|
||||
if self.displayMultisampling:
|
||||
logger.info("Enable multisampling.")
|
||||
|
@ -144,6 +155,9 @@ class App(ui_base.PropertyContainer, QtCore.QObject):
|
|||
format.setSamples(16)
|
||||
QtGui.QSurfaceFormat.setDefaultFormat(format)
|
||||
|
||||
os.environ["QT_QUICK_CONTROLS_STYLE"] = self.displayStyle
|
||||
os.environ["QT_QUICK_CONTROLS_MATERIAL_VARIANT"] = self.displayMaterialVariant
|
||||
|
||||
self.__qmlEngine = QtQml.QQmlEngine(self.__qtApp)
|
||||
self.__qmlEngine.warnings.connect(self.__qmlEngineWarnings)
|
||||
self.__qmlEngine.setOutputWarningsToStandardError(False)
|
||||
|
@ -258,6 +272,17 @@ class App(ui_base.PropertyContainer, QtCore.QObject):
|
|||
self.__settings.setValue('display/multisampling', 'true' if v else 'false')
|
||||
self.needsRestart = True
|
||||
|
||||
def __displayStyleChanged(self, v):
|
||||
self.__settings.setValue('display/style', v)
|
||||
self.needsRestart = True
|
||||
|
||||
def __displayMaterialThemeChanged(self, v):
|
||||
self.__settings.setValue('display/materialTheme', v)
|
||||
|
||||
def __displayMaterialVariantChanged(self, v):
|
||||
self.__settings.setValue('display/materialVariant', v)
|
||||
self.needsRestart = True
|
||||
|
||||
def quit(self, exit_code: int = 0) -> None:
|
||||
self.__exit_code = exit_code
|
||||
self.__quit.set()
|
||||
|
|
|
@ -26,12 +26,11 @@ import QtQuick.Controls 2.15
|
|||
import "." as Noisicaa
|
||||
import "matrix.js" as Transform
|
||||
|
||||
Rectangle {
|
||||
Control {
|
||||
id: root
|
||||
|
||||
property QtObject d
|
||||
|
||||
color: "#ffffff"
|
||||
property color bgColor: ApplicationWindow.window.color
|
||||
|
||||
Menu {
|
||||
id: contextMenu
|
||||
|
@ -160,7 +159,7 @@ Rectangle {
|
|||
property real step: 20 * d.zoom
|
||||
property real offsetx: d.offset.x % step
|
||||
property real offsety: d.offset.y % step
|
||||
|
||||
property color color: Qt.tint(root.bgColor, "#20808080")
|
||||
visible: step > 5
|
||||
|
||||
Repeater {
|
||||
|
@ -171,7 +170,7 @@ Rectangle {
|
|||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 1
|
||||
strokeColor: "#f8f8f8"
|
||||
strokeColor: grid.color
|
||||
startX: 0
|
||||
startY: 0
|
||||
PathLine {
|
||||
|
@ -190,7 +189,7 @@ Rectangle {
|
|||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 1
|
||||
strokeColor: "#f8f8f8"
|
||||
strokeColor: grid.color
|
||||
startX: 0
|
||||
startY: 0
|
||||
PathLine {
|
||||
|
@ -375,8 +374,9 @@ Rectangle {
|
|||
}
|
||||
|
||||
Rectangle {
|
||||
color: "#ffffff"
|
||||
border { width: 1; color: "#000000" }
|
||||
color: root.bgColor
|
||||
border.width: 1
|
||||
border.color: Qt.tint(root.bgColor, "#a0808080")
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
|
@ -391,6 +391,7 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
clip: true
|
||||
color: parent.color
|
||||
|
||||
property var complete: false
|
||||
property rect contentRect: d.contentRect
|
||||
|
@ -403,8 +404,10 @@ Rectangle {
|
|||
var t = new Transform.Matrix();
|
||||
|
||||
if (d.nodes.rowCount() == 0) {
|
||||
minimapView.visible = false;
|
||||
return;
|
||||
}
|
||||
minimapView.visible = true;
|
||||
|
||||
var sx = width / contentRect.width;
|
||||
var sy = height / contentRect.height;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Controls.Material 2.12
|
||||
|
||||
ApplicationWindow {
|
||||
id: root
|
||||
|
@ -9,8 +10,7 @@ ApplicationWindow {
|
|||
width: 1000
|
||||
height: 800
|
||||
|
||||
Component.onCompleted: {
|
||||
}
|
||||
Material.theme: d.app.displayMaterialTheme
|
||||
|
||||
onClosing: function (event) {
|
||||
d.closeProject()
|
||||
|
|
|
@ -25,6 +25,7 @@ from PySide2.QtCore import Qt
|
|||
from PySide2 import QtCore
|
||||
|
||||
from noisicaa.ui import ui_base
|
||||
from noisicaa.ui import qt_helper
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -33,12 +34,18 @@ class SettingsDialog(ui_base.CommonMixin, ui_base.PropertyContainer, QtCore.QObj
|
|||
modified, modifiedChanged = ui_base.Property('modified', bool)
|
||||
audioBackendIndex, audioBackendIndexChanged = ui_base.Property('audioBackendIndex', int)
|
||||
displayMultisampling, displayMultisamplingChanged = ui_base.Property('displayMultisampling', bool)
|
||||
displayStyleIndex, displayStyleIndexChanged = ui_base.Property('displayStyleIndex', int)
|
||||
displayMaterialThemeIndex, displayMaterialThemeIndexChanged = ui_base.Property('displayMaterialThemeIndex', int)
|
||||
displayMaterialVariantIndex, displayMaterialVariantIndexChanged = ui_base.Property('displayMaterialVariantIndex', int)
|
||||
|
||||
def __init__(self, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.audioBackendIndexChanged.connect(self.__setModified)
|
||||
self.displayMultisamplingChanged.connect(self.__setModified)
|
||||
self.displayStyleIndexChanged.connect(self.__setModified)
|
||||
self.displayMaterialThemeIndexChanged.connect(self.__setModified)
|
||||
self.displayMaterialVariantIndexChanged.connect(self.__setModified)
|
||||
|
||||
def __setModified(self, *args):
|
||||
self.modified = True
|
||||
|
@ -47,13 +54,39 @@ class SettingsDialog(ui_base.CommonMixin, ui_base.PropertyContainer, QtCore.QObj
|
|||
def audioBackendList(self):
|
||||
return ['jack', 'dummy']
|
||||
|
||||
@ui_base.ConstProperty(list)
|
||||
def displayStyleList(self):
|
||||
return qt_helper.availableQuickStyles()
|
||||
|
||||
@ui_base.ConstProperty(list)
|
||||
def displayMaterialThemeList(self):
|
||||
return ['Light', 'Dark', 'System']
|
||||
|
||||
@ui_base.ConstProperty(list)
|
||||
def displayMaterialVariantList(self):
|
||||
return ['Normal', 'Dense']
|
||||
|
||||
@QtCore.Slot()
|
||||
def reset(self):
|
||||
with self.app.settingsGroup('audio') as settings:
|
||||
self.audioBackendIndex = self.audioBackendList.index(settings.value('backend', 'jack'))
|
||||
try:
|
||||
self.audioBackendIndex = self.audioBackendList.index(settings.value('backend', 'jack'))
|
||||
except ValueError:
|
||||
self.audioBackendIndex = 0
|
||||
|
||||
self.displayMultisampling = self.app.displayMultisampling
|
||||
|
||||
try:
|
||||
self.displayStyleIndex = self.displayStyleList.index(self.app.displayStyle)
|
||||
except ValueError:
|
||||
self.displayStyleIndex = 0
|
||||
try:
|
||||
self.displayMaterialThemeIndex = self.displayMaterialThemeList.index(self.app.displayMaterialTheme)
|
||||
except ValueError:
|
||||
self.displayMaterialThemeIndex = 0
|
||||
try:
|
||||
self.displayMaterialVariantIndex = self.displayMaterialVariantList.index(self.app.displayMaterialVariant)
|
||||
except ValueError:
|
||||
self.displayMaterialVariantIndex = 0
|
||||
self.modified = False
|
||||
|
||||
@QtCore.Slot()
|
||||
|
@ -63,5 +96,8 @@ class SettingsDialog(ui_base.CommonMixin, ui_base.PropertyContainer, QtCore.QObj
|
|||
self.app.updateAudioBackend()
|
||||
|
||||
self.app.displayMultisampling = self.displayMultisampling
|
||||
self.app.displayStyle = self.displayStyleList[self.displayStyleIndex]
|
||||
self.app.displayMaterialTheme = self.displayMaterialThemeList[self.displayMaterialThemeIndex]
|
||||
self.app.displayMaterialVariant = self.displayMaterialVariantList[self.displayMaterialVariantIndex]
|
||||
|
||||
self.modified = False
|
||||
|
|
|
@ -94,6 +94,37 @@ Dialog {
|
|||
checked: d.displayMultisampling
|
||||
onToggled: d.displayMultisampling = checked;
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Style"
|
||||
}
|
||||
ComboBox {
|
||||
model: d.displayStyleList
|
||||
currentIndex: d.displayStyleIndex
|
||||
onActivated: d.displayStyleIndex = currentIndex;
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: d.displayStyleList[d.displayStyleIndex] == "Material"
|
||||
text: "Theme"
|
||||
}
|
||||
ComboBox {
|
||||
visible: d.displayStyleList[d.displayStyleIndex] == "Material"
|
||||
model: d.displayMaterialThemeList
|
||||
currentIndex: d.displayMaterialThemeIndex
|
||||
onActivated: d.displayMaterialThemeIndex = currentIndex;
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: d.displayStyleList[d.displayStyleIndex] == "Material"
|
||||
text: "Variant"
|
||||
}
|
||||
ComboBox {
|
||||
visible: d.displayStyleList[d.displayStyleIndex] == "Material"
|
||||
model: d.displayMaterialVariantList
|
||||
currentIndex: d.displayMaterialVariantIndex
|
||||
onActivated: d.displayMaterialVariantIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2021, Ben Niemann <pink@odahoda.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <QStringList>
|
||||
#include <QQuickStyle>
|
||||
|
||||
namespace noisicaa::ui {
|
||||
|
||||
// QtQuickControls2.QQuickStyle is not available in PySide2
|
||||
std::vector<std::string> c_availableQuickStyles() {
|
||||
std::vector<std::string> result;
|
||||
QStringList styles = QQuickStyle::availableStyles();
|
||||
for (auto i = styles.constBegin(); i < styles.constEnd(); ++i) {
|
||||
result.emplace_back(i->toLocal8Bit().constData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2021, Ben Niemann <pink@odahoda.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace noisicaa::ui {
|
||||
|
||||
std::vector<std::string> c_availableQuickStyles();
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
|
||||
cdef extern from "noisicaa/ui/qt_helper.h" namespace "noisicaa::ui" nogil:
|
||||
vector[string] c_availableQuickStyles()
|
||||
|
||||
|
||||
def availableQuickStyles():
|
||||
cdef vector[string] styles = c_availableQuickStyles()
|
||||
return [s.decode('utf-8') for s in styles]
|
|
@ -22,7 +22,18 @@ from waflib.Tools import qt5
|
|||
|
||||
|
||||
def build(ctx):
|
||||
ctx.shlib(
|
||||
features='qt5 cxx cxxshlib',
|
||||
uselib='QT5CORE QT5GUI QT5QUICK QT5QUICKCONTROLS2',
|
||||
source=['qt_helper.cpp'],
|
||||
# moc = [
|
||||
# 'beziercurve.h',
|
||||
# ],
|
||||
target = 'noisicaa-ui-qt_helper',
|
||||
)
|
||||
|
||||
ctx.py_module('__init__.py')
|
||||
ctx.cy_module('qt_helper.pyx', use=['noisicaa-ui-qt_helper'])
|
||||
ctx.py_module('main.py')
|
||||
ctx.py_module('ui_base.py')
|
||||
ctx.py_module('project.py')
|
||||
|
|
2
wscript
2
wscript
|
@ -82,7 +82,7 @@ def configure(ctx):
|
|||
raise ConfigurationError("--with-coverage requires --with-tests")
|
||||
|
||||
ctx.load('compiler_cxx')
|
||||
ctx.qt5_vars = ['Qt5Core', 'Qt5Gui', 'Qt5Widgets', 'Qt5Svg', 'Qt5Quick', 'Qt5Qml'];
|
||||
ctx.qt5_vars = ['Qt5Core', 'Qt5Gui', 'Qt5Widgets', 'Qt5Svg', 'Qt5Quick', 'Qt5QuickControls2', 'Qt5Qml'];
|
||||
ctx.load('qt5')
|
||||
ctx.load('python')
|
||||
ctx.load('build_utils.waf.local_rpath', tooldir='.')
|
||||
|
|
Loading…
Reference in New Issue