diff --git a/src/python/config_files.py b/src/python/config_files.py index aeeebbe7..b4972f4e 100644 --- a/src/python/config_files.py +++ b/src/python/config_files.py @@ -121,6 +121,10 @@ class UISettings(JSONConfigFile): "toggleDebugConsole": ["Alt+Shift+C"], "reloadConfig": ["Alt+Shift+R"], + "zoomIn": ["Ctrl+Plus", "Ctrl+Shift+Plus"], + "zoomOut": ["Ctrl+Minus", "Ctrl+Shift+Minus"], + "zoomReset": ["Ctrl+Equal", "Ctrl+Backspace"], + "scrollUp": ["Alt+Up", "Alt+K"], "scrollDown": ["Alt+Down", "Alt+J"], "scrollPageUp": ["Alt+Ctrl+Up", "Alt+Ctrl+K", "PageUp"], diff --git a/src/qml/Base/HCircleProgressBar.qml b/src/qml/Base/HCircleProgressBar.qml index 192c4632..67447d1b 100644 --- a/src/qml/Base/HCircleProgressBar.qml +++ b/src/qml/Base/HCircleProgressBar.qml @@ -3,7 +3,7 @@ import RadialBar 1.0 RadialBar { id: bar - implicitWidth: 96 + implicitWidth: 96 * (theme ? theme.uiScale : 1) implicitHeight: implicitWidth foregroundColor: theme.controls.circleProgressBar.background progressColor: theme.controls.circleProgressBar.foreground diff --git a/src/qml/Base/HIcon.qml b/src/qml/Base/HIcon.qml index 8717a526..87f36d4b 100644 --- a/src/qml/Base/HIcon.qml +++ b/src/qml/Base/HIcon.qml @@ -14,7 +14,13 @@ Image { property string svgName: "" - property int dimension: 20 + + property bool small: false + property int dimension: + theme ? + (small ? theme.icons.smallDimension : theme.icons.dimension) : + (small ? 16 : 22) + property color colorize: theme.icons.colorize property string iconPack: theme ? theme.icons.preferredPack : "thin" diff --git a/src/qml/Base/HImage.qml b/src/qml/Base/HImage.qml index 1594fd61..700ac301 100644 --- a/src/qml/Base/HImage.qml +++ b/src/qml/Base/HImage.qml @@ -80,7 +80,6 @@ Image { anchors.centerIn: parent visible: broken || image.status === Image.Error svgName: "broken-image" - dimension: Math.max(16, Math.min(parent.width, parent.height) * 0.2) colorize: theme.colors.negativeBackground } } diff --git a/src/qml/Base/HTile.qml b/src/qml/Base/HTile.qml index e4aa678c..ee1eb637 100644 --- a/src/qml/Base/HTile.qml +++ b/src/qml/Base/HTile.qml @@ -55,7 +55,8 @@ HButton { visible: Layout.maximumWidth > 0 Layout.maximumWidth: - text && tile.width >= 160 ? implicitWidth : 0 + text && tile.width >= 160 * theme.uiScale ? + implicitWidth : 0 Behavior on Layout.maximumWidth { HNumberAnimation {} } } diff --git a/src/qml/Base/HUserAvatar.qml b/src/qml/Base/HUserAvatar.qml index 42bddb68..1ced9fe1 100644 --- a/src/qml/Base/HUserAvatar.qml +++ b/src/qml/Base/HUserAvatar.qml @@ -21,7 +21,7 @@ HAvatar { z: 100 sourceComponent: HIcon { - dimension: 16 + small: true svgName: "user-power-" + (admin ? "100" : "50") colorize: admin ? theme.chat.roomSidePane.member.adminIcon : diff --git a/src/qml/Base/MediaPlayer/OSDButton.qml b/src/qml/Base/MediaPlayer/OSDButton.qml index 47100f3d..90bf8b96 100644 --- a/src/qml/Base/MediaPlayer/OSDButton.qml +++ b/src/qml/Base/MediaPlayer/OSDButton.qml @@ -4,5 +4,5 @@ import "../../Base" HButton { backgroundColor: "transparent" - iconItem.dimension: theme.mediaPlayer.controls.iconHeight + iconItem.dimension: theme.mediaPlayer.controls.iconSize } diff --git a/src/qml/Chat/Banners/Banner.qml b/src/qml/Chat/Banners/Banner.qml index 1145aab7..45bd8fac 100644 --- a/src/qml/Chat/Banners/Banner.qml +++ b/src/qml/Chat/Banners/Banner.qml @@ -42,7 +42,6 @@ Rectangle { HIcon { id: bannerIcon - dimension: bannerLabel.implicitHeight visible: Boolean(svgName) Layout.leftMargin: theme.spacing / 2 diff --git a/src/qml/Chat/Chat.qml b/src/qml/Chat/Chat.qml index 93a4e659..4aaa0b39 100644 --- a/src/qml/Chat/Chat.qml +++ b/src/qml/Chat/Chat.qml @@ -55,7 +55,7 @@ HPage { HLoader { source: ready ? "ChatSplitView.qml" : "../Base/HBusyIndicator.qml" - Layout.preferredWidth: ready ? -1 : 96 + Layout.preferredWidth: ready ? -1 : 96 * theme.uiScale Layout.preferredHeight: Layout.preferredWidth Layout.fillWidth: ready Layout.fillHeight: ready diff --git a/src/qml/Chat/RoomHeader.qml b/src/qml/Chat/RoomHeader.qml index 5a662acd..8c0fd203 100644 --- a/src/qml/Chat/RoomHeader.qml +++ b/src/qml/Chat/RoomHeader.qml @@ -93,7 +93,6 @@ Rectangle { HButton { backgroundColor: "transparent" icon.name: "room-view-" + modelData - iconItem.dimension: 22 height: parent.height spacing: theme.spacing / 1.5 topPadding: 0 diff --git a/src/qml/Chat/RoomSidePane/MembersView.qml b/src/qml/Chat/RoomSidePane/MembersView.qml index 9165a9db..ecb348c2 100644 --- a/src/qml/Chat/RoomSidePane/MembersView.qml +++ b/src/qml/Chat/RoomSidePane/MembersView.qml @@ -50,17 +50,19 @@ HColumnLayout { placeholderText: qsTr("Filter members") backgroundColor: theme.chat.roomSidePane.filterMembers.background bordered: false + opacity: width >= 16 ? 1 : 0 onTextChanged: filterLimiter.restart() Layout.fillWidth: true Layout.fillHeight: true + + Behavior on opacity { HOpacityAnimator {} } } HButton { enabled: false // TODO icon.name: "room-send-invite" - iconItem.dimension: parent.height - 10 topPadding: 0 bottomPadding: 0 toolTip.text: qsTr("Invite to this room") diff --git a/src/qml/Chat/Timeline/EventContent.qml b/src/qml/Chat/Timeline/EventContent.qml index 5e6cb86a..ac08e6c8 100644 --- a/src/qml/Chat/Timeline/EventContent.qml +++ b/src/qml/Chat/Timeline/EventContent.qml @@ -49,8 +49,12 @@ HRowLayout { opacity: collapseAvatar ? 0 : 1 visible: ! hideAvatar - Layout.minimumWidth: 58 - Layout.minimumHeight: collapseAvatar ? 1 : smallAvatar ? 28 : 58 + Layout.minimumWidth: theme.chat.message.avatarSize + Layout.minimumHeight: + collapseAvatar ? 1 : + smallAvatar ? theme.chat.message.collapsedAvatarSize : + Layout.minimumWidth + Layout.maximumWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight Layout.alignment: Qt.AlignTop @@ -61,7 +65,7 @@ HRowLayout { displayName: model.sender_name mxc: model.sender_avatar width: parent.width - height: collapseAvatar ? 1 : 58 + height: collapseAvatar ? 1 : theme.chat.message.avatarSize } } diff --git a/src/qml/Pages/AccountSettings/AccountSettings.qml b/src/qml/Pages/AccountSettings/AccountSettings.qml index 02ecc09a..5edd3911 100644 --- a/src/qml/Pages/AccountSettings/AccountSettings.qml +++ b/src/qml/Pages/AccountSettings/AccountSettings.qml @@ -7,7 +7,7 @@ import "../../utils.js" as Utils HPage { id: accountSettings - property int avatarPreferredSize: 256 + property int avatarPreferredSize: 256 * theme.uiScale property string userId: "" diff --git a/src/qml/Pages/AccountSettings/Profile.qml b/src/qml/Pages/AccountSettings/Profile.qml index 62c9556d..fd16c77e 100644 --- a/src/qml/Pages/AccountSettings/Profile.qml +++ b/src/qml/Pages/AccountSettings/Profile.qml @@ -95,7 +95,7 @@ HGridLayout { svgName: "upload-avatar" colorize: (! avatar.mxc && overlayHover.hovered) ? theme.colors.accentText : theme.icons.colorize - dimension: 64 + dimension: avatar.width / 3 Layout.alignment: Qt.AlignCenter } diff --git a/src/qml/Pages/SignIn.qml b/src/qml/Pages/SignIn.qml index 52920994..343500b1 100644 --- a/src/qml/Pages/SignIn.qml +++ b/src/qml/Pages/SignIn.qml @@ -101,7 +101,6 @@ HPage { HButton { icon.name: modelData - iconItem.dimension: 24 circle: true checked: loginWith == modelData enabled: modelData == "username" diff --git a/src/qml/Shortcuts.qml b/src/qml/Shortcuts.qml index 066ce12c..704e3b26 100644 --- a/src/qml/Shortcuts.qml +++ b/src/qml/Shortcuts.qml @@ -33,6 +33,21 @@ HShortcutHandler { onPressed: py.loadSettings(() => { mainUI.pressAnimation.start() }) } + HShortcut { + sequences: settings.keys.zoomIn + onPressed: theme.uiScale += 0.1 + } + + HShortcut { + sequences: settings.keys.zoomOut + onPressed: theme.uiScale = Math.max(0.1, theme.uiScale - 0.1) + } + + HShortcut { + sequences: settings.keys.zoomReset + onPressed: theme.uiScale = 1 + } + // Pages HShortcut { diff --git a/src/qml/SidePane/AccountDelegate.qml b/src/qml/SidePane/AccountDelegate.qml index 8c1e4e6b..485e4bfc 100644 --- a/src/qml/SidePane/AccountDelegate.qml +++ b/src/qml/SidePane/AccountDelegate.qml @@ -58,7 +58,7 @@ HTileDelegate { HButton { id: addChat - iconItem.dimension: 16 + iconItem.small: true icon.name: "add-chat" backgroundColor: "transparent" toolTip.text: qsTr("Add new chat") @@ -80,7 +80,7 @@ HTileDelegate { HButton { id: expand loading: ! model.data.first_sync_done || ! model.data.profile_updated - iconItem.dimension: addChat.iconItem.dimension + iconItem.small: true icon.name: "expand" backgroundColor: "transparent" toolTip.text: collapsed ? qsTr("Expand") : qsTr("Collapse") diff --git a/src/themes/Default.qpl b/src/themes/Default.qpl index ef6c2f58..a900ce3a 100644 --- a/src/themes/Default.qpl +++ b/src/themes/Default.qpl @@ -2,11 +2,7 @@ // Base variables -real uiScale: 1.0 /* TODO: Implement correctly, do not change for now */ -real fontScale: uiScale - -Behavior on uiScale { HNumberAnimation {} } -Behavior on fontScale { HNumberAnimation {} } +real uiScale: 1.0 int minimumSupportedWidth: 240 * uiScale int minimumSupportedHeight: 120 * uiScale @@ -17,19 +13,19 @@ int minimumSupportedHeightPlusSpacing: minimumSupportedHeight + spacing * 2 int baseElementsHeight: 36 * uiScale int spacing: 12 * uiScale -int radius: 5 +int radius: 5 * uiScale int animationDuration: 100 real loadingElementsOpacity: 0.8 real disabledElementsOpacity: 0.3 fontSize: - int smaller: 13 * fontScale - int small: 13 * fontScale - int normal: 16 * fontScale - int big: 22 * fontScale - int bigger: 32 * fontScale - int biggest: 48 * fontScale + int smaller: 13 * uiScale + int small: 13 * uiScale + int normal: 16 * uiScale + int big: 22 * uiScale + int bigger: 32 * uiScale + int biggest: 48 * uiScale fontFamily: string sans: "Roboto" @@ -94,6 +90,9 @@ icons: color colorize: hsluv(0, 0, colors.intensity * 90) color disabledColorize: "white" + int smallDimension: 16 * uiScale + int dimension: 22 * uiScale + // Generic UI controls @@ -318,6 +317,9 @@ chat: color background: "transparent" message: + int avatarSize: 58 * uiScale + int collapsedAvatarSize: 28 * uiScale + int radius: theme.radius color background: colors.strongBackground color ownBackground: hsluv( @@ -408,7 +410,7 @@ mediaPlayer: color background: hsluv(0, 0, 0, 0.5) controls: - int iconHeight: 20 + int iconSize: icons.dimension int volumeSliderWidth: 100 int speedSliderWidth: 100 color background: hsluv(