mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-23 18:17:38 +00:00
Port window-manager to React (#174)
This commit is contained in:
parent
c5caa3cbf6
commit
a87c5cfaf0
5 changed files with 121 additions and 109 deletions
77
js/DraggableWindow.jsx
Normal file
77
js/DraggableWindow.jsx
Normal file
|
|
@ -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;
|
||||
|
|
@ -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 <DragTarget handleFiles={handleDrop}>
|
||||
<div id='main-window' className={className}>
|
||||
<div id='loading'>Loading...</div>
|
||||
<div id='title-bar' className='selected'>
|
||||
<ContextMenu mediaPlayer={props.mediaPlayer} winamp={props.winamp} />
|
||||
<ShadeTime />
|
||||
<div id='minimize'></div>
|
||||
<Shade />
|
||||
<Close />
|
||||
<DraggableWindow handleClass='title-bar'>
|
||||
<div id='main-window' className={className}>
|
||||
<div id='loading'>Loading...</div>
|
||||
<div id='title-bar' className='selected title-bar'>
|
||||
<ContextMenu mediaPlayer={props.mediaPlayer} winamp={props.winamp} />
|
||||
<ShadeTime />
|
||||
<div id='minimize'></div>
|
||||
<Shade />
|
||||
<Close />
|
||||
</div>
|
||||
<div className='status'>
|
||||
<ClutterBar />
|
||||
<div id='play-pause'></div>
|
||||
<div id='work-indicator' className={props.display.working ? 'selected' : ''}></div>
|
||||
<Time />
|
||||
<Visualizer />
|
||||
</div>
|
||||
<div className='media-info'>
|
||||
<Marquee />
|
||||
<Kbps />
|
||||
<Khz />
|
||||
<MonoStereo />
|
||||
</div>
|
||||
<Volume />
|
||||
<Balance />
|
||||
<div className='windows'>
|
||||
<div id='equalizer-button'></div>
|
||||
<div id='playlist-button'></div>
|
||||
</div>
|
||||
<Position mediaPlayer={props.mediaPlayer} />
|
||||
<Actions mediaPlayer={props.mediaPlayer} />
|
||||
<Eject />
|
||||
<div className='shuffle-repeat'>
|
||||
<Shuffle />
|
||||
<Repeat />
|
||||
</div>
|
||||
<a id='about' target='blank' href='https://github.com/captbaritone/winamp2-js'></a>
|
||||
</div>
|
||||
<div className='status'>
|
||||
<ClutterBar />
|
||||
<div id='play-pause'></div>
|
||||
<div id='work-indicator' className={props.display.working ? 'selected' : ''}></div>
|
||||
<Time />
|
||||
<Visualizer />
|
||||
</div>
|
||||
<div className='media-info'>
|
||||
<Marquee />
|
||||
<Kbps />
|
||||
<Khz />
|
||||
<MonoStereo />
|
||||
</div>
|
||||
<Volume />
|
||||
<Balance />
|
||||
<div className='windows'>
|
||||
<div id='equalizer-button'></div>
|
||||
<div id='playlist-button'></div>
|
||||
</div>
|
||||
<Position mediaPlayer={props.mediaPlayer} />
|
||||
<Actions mediaPlayer={props.mediaPlayer} />
|
||||
<Eject />
|
||||
<div className='shuffle-repeat'>
|
||||
<Shuffle />
|
||||
<Repeat />
|
||||
</div>
|
||||
<a id='about' target='blank' href='https://github.com/captbaritone/winamp2-js'></a>
|
||||
</div>
|
||||
</DraggableWindow>
|
||||
</DragTarget>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = {
|
||||
init: function() {
|
||||
this.handle = document.getElementById('title-bar');
|
||||
this.body = document.getElementById('main-window');
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue