diff --git a/js/DraggableWindow.jsx b/js/DraggableWindow.jsx new file mode 100644 index 00000000..e342197c --- /dev/null +++ b/js/DraggableWindow.jsx @@ -0,0 +1,77 @@ +import {cloneElement, Children, Component} from 'react'; + +// Many of the ideas of how to build this as a React componant were stolen +// from: https://github.com/mzabriskie/react-draggable Thanks! @mzabriskie +class DraggableWindow extends Component { + constructor(props) { + super(props); + this.handleMouseDown = this.handleMouseDown.bind(this); + this.state = {}; + } + + handleMouseDown(e) { + if (!e.target.classList.contains(this.props.handleClass)) { + // Prevent going into drag mode when clicking any of the title + // bar's icons by making sure the click was made directly on the + // handle + return true; + } + // If the element was 'absolutely' positioned we could simply use + // offsetLeft / offsetTop however the element is 'relatively' + // positioned so we're using style.left. parseInt is used to remove the + // 'px' postfix from the value + const winStart = { + left: parseInt(this.body.offsetLeft || 0, 10), + top: parseInt(this.body.offsetTop || 0, 10) + }; + + // Get starting mouse position + const mouseStart = { + left: e.clientX, + top: e.clientY + }; + + // Mouse move handler function while mouse is down + const handleMove = (moveEvent) => { + // Calculate difference offsets between current and starting positions + const diff = { + left: moveEvent.clientX - mouseStart.left, + top: moveEvent.clientY - mouseStart.top + }; + + // These margins were only useful for centering the div, now we + // don't need them + this.setState({ + marginLeft: '0px', + marginTop: '0px', + left: `${winStart.left + diff.left}px`, + top: `${winStart.top + diff.top}px`, + position: 'absolute' + }); + }; + + // Mouse button up + function handleUp() { + removeListeners(); + } + + function removeListeners() { + window.removeEventListener('mousemove', handleMove); + window.removeEventListener('mouseup', handleUp); + } + + window.addEventListener('mousemove', handleMove); + window.addEventListener('mouseup', handleUp); + return false; + } + render() { + return cloneElement(Children.only(this.props.children), { + ref: (body) => this.body = body, + onMouseDown: this.handleMouseDown, + style: {...this.props.children.props, ...this.state} + }); + } + +} + +module.exports = DraggableWindow; diff --git a/js/MainWindow.jsx b/js/MainWindow.jsx index 039daebd..0b5abb32 100644 --- a/js/MainWindow.jsx +++ b/js/MainWindow.jsx @@ -8,6 +8,7 @@ import Close from './Close.jsx'; import ClutterBar from './ClutterBar.jsx'; import ContextMenu from './ContextMenu.jsx'; import DragTarget from './DragTarget.jsx'; +import DraggableWindow from './DraggableWindow.jsx'; import Eject from './Eject.jsx'; import Kbps from './Kbps.jsx'; import Khz from './Khz.jsx'; @@ -45,44 +46,51 @@ const MainWindow = (props) => { props.winamp.loadFromFileReference(files[0]); }; + // NOTE: DragTarget but be outside Draggable Window, since currently + // DragTarget creates a wrapper DOM element which, since main-window is + // absolutely positioned, exists at a different location than the main + // window. Drag/Drop still work, because events propogate up to parent + // elements. return -
-
Loading...
-
- - -
- - + +
+
Loading...
+
+ + +
+ + +
+
+ +
+
+
+
+ + + + + + + +
+
+
+
+ + + +
+ + +
+ -
- -
-
-
-
- - - - - - - -
-
-
-
- - - -
- - -
- - + ; }; diff --git a/js/main-window.js b/js/main-window.js deleted file mode 100644 index 17777896..00000000 --- a/js/main-window.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - init: function() { - this.handle = document.getElementById('title-bar'); - this.body = document.getElementById('main-window'); - return this; - } -}; diff --git a/js/winamp.js b/js/winamp.js index 0c6aadf5..8f509d1c 100755 --- a/js/winamp.js +++ b/js/winamp.js @@ -1,6 +1,4 @@ // UI and App logic -import MainWindow from './main-window'; -import WindowManager from './window-manager'; import Skin from './skin'; import Media from './media'; import MyFile from './my-file'; @@ -14,12 +12,9 @@ module.exports = { this.fileInput.type = 'file'; this.fileInput.style.display = 'none'; - this.windowManager = WindowManager; this.skin = Skin.init(document.getElementById('visualizer'), this.media._analyser); this.state = ''; - this.mainWindow = MainWindow.init(this); - this.events = { timeUpdated: new Event('timeUpdated') }; @@ -36,8 +31,6 @@ module.exports = { }, _registerListeners: function() { - this.windowManager.registerWindow(this.mainWindow); - this.media.addEventListener('timeupdate', () => { this.dispatch({type: 'UPDATE_TIME_ELAPSED', elapsed: this.media.timeElapsed()}); // Legacy diff --git a/js/window-manager.js b/js/window-manager.js deleted file mode 100644 index b57fc3e0..00000000 --- a/js/window-manager.js +++ /dev/null @@ -1,59 +0,0 @@ -module.exports = { - registerWindow: function(win) { - var body = win.body; - var handle = win.handle; - - // Make window dragable - handle.addEventListener('mousedown', function(e){ - if (e.target !== this) { - // Prevent going into drag mode when clicking any of the title - // bar's icons by making sure the click was made directly on the - // titlebar - return true; - } - - // If the element was 'absolutely' positioned we could simply use - // offsetLeft / offsetTop however the element is 'relatively' - // positioned so we're using style.left. parseInt is used to remove the - // 'px' postfix from the value - var winStartLeft = parseInt(body.offsetLeft || 0, 10), - winStartTop = parseInt(body.offsetTop || 0, 10); - - // Get starting mouse position - var mouseStartLeft = e.clientX, - mouseStartTop = e.clientY; - - // Mouse move handler function while mouse is down - function handleMove(moveEvent) { - // Get current mouse position - var mouseLeft = moveEvent.clientX, - mouseTop = moveEvent.clientY; - - // Calculate difference offsets - var diffLeft = mouseLeft - mouseStartLeft, - diffTop = mouseTop - mouseStartTop; - - // These margins were only useful for centering the div, now we - // don't need them - body.style.marginLeft = '0px'; - body.style.marginTop = '0px'; - // Move window to new position - body.style.left = (winStartLeft + diffLeft) + 'px'; - body.style.top = (winStartTop + diffTop) + 'px'; - } - - // Mouse button up - function handleUp() { - removeListeners(); - } - - function removeListeners() { - window.removeEventListener('mousemove', handleMove); - window.removeEventListener('mouseup', handleUp); - } - - window.addEventListener('mousemove', handleMove); - window.addEventListener('mouseup', handleUp); - }); - } -};