mirror of
https://github.com/captbaritone/webamp.git
synced 2026-08-05 00:14:46 +00:00
More EQ stuff
This commit is contained in:
parent
8d6357f26c
commit
4fb6467015
9 changed files with 370 additions and 130 deletions
|
|
@ -9,6 +9,38 @@
|
|||
width: 275px;
|
||||
}
|
||||
|
||||
#winamp2-js #on {
|
||||
position: absolute;
|
||||
width: 26px;
|
||||
height: 12px;
|
||||
top: 18px;
|
||||
left: 14px;
|
||||
}
|
||||
|
||||
#winamp2-js #auto {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 12px;
|
||||
top: 18px;
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
#winamp2-js #presets {
|
||||
position: absolute;
|
||||
width: 44px;
|
||||
height: 12px;
|
||||
top: 18px;
|
||||
left: 217px;
|
||||
}
|
||||
|
||||
#winamp2-js #eqGraph {
|
||||
position: absolute;
|
||||
width: 113px;
|
||||
height: 19px;
|
||||
top: 17px;
|
||||
left: 86px;
|
||||
}
|
||||
|
||||
#winamp2-js #preamp {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
|
|
|
|||
|
|
@ -51,4 +51,4 @@ class Band extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default connect((state) => state.equalizer)(Band);
|
||||
export default connect((state) => state.equalizer.sliders)(Band);
|
||||
|
|
|
|||
27
js/components/EqAuto.jsx
Normal file
27
js/components/EqAuto.jsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
|
||||
class EqAuto extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'TOGGLE_EQ_AUTO'});
|
||||
}
|
||||
|
||||
render() {
|
||||
const className = classnames({
|
||||
selected: this.props.auto
|
||||
});
|
||||
return <div
|
||||
id='auto'
|
||||
className={className}
|
||||
onClick={this.handleClick}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect((state) => state.equalizer)(EqAuto);
|
||||
88
js/components/EqGraph.jsx
Normal file
88
js/components/EqGraph.jsx
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
export const getY = (value) => (
|
||||
32 - ((value / 100) * 32)
|
||||
);
|
||||
|
||||
class EqGraph extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.canvasCtx = this.refs.canvas.getContext('2d');
|
||||
this.canvasCtx.imageSmoothingEnabled = false;
|
||||
this.width = this.refs.canvas.width * 1; // Cast to int
|
||||
this.height = this.refs.canvas.height * 1; // Cast to int
|
||||
this.bgImage = new Image();
|
||||
this.bgImage.onload = () => {
|
||||
this.createColorPattern();
|
||||
this.componentDidUpdate();
|
||||
};
|
||||
this.bgImage.src = 'bg.png';
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.canvasCtx.clearRect(0, 0, this.width, this.height);
|
||||
this.drawPreampLine();
|
||||
this.drawEqLine(); // This should paint on top of the preamp line
|
||||
}
|
||||
|
||||
createColorPattern() {
|
||||
const colorsCanvas = document.createElement('canvas');
|
||||
const colorsCtx = colorsCanvas.getContext('2d');
|
||||
colorsCanvas.width = this.bgImage.width * 2;
|
||||
colorsCanvas.height = this.bgImage.height * 2;
|
||||
colorsCtx.drawImage(this.bgImage, 0, 0, colorsCanvas.width, colorsCanvas.height);
|
||||
this.colorPattern = this.canvasCtx.createPattern(colorsCanvas, 'repeat-x');
|
||||
}
|
||||
|
||||
drawEqLine() {
|
||||
const {props} = this;
|
||||
const values = [
|
||||
props.band60,
|
||||
props.band170,
|
||||
props.band310,
|
||||
props.band600,
|
||||
props.band1k,
|
||||
props.band3k,
|
||||
props.band6k,
|
||||
props.band12k,
|
||||
props.band14k,
|
||||
props.band16k
|
||||
];
|
||||
|
||||
this.canvasCtx.strokeStyle = this.colorPattern;
|
||||
this.canvasCtx.lineWidth = 2;
|
||||
this.canvasCtx.beginPath();
|
||||
const paddingLeft = 4;
|
||||
// TODO: Curve these lines
|
||||
// TODO: Color these lines
|
||||
values.forEach((value, i) => {
|
||||
this.canvasCtx.lineTo(paddingLeft + (i * 16), getY(value));
|
||||
});
|
||||
this.canvasCtx.stroke();
|
||||
}
|
||||
|
||||
drawPreampLine() {
|
||||
const preampValue = getY(this.props.preamp);
|
||||
this.canvasCtx.lineWidth = 2;
|
||||
this.canvasCtx.strokeStyle = 'white';
|
||||
this.canvasCtx.beginPath();
|
||||
this.canvasCtx.moveTo(0, preampValue);
|
||||
this.canvasCtx.lineTo(this.width, preampValue);
|
||||
this.canvasCtx.stroke();
|
||||
}
|
||||
|
||||
render() {
|
||||
return <canvas
|
||||
id='eqGraph'
|
||||
ref='canvas'
|
||||
width='152'
|
||||
height='32'
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((state) => state.equalizer.sliders)(EqGraph);
|
||||
27
js/components/EqOn.jsx
Normal file
27
js/components/EqOn.jsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
|
||||
class EqOn extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'TOGGLE_EQ_ON'});
|
||||
}
|
||||
|
||||
render() {
|
||||
const className = classnames({
|
||||
selected: this.props.on
|
||||
});
|
||||
return <div
|
||||
id='on'
|
||||
className={className}
|
||||
onClick={this.handleClick}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect((state) => state.equalizer)(EqOn);
|
||||
|
|
@ -4,54 +4,73 @@ import classnames from 'classnames';
|
|||
|
||||
import DraggableWindow from './DraggableWindow.jsx';
|
||||
import Band from './Band.jsx';
|
||||
import EqOn from './EqOn.jsx';
|
||||
import EqAuto from './EqAuto.jsx';
|
||||
import EqGraph from './EqGraph.jsx';
|
||||
|
||||
import '../../css/equalizer-window.css';
|
||||
|
||||
const EqualizerWindow = (props) => {
|
||||
const {doubled} = props.display;
|
||||
class EqualizerWindow extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
const className = classnames({
|
||||
window: true,
|
||||
doubled
|
||||
});
|
||||
return <DraggableWindow handleClass='title-bar'>
|
||||
<div id='equalizer-window' className={className}>
|
||||
<div className='equalizer-top title-bar' />
|
||||
<div id='preamp'>
|
||||
<Band band='preamp' />
|
||||
</div>
|
||||
<div id='band-60'>
|
||||
<Band band='band60' />
|
||||
</div>
|
||||
<div id='band-170'>
|
||||
<Band band='band170' />
|
||||
</div>
|
||||
<div id='band-310'>
|
||||
<Band band='band310' />
|
||||
</div>
|
||||
<div id='band-600'>
|
||||
<Band band='band600' />
|
||||
</div>
|
||||
<div id='band-1k'>
|
||||
<Band band='band1k' />
|
||||
</div>
|
||||
<div id='band-3k'>
|
||||
<Band band='band3k' />
|
||||
</div>
|
||||
<div id='band-6k'>
|
||||
<Band band='band6k' />
|
||||
</div>
|
||||
<div id='band-12k'>
|
||||
<Band band='band12k' />
|
||||
</div>
|
||||
<div id='band-14k'>
|
||||
<Band band='band14k' />
|
||||
</div>
|
||||
<div id='band-16k'>
|
||||
<Band band='band16k' />
|
||||
</div>
|
||||
</div>
|
||||
</DraggableWindow>;
|
||||
};
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'SET_FOCUSED_WINDOW', window: 'EQUALIZER'});
|
||||
}
|
||||
|
||||
module.exports = connect((state) => state)(EqualizerWindow);
|
||||
render() {
|
||||
const {doubled} = this.props.display;
|
||||
|
||||
const className = classnames({
|
||||
window: true,
|
||||
selected: this.props.windows.focused === 'EQUALIZER',
|
||||
doubled
|
||||
});
|
||||
return <DraggableWindow handleClass='title-bar'>
|
||||
<div id='equalizer-window' className={className} onClick={this.handleClick}>
|
||||
<div className='equalizer-top title-bar' />
|
||||
<EqOn />
|
||||
<EqAuto />
|
||||
<EqGraph />
|
||||
<div id='presets' />
|
||||
<div id='preamp'>
|
||||
<Band band='preamp' />
|
||||
</div>
|
||||
<div id='band-60'>
|
||||
<Band band='band60' />
|
||||
</div>
|
||||
<div id='band-170'>
|
||||
<Band band='band170' />
|
||||
</div>
|
||||
<div id='band-310'>
|
||||
<Band band='band310' />
|
||||
</div>
|
||||
<div id='band-600'>
|
||||
<Band band='band600' />
|
||||
</div>
|
||||
<div id='band-1k'>
|
||||
<Band band='band1k' />
|
||||
</div>
|
||||
<div id='band-3k'>
|
||||
<Band band='band3k' />
|
||||
</div>
|
||||
<div id='band-6k'>
|
||||
<Band band='band6k' />
|
||||
</div>
|
||||
<div id='band-12k'>
|
||||
<Band band='band12k' />
|
||||
</div>
|
||||
<div id='band-14k'>
|
||||
<Band band='band14k' />
|
||||
</div>
|
||||
<div id='band-16k'>
|
||||
<Band band='band16k' />
|
||||
</div>
|
||||
</div>
|
||||
</DraggableWindow>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect((state) => state)(EqualizerWindow);
|
||||
|
|
|
|||
|
|
@ -25,74 +25,86 @@ import Volume from './Volume.jsx';
|
|||
|
||||
import '../../css/main-window.css';
|
||||
|
||||
const MainWindow = (props) => {
|
||||
const {status} = props.media;
|
||||
const {loading, doubled, shade, closed, llama} = props.display;
|
||||
class MainWindow extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
const className = classnames({
|
||||
window: true,
|
||||
// TODO: Handle these status changes in the individual components
|
||||
play: status === 'PLAYING',
|
||||
stop: status === 'STOPPED',
|
||||
pause: status === 'PAUSED',
|
||||
loading,
|
||||
doubled,
|
||||
llama,
|
||||
shade,
|
||||
closed
|
||||
});
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'SET_FOCUSED_WINDOW', window: 'MAIN'});
|
||||
}
|
||||
|
||||
// TODO: Move this to an actionCreator
|
||||
const handleDrop = (files) => {
|
||||
props.winamp.loadFromFileReference(files[0]);
|
||||
};
|
||||
render() {
|
||||
const {status} = this.props.media;
|
||||
const {loading, doubled, shade, closed, llama} = this.props.display;
|
||||
|
||||
// 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}>
|
||||
<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' />
|
||||
<Shade />
|
||||
<Close mediaPlayer={props.mediaPlayer} />
|
||||
</div>
|
||||
<div className='status'>
|
||||
<ClutterBar />
|
||||
<div id='play-pause' />
|
||||
<div id='work-indicator' className={props.display.working ? 'selected' : ''} />
|
||||
<Time />
|
||||
<Visualizer analyser={props.mediaPlayer._analyser}/>
|
||||
</div>
|
||||
<div className='media-info'>
|
||||
<Marquee />
|
||||
<Kbps />
|
||||
<Khz />
|
||||
<MonoStereo />
|
||||
</div>
|
||||
<Volume mediaPlayer={props.mediaPlayer} />
|
||||
<Balance mediaPlayer={props.mediaPlayer} />
|
||||
<div className='windows'>
|
||||
<div id='equalizer-button' />
|
||||
<div id='playlist-button' />
|
||||
</div>
|
||||
<Position mediaPlayer={props.mediaPlayer} />
|
||||
<ActionButtons mediaPlayer={props.mediaPlayer} />
|
||||
<Eject winamp={props.winamp} />
|
||||
<div className='shuffle-repeat'>
|
||||
<Shuffle mediaPlayer={props.mediaPlayer} />
|
||||
<Repeat mediaPlayer={props.mediaPlayer} />
|
||||
</div>
|
||||
<a id='about' target='blank' href='https://github.com/captbaritone/winamp2-js' />
|
||||
</div>
|
||||
</DraggableWindow>
|
||||
</DragTarget>;
|
||||
};
|
||||
const className = classnames({
|
||||
window: true,
|
||||
// TODO: Handle these status changes in the individual components
|
||||
play: status === 'PLAYING',
|
||||
stop: status === 'STOPPED',
|
||||
pause: status === 'PAUSED',
|
||||
selected: this.props.windows.focused === 'MAIN',
|
||||
loading,
|
||||
doubled,
|
||||
llama,
|
||||
shade,
|
||||
closed
|
||||
});
|
||||
|
||||
module.exports = connect((state) => state)(MainWindow);
|
||||
// TODO: Move this to an actionCreator
|
||||
const handleDrop = (files) => {
|
||||
this.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}>
|
||||
<DraggableWindow handleClass='title-bar'>
|
||||
<div id='main-window' className={className} onClick={this.handleClick}>
|
||||
<div id='loading'>Loading...</div>
|
||||
<div id='title-bar' className='selected title-bar'>
|
||||
<ContextMenu mediaPlayer={this.props.mediaPlayer} winamp={this.props.winamp} />
|
||||
<ShadeTime />
|
||||
<div id='minimize' />
|
||||
<Shade />
|
||||
<Close mediaPlayer={this.props.mediaPlayer} />
|
||||
</div>
|
||||
<div className='status'>
|
||||
<ClutterBar />
|
||||
<div id='play-pause' />
|
||||
<div id='work-indicator' className={this.props.display.working ? 'selected' : ''} />
|
||||
<Time />
|
||||
<Visualizer analyser={this.props.mediaPlayer._analyser}/>
|
||||
</div>
|
||||
<div className='media-info'>
|
||||
<Marquee />
|
||||
<Kbps />
|
||||
<Khz />
|
||||
<MonoStereo />
|
||||
</div>
|
||||
<Volume mediaPlayer={this.props.mediaPlayer} />
|
||||
<Balance mediaPlayer={this.props.mediaPlayer} />
|
||||
<div className='windows'>
|
||||
<div id='equalizer-button' />
|
||||
<div id='playlist-button' />
|
||||
</div>
|
||||
<Position mediaPlayer={this.props.mediaPlayer} />
|
||||
<ActionButtons mediaPlayer={this.props.mediaPlayer} />
|
||||
<Eject winamp={this.props.winamp} />
|
||||
<div className='shuffle-repeat'>
|
||||
<Shuffle mediaPlayer={this.props.mediaPlayer} />
|
||||
<Repeat mediaPlayer={this.props.mediaPlayer} />
|
||||
</div>
|
||||
<a id='about' target='blank' href='https://github.com/captbaritone/winamp2-js' />
|
||||
</div>
|
||||
</DraggableWindow>
|
||||
</DragTarget>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect((state) => state)(MainWindow);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,20 @@ const userInput = (state, action) => {
|
|||
}
|
||||
};
|
||||
|
||||
const windows = (state, action) => {
|
||||
if (!state) {
|
||||
return {
|
||||
focused: 'MAIN'
|
||||
};
|
||||
}
|
||||
switch (action.type) {
|
||||
case 'SET_FOCUSED_WINDOW':
|
||||
return {...state, focused: action.window};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const display = (state, action) => {
|
||||
if (!state) {
|
||||
return {
|
||||
|
|
@ -87,24 +101,32 @@ const contextMenu = (state, action) => {
|
|||
const equalizer = (state, action) => {
|
||||
if (!state) {
|
||||
return {
|
||||
preamp: 50,
|
||||
band60: 50,
|
||||
band170: 50,
|
||||
band310: 50,
|
||||
band600: 50,
|
||||
band1k: 50,
|
||||
band3k: 50,
|
||||
band6k: 50,
|
||||
band12k: 50,
|
||||
band14k: 50,
|
||||
band16k: 50
|
||||
on: false,
|
||||
auto: false,
|
||||
sliders: {
|
||||
preamp: 50,
|
||||
band60: 50,
|
||||
band170: 50,
|
||||
band310: 50,
|
||||
band600: 50,
|
||||
band1k: 50,
|
||||
band3k: 50,
|
||||
band6k: 50,
|
||||
band12k: 50,
|
||||
band14k: 50,
|
||||
band16k: 50
|
||||
}
|
||||
};
|
||||
}
|
||||
switch (action.type) {
|
||||
case 'SET_BAND_VALUE':
|
||||
const newState = {...state};
|
||||
newState[action.band] = action.value;
|
||||
return newState;
|
||||
const newSliders = {...state.sliders};
|
||||
newSliders[action.band] = action.value;
|
||||
return {...state, sliders: newSliders};
|
||||
case 'TOGGLE_EQ_ON':
|
||||
return {...state, on: !state.on};
|
||||
case 'TOGGLE_EQ_AUTO':
|
||||
return {...state, auto: !state.auto};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -160,6 +182,7 @@ const media = (state, action) => {
|
|||
|
||||
const reducer = combineReducers({
|
||||
userInput,
|
||||
windows,
|
||||
display,
|
||||
contextMenu,
|
||||
equalizer,
|
||||
|
|
|
|||
|
|
@ -146,7 +146,19 @@ module.exports = [
|
|||
{selectors: ['.selected .equalizer-top'], x: 0, y: 134, width: 275, height: 14},
|
||||
{selectors: ['.band'], x: 13, y: 164, width: 209, height: 129},
|
||||
{selectors: ['.band input::-webkit-slider-thumb', 'band input::-moz-range-thumb'], x: 0, y: 164, width: 11, height: 11},
|
||||
{selectors: ['band input::-webkit-slider-thumb:active', '.band input::-moz-range-thumb:active'], x: 0, y: 176, width: 11, height: 11}
|
||||
{selectors: ['band input::-webkit-slider-thumb:active', '.band input::-moz-range-thumb:active'], x: 0, y: 176, width: 11, height: 11},
|
||||
{selectors: ['#on'], x: 10, y: 119, width: 26, height: 12},
|
||||
{selectors: ['#on:active'], x: 128, y: 119, width: 26, height: 12},
|
||||
{selectors: ['#on.selected'], x: 69, y: 119, width: 26, height: 12},
|
||||
{selectors: ['#on.selected:active'], x: 187, y: 119, width: 26, height: 12},
|
||||
{selectors: ['#auto'], x: 36, y: 119, width: 32, height: 12},
|
||||
{selectors: ['#auto:active'], x: 154, y: 119, width: 32, height: 12},
|
||||
{selectors: ['#auto.selected'], x: 95, y: 119, width: 32, height: 12},
|
||||
{selectors: ['#auto.selected:active'], x: 213, y: 119, width: 32, height: 12},
|
||||
{selectors: ['#eqGraph'], x: 0, y: 294, width: 113, height: 19},
|
||||
{selectors: ['#presets'], x: 224, y: 164, width: 44, height: 12},
|
||||
{selectors: ['#presets:active'], x: 224, y: 176, width: 44, height: 12},
|
||||
{name: 'PREAMP_LINE', selectors: ['#preamp-line'], x: 0, y: 314, width: 113, height: 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -182,7 +194,7 @@ module.exports = [
|
|||
name: 'TITLEBAR',
|
||||
sprites: [
|
||||
{selectors: ['#title-bar'], x: 27, y: 15, width: 275, height: 14},
|
||||
{selectors: ['#title-bar.selected'], x: 27, y: 0, width: 275, height: 14},
|
||||
{selectors: ['.selected #title-bar'], x: 27, y: 0, width: 275, height: 14},
|
||||
{selectors: ['.llama #title-bar'], x: 27, y: 61, width: 275, height: 14},
|
||||
{selectors: ['.llama #title-bar.selected'], x: 27, y: 57, width: 275, height: 14},
|
||||
{selectors: ['#title-bar #option'], x: 0, y: 0, width: 9, height: 9},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue