Compare commits
2 commits
fefe757b6a
...
0c45946a0d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c45946a0d | ||
|
|
3ec7a71fa3 |
7 changed files with 178 additions and 148 deletions
|
|
@ -58,7 +58,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
function showGallery(index) {
|
||||
imageMouseArea.snapping = true;
|
||||
tapHandler.snapping = true;
|
||||
baseMode = "Full";
|
||||
extraZoomPercent = 100;
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ Rectangle {
|
|||
|
||||
currentIndex = idx;
|
||||
Qt.callLater( function() {
|
||||
imageMouseArea.snapping = false;
|
||||
tapHandler.snapping = false;
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
@ -113,85 +113,90 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// background click to close (outside mainImageFrame)
|
||||
|
||||
MouseArea {
|
||||
id: imageMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
|
||||
//preventStealing: false
|
||||
//propagateComposedEvents: true
|
||||
|
||||
property bool insideMe: false
|
||||
property bool snapping: false
|
||||
|
||||
onTapped: function(ev, button) {
|
||||
if( Qt.MiddleButton === button ) {
|
||||
mouse.accepted = true;
|
||||
overlayRoot.toggleBaseOrReset();
|
||||
return;
|
||||
}
|
||||
|
||||
let item = contentRepeater.itemAt( overlayRoot.currentIndex );
|
||||
if( !item || !item.clicked )
|
||||
return;
|
||||
|
||||
console.log(`Sending click`);
|
||||
item.clicked(ev);
|
||||
}
|
||||
|
||||
onDoubleTapped: function(ev, button) {
|
||||
ev.accepted = true;
|
||||
let item = contentRepeater.itemAt( overlayRoot.currentIndex );
|
||||
if( !item )
|
||||
return;
|
||||
|
||||
console.log(`Sending doubleClick`);
|
||||
item.doubleClicked(ev);
|
||||
}
|
||||
}
|
||||
DragHandler {
|
||||
id: dragHandler
|
||||
target: null
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
property bool dragging: false
|
||||
property real pressX: 0
|
||||
property real pressY: 0
|
||||
property int startIndex: 0
|
||||
property real dragFactor: 2.0 // perceived speed
|
||||
property real thresholdFactor: 0.15 // 15% of width to change
|
||||
property bool snapping: false
|
||||
property bool doubleClicking: false
|
||||
|
||||
Timer {
|
||||
id: doubleClickTimer
|
||||
interval: 150
|
||||
repeat: false
|
||||
property variant ev
|
||||
onTriggered: {
|
||||
let item = contentRepeater.itemAt( overlayRoot.currentIndex );
|
||||
if( !item || !item.clicked )
|
||||
return;
|
||||
|
||||
console.log(`Sending click`);
|
||||
item.clicked(ev);
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: function(ev) {
|
||||
ev.accepted = true;
|
||||
doubleClicking = true;
|
||||
doubleClickTimer.stop();
|
||||
let item = contentRepeater.itemAt( overlayRoot.currentIndex );
|
||||
if( !item || !item.doubleClicked )
|
||||
return;
|
||||
|
||||
console.log(`Sending doubleClick`);
|
||||
item.doubleClicked(ev);
|
||||
}
|
||||
|
||||
onPressed: function(mouse) {
|
||||
if (Qt.LeftButton === mouse.button) {
|
||||
mouse.accepted = true;
|
||||
insideMe = true;
|
||||
onActiveChanged: function() {
|
||||
const mouse = dragHandler.centroid.position;
|
||||
if( active ) {
|
||||
dragging = true;
|
||||
pressX = mouse.x;
|
||||
pressY = mouse.y;
|
||||
startIndex = overlayRoot.currentIndex;
|
||||
} else if (Qt.MiddleButton === mouse.button) {
|
||||
overlayRoot.toggleBaseOrReset();
|
||||
mouse.accepted = true;
|
||||
} else {
|
||||
dragging = false;
|
||||
|
||||
const pageWidth = mainImageFrame.width;
|
||||
if (pageWidth <= 0 || !overlayRoot.images || overlayRoot.images.length <= 0) {
|
||||
overlayRoot.currentIndex = 0;
|
||||
imageView.snap();
|
||||
return;
|
||||
}
|
||||
|
||||
const dx = (mouse.x - pressX) * dragFactor;
|
||||
const threshold = pageWidth * thresholdFactor;
|
||||
|
||||
let newIndex = startIndex;
|
||||
|
||||
if (Math.abs(dx) >= threshold) {
|
||||
if (dx < 0 && startIndex < images.length - 1)
|
||||
newIndex = startIndex + 1;
|
||||
else if (dx > 0 && startIndex > 0)
|
||||
newIndex = startIndex - 1;
|
||||
}
|
||||
|
||||
overlayRoot.currentIndex = newIndex;
|
||||
imageView.snap();
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: function(mouse) {
|
||||
if( Qt.LeftButton !== imageMouseArea.pressedButtons )
|
||||
return;
|
||||
onCentroidChanged: {
|
||||
if( !dragging ) return;
|
||||
|
||||
const mouse = dragHandler.centroid.position;
|
||||
const px = mouse.x - pressX;
|
||||
const py = mouse.y - pressY;
|
||||
|
||||
if( !insideMe )
|
||||
return;
|
||||
|
||||
if( !dragging ) {
|
||||
if( Math.hypot(px, py) < 10 ) // 10px threshold
|
||||
return;
|
||||
else
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
doubleClickTimer.stop();
|
||||
mouse.accepted = true;
|
||||
const pageWidth = mainImageFrame.width;
|
||||
if (pageWidth <= 0 || !overlayRoot.images || overlayRoot.images.length <= 0)
|
||||
return;
|
||||
|
|
@ -209,65 +214,12 @@ Rectangle {
|
|||
imageView.contentX = newX;
|
||||
}
|
||||
|
||||
onReleased: function(mouse) {
|
||||
if( Qt.LeftButton !== mouse.button )
|
||||
return;
|
||||
|
||||
if( !insideMe && !dragging )
|
||||
return false;
|
||||
|
||||
mouse.accepted = true;
|
||||
|
||||
if( !dragging ) {
|
||||
mouse.accepted = true;
|
||||
if( doubleClicking || doubleClickTimer.running ) {
|
||||
console.log(`Stopping doubleClickTimer`);
|
||||
doubleClicking = false;
|
||||
doubleClickTimer.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Starting doubleClickTimer`);
|
||||
doubleClickTimer.ev = mouse;
|
||||
doubleClickTimer.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
dragging = false;
|
||||
|
||||
if( Math.abs(pressX - mouse.x) < 5 && Math.abs(pressY - mouse.y) < 5 )
|
||||
return
|
||||
|
||||
const pageWidth = mainImageFrame.width;
|
||||
if (pageWidth <= 0 || !overlayRoot.images || overlayRoot.images.length <= 0) {
|
||||
overlayRoot.currentIndex = 0;
|
||||
imageView.snap();
|
||||
return;
|
||||
}
|
||||
|
||||
const dx = (mouse.x - pressX) * dragFactor;
|
||||
const threshold = pageWidth * thresholdFactor;
|
||||
|
||||
let newIndex = startIndex;
|
||||
|
||||
if (Math.abs(dx) >= threshold) {
|
||||
if (dx < 0 && startIndex < images.length - 1)
|
||||
newIndex = startIndex + 1;
|
||||
else if (dx > 0 && startIndex > 0)
|
||||
newIndex = startIndex - 1;
|
||||
}
|
||||
|
||||
overlayRoot.currentIndex = newIndex;
|
||||
imageView.snap();
|
||||
mouse.accepted = true;
|
||||
}
|
||||
|
||||
onCanceled: {
|
||||
dragging = false;
|
||||
insideMe = false;
|
||||
imageView.snap();
|
||||
}
|
||||
|
||||
}
|
||||
WheelHandler {
|
||||
onWheel: function(event) {
|
||||
event.accepted = true;
|
||||
const delta = event.angleDelta.y || event.pixelDelta.y;
|
||||
|
|
@ -305,7 +257,7 @@ Rectangle {
|
|||
x: 0 - contentX;
|
||||
|
||||
Behavior on x {
|
||||
enabled: !imageMouseArea.dragging && !imageMouseArea.snapping
|
||||
enabled: !tapHandler.dragging && !tapHandler.snapping
|
||||
NumberAnimation {
|
||||
duration: 150
|
||||
easing.type: Easing.InOutQuad
|
||||
|
|
@ -325,9 +277,9 @@ Rectangle {
|
|||
if (pageWidth <= 0)
|
||||
return;
|
||||
|
||||
if( instantly ) imageMouseArea.snapping = true;
|
||||
if( instantly ) tapHandler.snapping = true;
|
||||
imageView.contentX = overlayRoot.currentIndex * pageWidth;
|
||||
if( instantly ) imageMouseArea.snapping = false;
|
||||
if( instantly ) tapHandler.snapping = false;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
|
|
@ -515,7 +467,7 @@ Rectangle {
|
|||
preferredHighlightEnd: width * 2 / 3
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
highlightFollowsCurrentItem: true
|
||||
highlightMoveDuration: imageMouseArea.snapping ? 0 : 150
|
||||
highlightMoveDuration: tapHandler.snapping ? 0 : 150
|
||||
|
||||
onWidthChanged: {
|
||||
if (count > 0)
|
||||
|
|
@ -523,7 +475,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
Behavior on contentX {
|
||||
enabled: !imageMouseArea.snapping
|
||||
enabled: !tapHandler.snapping
|
||||
NumberAnimation {
|
||||
duration: 180
|
||||
easing.type: Easing.InOutQuad
|
||||
|
|
@ -569,9 +521,10 @@ Rectangle {
|
|||
//live: index === overlayRoot.currentIndex && visible
|
||||
}
|
||||
*/
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
onTapped: function(ev, btn) {
|
||||
ev.accepted = true;
|
||||
overlayRoot.currentIndex = index;
|
||||
imageView.snap();
|
||||
}
|
||||
|
|
@ -643,9 +596,12 @@ Rectangle {
|
|||
color: "white"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: hide()
|
||||
TapHandler {
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
onTapped: function(ev, btn) {
|
||||
ev.accepted = true;
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@ ToolButton {
|
|||
property int currentIndex: root.player[root.activeProperty]
|
||||
onTracksChanged: currentIndex = root.player[root.activeProperty];
|
||||
|
||||
signal updated(int track)
|
||||
|
||||
Menu {
|
||||
id: menu
|
||||
y: root.height
|
||||
y: 0 - height
|
||||
|
||||
Repeater {
|
||||
model: root.tracks || []
|
||||
|
|
@ -34,6 +36,7 @@ ToolButton {
|
|||
onTriggered: {
|
||||
root.currentIndex = trackIndex;
|
||||
root.player[root.activeProperty] = trackIndex;
|
||||
root.updated(trackIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ Item {
|
|||
console.log(`Audio Tracks: ${JSON.stringify(videoMediaPlayer.audioTracks, null, 2)}`);
|
||||
console.log(`Subtitle Tracks: ${JSON.stringify(videoMediaPlayer.subtitleTracks, null, 2)}`);
|
||||
|
||||
return; // skip thumbnails
|
||||
Qt.callLater( function() {
|
||||
console.log(`Calling grabToImage on ${previewItem} which is ${previewItem.implicitWidth}x${previewItem.implicitHeight}`);
|
||||
previewItem.grabToImage( function(res) {
|
||||
|
|
@ -112,6 +113,7 @@ Item {
|
|||
onActivated: {
|
||||
controlsBar.popup();
|
||||
videoMediaPlayer.audioOutput.muted = !videoMediaPlayer.audioOutput.muted;
|
||||
videoSessionManager.setMute(videoMediaPlayer.audioOutput.muted);
|
||||
}
|
||||
}
|
||||
Shortcut {
|
||||
|
|
@ -120,6 +122,7 @@ Item {
|
|||
onActivated: {
|
||||
controlsBar.popup();
|
||||
videoMediaPlayer.loopRequested = !videoMediaPlayer.loopRequested;
|
||||
videoSessionManager.setLoop(videoMediaPlayer.loopRequested);
|
||||
}
|
||||
}
|
||||
Shortcut {
|
||||
|
|
@ -244,7 +247,7 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
MouseArea {
|
||||
id: controlsBarMouse
|
||||
anchors.left: parent.left
|
||||
|
|
@ -262,7 +265,7 @@ Item {
|
|||
controlsCloseLater.interval = 2000;
|
||||
controlsCloseLater.start();
|
||||
}
|
||||
|
||||
*/
|
||||
Rectangle {
|
||||
id: controlsBar
|
||||
anchors.left: parent.left
|
||||
|
|
@ -273,9 +276,28 @@ Item {
|
|||
height: 60
|
||||
color: "#CC212121" // semi-opaque dark
|
||||
|
||||
onShouldBeVisibleChanged: {
|
||||
console.log(`shouldBeVisible: ${shouldBeVisible}`);
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: controlsBarMouseHover
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
console.log(`controlsBarMouseHover: ${hovered}`);
|
||||
controlsCloseLater.stop();
|
||||
if( hovered ) {
|
||||
controlsBar.shouldBeVisible = true;
|
||||
} else {
|
||||
controlsCloseLater.interval = 2000;
|
||||
controlsCloseLater.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function popup(duration) {
|
||||
if( !duration ) {
|
||||
if( controlsBarMouse.containsMouse )
|
||||
if( controlsBarMouseHover.hovered )
|
||||
return;
|
||||
duration = 1500;
|
||||
}
|
||||
|
|
@ -352,7 +374,10 @@ Item {
|
|||
text: "\uf0e2"
|
||||
checkable: true
|
||||
checked: videoMediaPlayer.loopRequested
|
||||
onClicked: videoMediaPlayer.loopRequested = !videoMediaPlayer.loopRequested
|
||||
onClicked: {
|
||||
videoMediaPlayer.loopRequested = !videoMediaPlayer.loopRequested;
|
||||
videoSessionManager.setLoop(videoMediaPlayer.loopRequested);
|
||||
}
|
||||
}
|
||||
|
||||
VolumeButton {
|
||||
|
|
@ -366,6 +391,9 @@ Item {
|
|||
player: videoMediaPlayer
|
||||
tracks: videoMediaPlayer.audioTracks
|
||||
activeProperty: "activeAudioTrack"
|
||||
onUpdated: function(v) {
|
||||
videoSessionManager.setAudioTrack(v);
|
||||
}
|
||||
text: "\uf1ab"
|
||||
}
|
||||
|
||||
|
|
@ -375,6 +403,9 @@ Item {
|
|||
player: videoMediaPlayer
|
||||
tracks: videoMediaPlayer.subtitleTracks
|
||||
activeProperty: "activeSubtitleTrack"
|
||||
onUpdated: function(v) {
|
||||
videoSessionManager.setSubtitleTrack(v);
|
||||
}
|
||||
text: "\uf20a"
|
||||
}
|
||||
|
||||
|
|
@ -387,5 +418,5 @@ Item {
|
|||
}
|
||||
} // RowLayout
|
||||
} // Rectangle
|
||||
} // MouseArea:constrolsBarMouse
|
||||
// } // MouseArea:constrolsBarMouse
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,40 @@ Item {
|
|||
sessions[k].pause();
|
||||
}
|
||||
|
||||
property bool m_muted: false
|
||||
property bool m_looping: false
|
||||
property int m_audioTrack: 0
|
||||
property int m_subtitleTrack: 0
|
||||
function setMute(onoff) {
|
||||
m_muted = onoff;
|
||||
const keys = Object.keys(sessions);
|
||||
for( let k of keys )
|
||||
sessions[k].audioOutput.muted = m_muted;
|
||||
}
|
||||
|
||||
function setLoop(onoff) {
|
||||
m_looping = onoff;
|
||||
const keys = Object.keys(sessions);
|
||||
for( let k of keys )
|
||||
sessions[k].loopRequested = m_looping;
|
||||
}
|
||||
|
||||
function setAudioTrack(idx) {
|
||||
m_audioTrack = idx;
|
||||
const keys = Object.keys(sessions);
|
||||
for( let k of keys )
|
||||
if( sessions[k].audioTracks.length < m_audioTrack )
|
||||
sessions[k].activeAudioTrack = m_audioTrack;
|
||||
}
|
||||
|
||||
function setSubtitleTrack(idx) {
|
||||
m_subtitleTrack = idx;
|
||||
const keys = Object.keys(sessions);
|
||||
for( let k of keys )
|
||||
if( sessions[k].subtitleTracks.length < m_subtitleTrack )
|
||||
sessions[k].activeSubtitleTrack = m_subtitleTrack;
|
||||
}
|
||||
|
||||
function ensureSession(messageId, url, videoOutput, callback) {
|
||||
if( videoSessionComponent.status !== Component.Ready )
|
||||
console.log(`videoSessionComponent not ready: ${videoSessionComponent.status} / ${videoSessionComponent.errorString()}`);
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ Control {
|
|||
if (v < 0) v = 0
|
||||
if (v > 1) v = 1
|
||||
audioOutput.volume = v
|
||||
if (v > 0 && audioOutput.muted)
|
||||
audioOutput.muted = false
|
||||
if (v > 0 && audioOutput.muted) {
|
||||
audioOutput.muted = false;
|
||||
videoSessionManager.setMute(audioOutput.muted);
|
||||
}
|
||||
|
||||
popup.open();
|
||||
if( !popupHover.containsMouse )
|
||||
|
|
@ -51,14 +53,12 @@ Control {
|
|||
text: root.volumeIcon()
|
||||
focusPolicy: Qt.NoFocus
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
|
||||
onClicked: function(ev) {
|
||||
onTapped: function(ev, button) {
|
||||
if (!root.audioOutput)
|
||||
return
|
||||
|
||||
const button = ev.button;
|
||||
if (button === Qt.MiddleButton) {
|
||||
ev.accepted = true
|
||||
root.audioOutput.toggleMuted();
|
||||
|
|
@ -69,13 +69,14 @@ Control {
|
|||
closeTimer.stop();
|
||||
closeTimer.start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (button === Qt.LeftButton)
|
||||
{
|
||||
ev.accepted = true
|
||||
popup.open()
|
||||
}
|
||||
|
||||
ev.accepted = true
|
||||
popup.open()
|
||||
}
|
||||
}
|
||||
WheelHandler {
|
||||
onWheel: function(ev) {
|
||||
root.setVolumeFromWheel(ev.angleDelta.y)
|
||||
ev.accepted = true
|
||||
|
|
@ -169,6 +170,7 @@ Control {
|
|||
root.audioOutput.muted = false;
|
||||
else
|
||||
root.audioOutput.muted = true;
|
||||
videoSessionManager.setMute(audioOutput.muted);
|
||||
|
||||
root.audioOutput.volume = value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ Window {
|
|||
contentHeight: flow.height
|
||||
contentWidth: flow.width
|
||||
clip: true
|
||||
interactive: !imageViewer.visible
|
||||
|
||||
GridLayout {
|
||||
id: flow
|
||||
|
|
@ -250,9 +251,10 @@ Window {
|
|||
color: "transparent"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: navigator.open(modelData);
|
||||
TapHandler {
|
||||
enabled: !imageViewer.visible
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.TouchScreen
|
||||
onTapped: navigator.open(modelData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ int main(int argc, char *argv[])
|
|||
app.setOrganizationDomain("oneill.app");
|
||||
app.setDesktopFileName("Media.desktop");
|
||||
|
||||
QGuiApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.rootContext()->setContextProperty("Clipboard", new Clipboard());
|
||||
engine.rootContext()->setContextProperty("Settings", new Settings());
|
||||
|
|
|
|||
Loading…
Reference in a new issue