Add info bar to image viewer
This commit is contained in:
		
							
								
								
									
										5
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								TODO.md
									
									
									
									
									
								
							| @@ -1,9 +1,12 @@ | |||||||
| # TODO | # TODO | ||||||
|  |  | ||||||
| - Image viewer:  | - Image viewer:  | ||||||
|     - open externally in context menu in timeline thumbnail, also button |     - auto-hide buttons & header when needed | ||||||
|     - hflickable: support kinetic scrolling disabler  |     - hflickable: support kinetic scrolling disabler  | ||||||
|  |  | ||||||
|  | - compress png in a thread | ||||||
|  | - ctrl+o: ignore mx-reply links | ||||||
|  | - verify upload cancellation | ||||||
| - clipboard preview doesn't update when copied image changes until second time | - clipboard preview doesn't update when copied image changes until second time | ||||||
| - Avatar tooltip can get displayed in front of presence menu | - Avatar tooltip can get displayed in front of presence menu | ||||||
| - Use loading cursorShape | - Use loading cursorShape | ||||||
|   | |||||||
| @@ -7,6 +7,8 @@ HGridLayout { | |||||||
|     readonly property real summedImplicitWidth: |     readonly property real summedImplicitWidth: | ||||||
|         utils.sumChildrenImplicitWidths(visibleChildren, columnSpacing) |         utils.sumChildrenImplicitWidths(visibleChildren, columnSpacing) | ||||||
|  |  | ||||||
|  |     readonly property bool vertical: flow === HGridLayout.TopToBottom | ||||||
|  |  | ||||||
|  |  | ||||||
|     flow: |     flow: | ||||||
|         width >= summedImplicitWidth ? |         width >= summedImplicitWidth ? | ||||||
|   | |||||||
| @@ -406,7 +406,8 @@ Rectangle { | |||||||
|             // if forLink is empty, this must be a media event |             // if forLink is empty, this must be a media event | ||||||
|  |  | ||||||
|             const title = |             const title = | ||||||
|                 event.media_title || utils.urlFileName(event.media_url) |                 event.media_title || | ||||||
|  |                 utils.urlFileName(forLink || event.media_url) | ||||||
|  |  | ||||||
|             // The thumbnail/cached path will be the full GIF |             // The thumbnail/cached path will be the full GIF | ||||||
|             const fullMxc = |             const fullMxc = | ||||||
| @@ -423,6 +424,7 @@ Rectangle { | |||||||
|                     fullTitle: title, |                     fullTitle: title, | ||||||
|                     fullMxc: fullMxc, |                     fullMxc: fullMxc, | ||||||
|                     fullCryptDict: JSON.parse(event.media_crypt_dict), |                     fullCryptDict: JSON.parse(event.media_crypt_dict), | ||||||
|  |                     fullFileSize: event.media_size, | ||||||
|  |  | ||||||
|                     overallSize: Qt.size( |                     overallSize: Qt.size( | ||||||
|                         event.media_width || |                         event.media_width || | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ HPopup { | |||||||
|     property string fullTitle |     property string fullTitle | ||||||
|     property string fullMxc |     property string fullMxc | ||||||
|     property var fullCryptDict |     property var fullCryptDict | ||||||
|  |     property int fullFileSize | ||||||
|     property size overallSize |     property size overallSize | ||||||
|  |  | ||||||
|     property bool alternateScaling: false |     property bool alternateScaling: false | ||||||
| @@ -25,6 +26,7 @@ HPopup { | |||||||
|     property real imagesSpeed: 1 |     property real imagesSpeed: 1 | ||||||
|     property var availableSpeeds: [16, 8, 2, 1.75, 1.5, 1.25, 1, 0.75, 0.5] |     property var availableSpeeds: [16, 8, 2, 1.75, 1.5, 1.25, 1, 0.75, 0.5] | ||||||
|  |  | ||||||
|  |     readonly property alias info: info | ||||||
|     readonly property alias canvas: canvas |     readonly property alias canvas: canvas | ||||||
|     readonly property alias buttons: buttons |     readonly property alias buttons: buttons | ||||||
|  |  | ||||||
| @@ -96,6 +98,16 @@ HPopup { | |||||||
|             viewer: popup |             viewer: popup | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         ViewerInfo { | ||||||
|  |             id: info | ||||||
|  |             viewer: popup | ||||||
|  |             width: parent.width | ||||||
|  |             y: parent.width < buttons.width * 4 ?  0 : parent.height - height | ||||||
|  |             maxTitleWidth: y === 0 ? -1 : buttons.x - buttons.width / 2 | ||||||
|  |  | ||||||
|  |             Behavior on y { HNumberAnimation {} } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         ViewerButtons { |         ViewerButtons { | ||||||
|             id: buttons |             id: buttons | ||||||
|             anchors.bottom: parent.bottom |             anchors.bottom: parent.bottom | ||||||
|   | |||||||
| @@ -6,14 +6,22 @@ import ".." | |||||||
| import "../../Base" | import "../../Base" | ||||||
|  |  | ||||||
| HFlow { | HFlow { | ||||||
|  |     id: root | ||||||
|  |  | ||||||
|     property HPopup viewer |     property HPopup viewer | ||||||
|  |  | ||||||
|  |     property color backgroundsColor: | ||||||
|  |         viewer.info.y === viewer.height - viewer.info.height ? | ||||||
|  |         "transparent" : | ||||||
|  |         theme.controls.button.background | ||||||
|  |  | ||||||
|     readonly property real calculatedWidth: |     readonly property real calculatedWidth: | ||||||
|         utils.sumChildrenImplicitWidths(visibleChildren) |         utils.sumChildrenImplicitWidths(visibleChildren) | ||||||
|  |  | ||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: pause |         id: pause | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: viewer.imagesPaused ? "image-play" : "image-pause" |         icon.name: viewer.imagesPaused ? "image-play" : "image-pause" | ||||||
|         toolTip.text: viewer.imagesPaused ? qsTr("Play") : qsTr("Pause") |         toolTip.text: viewer.imagesPaused ? qsTr("Play") : qsTr("Pause") | ||||||
|         onClicked: viewer.imagesPaused = ! viewer.imagesPaused |         onClicked: viewer.imagesPaused = ! viewer.imagesPaused | ||||||
| @@ -26,6 +34,7 @@ HFlow { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         text: qsTr("%1x").arg(utils.round(viewer.imagesSpeed)) |         text: qsTr("%1x").arg(utils.round(viewer.imagesSpeed)) | ||||||
|         label.font.pixelSize: theme.fontSize.big |         label.font.pixelSize: theme.fontSize.big | ||||||
|         height: pause.height |         height: pause.height | ||||||
| @@ -58,6 +67,7 @@ HFlow { | |||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: rotateLeft |         id: rotateLeft | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: "image-rotate-left" |         icon.name: "image-rotate-left" | ||||||
|         toolTip.text: qsTr("Rotate left") |         toolTip.text: qsTr("Rotate left") | ||||||
|         autoRepeat: true |         autoRepeat: true | ||||||
| @@ -73,6 +83,7 @@ HFlow { | |||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: rotateRight |         id: rotateRight | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: "image-rotate-right" |         icon.name: "image-rotate-right" | ||||||
|         toolTip.text: qsTr("Rotate right") |         toolTip.text: qsTr("Rotate right") | ||||||
|         autoRepeat: true |         autoRepeat: true | ||||||
| @@ -93,6 +104,7 @@ HFlow { | |||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: expand |         id: expand | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: "image-alt-scale-mode" |         icon.name: "image-alt-scale-mode" | ||||||
|         toolTip.text: |         toolTip.text: | ||||||
|             viewer.imageLargerThanWindow ? |             viewer.imageLargerThanWindow ? | ||||||
| @@ -110,6 +122,7 @@ HFlow { | |||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: fullScreen |         id: fullScreen | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: "image-fullscreen" |         icon.name: "image-fullscreen" | ||||||
|         toolTip.text: qsTr("Fullscreen") |         toolTip.text: qsTr("Fullscreen") | ||||||
|         checked: window.visibility === Window.FullScreen |         checked: window.visibility === Window.FullScreen | ||||||
| @@ -124,6 +137,7 @@ HFlow { | |||||||
|  |  | ||||||
|     HButton { |     HButton { | ||||||
|         id: close  // always visible |         id: close  // always visible | ||||||
|  |         backgroundColor: root.backgroundsColor | ||||||
|         icon.name: "image-close" |         icon.name: "image-close" | ||||||
|         toolTip.text: qsTr("Close") |         toolTip.text: qsTr("Close") | ||||||
|         onClicked: viewer.close() |         onClicked: viewer.close() | ||||||
|   | |||||||
							
								
								
									
										86
									
								
								src/gui/Popups/ImageViewerPopup/ViewerInfo.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/gui/Popups/ImageViewerPopup/ViewerInfo.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | // SPDX-License-Identifier: LGPL-3.0-or-later | ||||||
|  |  | ||||||
|  | import QtQuick 2.12 | ||||||
|  | import QtQuick.Layouts 1.12 | ||||||
|  | import CppUtils 0.1 | ||||||
|  | import "../../Base" | ||||||
|  |  | ||||||
|  | Rectangle { | ||||||
|  |     property HPopup viewer | ||||||
|  |     property int maxTitleWidth: -1 | ||||||
|  |  | ||||||
|  |     readonly property alias layout: layout | ||||||
|  |     readonly property alias title: title | ||||||
|  |     readonly property alias dimensions: dimensions | ||||||
|  |     readonly property alias fileSize: fileSize | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     implicitHeight: Math.max(theme.baseElementsHeight, childrenRect.height) | ||||||
|  |     color: utils.hsluv(0, 0, 0, 0.6) | ||||||
|  |  | ||||||
|  |     Behavior on implicitHeight { HNumberAnimation {} } | ||||||
|  |  | ||||||
|  |     AutoDirectionLayout { | ||||||
|  |         id: layout | ||||||
|  |         width: parent.width - theme.spacing * 2 | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         columnSpacing: theme.spacing | ||||||
|  |  | ||||||
|  |         HLabel { | ||||||
|  |             id: title | ||||||
|  |             text: viewer.fullTitle | ||||||
|  |             elide: HLabel.ElideMiddle | ||||||
|  |             topPadding: theme.spacing / 2 | ||||||
|  |             bottomPadding: topPadding | ||||||
|  |             horizontalAlignment: | ||||||
|  |                 layout.vertical ? HLabel.AlignHCenter : HLabel.AlignLeft | ||||||
|  |  | ||||||
|  |             Layout.fillWidth: maxTitleWidth < 0 | ||||||
|  |             Layout.maximumWidth: maxTitleWidth | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HSpacer { | ||||||
|  |             visible: ! title.Layout.fillWidth | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HLabel { | ||||||
|  |             id: dimensions | ||||||
|  |             text: qsTr("%1 x %2") | ||||||
|  |                   .arg(viewer.canvas.full.implicitWidth) | ||||||
|  |                   .arg(viewer.canvas.full.implicitHeight) | ||||||
|  |  | ||||||
|  |             elide: HLabel.ElideRight | ||||||
|  |             topPadding: theme.spacing / 2 | ||||||
|  |             bottomPadding: topPadding | ||||||
|  |             horizontalAlignment: HLabel.AlignHCenter | ||||||
|  |  | ||||||
|  |             Layout.fillWidth: layout.vertical | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HLabel { | ||||||
|  |             id: fileSize | ||||||
|  |             visible: viewer.fullFileSize !== 0 | ||||||
|  |             text: CppUtils.formattedBytes(viewer.fullFileSize) | ||||||
|  |             elide: HLabel.ElideRight | ||||||
|  |             topPadding: theme.spacing / 2 | ||||||
|  |             bottomPadding: topPadding | ||||||
|  |             horizontalAlignment: HLabel.AlignHCenter | ||||||
|  |  | ||||||
|  |             Layout.fillWidth: layout.vertical | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         HLoader { | ||||||
|  |             source: "../../Base/HBusyIndicator.qml" | ||||||
|  |             visible: Layout.preferredWidth > 0 | ||||||
|  |             active: viewer.canvas.full.showProgressBar | ||||||
|  |  | ||||||
|  |             Layout.topMargin: theme.spacing / 2 | ||||||
|  |             Layout.bottomMargin: Layout.topMargin | ||||||
|  |             Layout.alignment: Qt.AlignCenter | ||||||
|  |             Layout.preferredWidth: active ? height : 0 | ||||||
|  |             Layout.preferredHeight: fileSize.implicitHeight - theme.spacing | ||||||
|  |  | ||||||
|  |             Behavior on Layout.preferredWidth { HNumberAnimation {} } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	