diff --git a/css/context-menu.css b/css/context-menu.css index 7c1b3a7e..62dda464 100644 --- a/css/context-menu.css +++ b/css/context-menu.css @@ -1,5 +1,11 @@ +#winamp2-js .doubled #context-menu { + -moz-transform: scale(0.5); + -moz-transform-origin: top left; + -webkit-transform: scale(0.5); + -webkit-transform-origin: top left; +} + #winamp2-js #context-menu { - display: none; left: 0px; } @@ -11,11 +17,7 @@ top: 0px; } -#winamp2-js div:active > div > #context-menu { - display: block; -} - -#winamp2-js .selected > #context-menu { +#winamp2-js .selected #context-menu { display: block; } @@ -43,6 +45,7 @@ padding: 1px 18px 3px 18px; display: block; } + #winamp2-js #context-menu li.parent:after { float: right; content: "\25b8"; diff --git a/css/equalizer-window.css b/css/equalizer-window.css index 2893a712..1f95f44b 100644 --- a/css/equalizer-window.css +++ b/css/equalizer-window.css @@ -112,7 +112,7 @@ left: 40px; } -#winamp2-js #presets { +#winamp2-js #presets-context { position: absolute; width: 44px; height: 12px; @@ -120,6 +120,11 @@ left: 217px; } +#winamp2-js #presets { + width: 100%; + height: 100%; +} + #winamp2-js #eqGraph { position: absolute; width: 113px; diff --git a/css/main-window.css b/css/main-window.css index 3af85597..a05775db 100755 --- a/css/main-window.css +++ b/css/main-window.css @@ -12,19 +12,6 @@ -ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */ } -#winamp2-js #main-window.doubled #context-menu { - -moz-transform: scale(0.5); - -moz-transform-origin: top left; - -webkit-transform: scale(0.5); - -webkit-transform-origin: top left; -} - -#winamp2-js #main-window.loading { - background-image: none; - background-color: #ffffff; - border: 2px solid #dddddd; -} - #winamp2-js #loading { color: white; text-align: center; @@ -92,7 +79,7 @@ cursor: url("../cursors/TITLEBAR.PNG"), auto; } -#winamp2-js #option, +#winamp2-js #option-context, #winamp2-js #minimize, #winamp2-js #shade, #winamp2-js #close { @@ -104,6 +91,11 @@ } #winamp2-js #title-bar #option { + width: 100%; + height: 100%; +} + +#winamp2-js #title-bar #option-context { left: 6px; } #winamp2-js #title-bar #minimize { diff --git a/js/actionTypes.js b/js/actionTypes.js index 50edef2b..1bedbbbc 100644 --- a/js/actionTypes.js +++ b/js/actionTypes.js @@ -1,7 +1,5 @@ export const LOAD_AUDIO_URL = "LOAD_AUDIO_URL"; export const LOAD_AUDIO_FILE = "LOAD_AUDIO_FILE"; -export const CLOSE_CONTEXT_MENU = "CLOSE_CONTEXT_MENU"; -export const CLOSE_PRESETS_CONTEXT_MENU = "CLOSE_PRESETS_CONTEXT_MENU"; export const CLOSE_WINAMP = "CLOSE_WINAMP"; export const CLOSE_EQUALIZER_WINDOW = "CLOSE_EQUALIZER_WINDOW"; export const IS_PLAYING = "IS_PLAYING"; @@ -24,8 +22,6 @@ export const START_WORKING = "START_WORKING"; export const STEP_MARQUEE = "STEP_MARQUEE"; export const STOP = "STOP"; export const STOP_WORKING = "STOP_WORKING"; -export const TOGGLE_CONTEXT_MENU = "TOGGLE_CONTEXT_MENU"; -export const TOGGLE_PRESETS_CONTEXT_MENU = "TOGGLE_PRESET_CONTEXT_MENU"; export const TOGGLE_DOUBLESIZE_MODE = "TOGGLE_DOUBLESIZE_MODE"; export const TOGGLE_EQUALIZER_WINDOW = "TOGGLE_EQUALIZER_WINDOW"; export const TOGGLE_PLAYLIST_WINDOW = "TOGGLE_PLAYLIST_WINDOW"; diff --git a/js/components/ContextMenu.js b/js/components/ContextMenu.js index a4d0fcac..1e53fbb2 100644 --- a/js/components/ContextMenu.js +++ b/js/components/ContextMenu.js @@ -37,28 +37,56 @@ Node.propTypes = { }; export class ContextMenu extends React.Component { - componentWillMount() { - // Clicking anywhere outside the context menu will close the window - document.addEventListener("click", this.props.closeMenu); + constructor(props) { + super(props); + this.state = { selected: false }; + this._handleHandleClick = this._handleHandleClick.bind(this); + this._handleGlobalClick = this._handleGlobalClick.bind(this); } - componantWillUnmount() { - document.removeEventListener("click", this.props.closeMenu); + componentDidMount() { + document.addEventListener("click", this._handleGlobalClick); + } + + componentWillUnmount() { + document.removeEventListener("click", this._handleGlobalClick); + } + + _handleHandleClick() { + this.setState({ selected: !this.state.selected }); + } + + _handleGlobalClick(e) { + if (this.state.selected && !this.handleNode.contains(e.target)) { + this.setState({ selected: false }); + } } render() { - const { selected, top, bottom, children } = this.props; + const { handle, children, top, bottom, ...passThroughProps } = this.props; return ( -
- +
+
(this.handleNode = node)} + onClick={this._handleHandleClick} + > + {handle} +
+ {this.state.selected && ( +
+
    {children}
+
+ )}
); } } ContextMenu.propTypes = { - closeMenu: PropTypes.func.isRequired, children: PropTypes.any.isRequired, + handle: PropTypes.any.isRequired, top: PropTypes.bool, bottom: PropTypes.bool }; diff --git a/js/components/EqualizerWindow/PresetsContextMenu.js b/js/components/EqualizerWindow/PresetsContextMenu.js index 94d1252e..dacb9117 100644 --- a/js/components/EqualizerWindow/PresetsContextMenu.js +++ b/js/components/EqualizerWindow/PresetsContextMenu.js @@ -1,18 +1,16 @@ import React from "react"; import { connect } from "react-redux"; -import { CLOSE_PRESETS_CONTEXT_MENU } from "../../actionTypes"; import { openFileDialog, downloadPreset } from "../../actionCreators"; import { ContextMenu, Node } from "../ContextMenu"; const MainContextMenu = props => ( - + }> ); const mapDispatchToProps = (dispatch, ownProps) => ({ - closeMenu: () => dispatch({ type: CLOSE_PRESETS_CONTEXT_MENU }), openFileDialog: () => dispatch(openFileDialog(ownProps.fileInput)), downloadPreset: () => dispatch(downloadPreset()) }); diff --git a/js/components/EqualizerWindow/__snapshots__/index.test.js.snap b/js/components/EqualizerWindow/__snapshots__/index.test.js.snap index 3bee5f49..94edd992 100644 --- a/js/components/EqualizerWindow/__snapshots__/index.test.js.snap +++ b/js/components/EqualizerWindow/__snapshots__/index.test.js.snap @@ -35,28 +35,21 @@ exports[`EqualizerWindow renders to snapshot 1`] = ` width="152" />
-
    -
  • - Load -
  • -
  • - Save -
  • -
+
{ -
- -
+
@@ -109,12 +101,6 @@ const mapDispatchToProps = dispatch => ({ setEqToMid: () => dispatch(setEqToMid()), setEqToMax: () => dispatch(setEqToMax()), setHertzValue: hertz => value => dispatch(setEqBand(hertz, value)), - togglePresetsContextMenu: e => { - dispatch({ type: TOGGLE_PRESETS_CONTEXT_MENU }); - // TODO: Consider binding to a ref instead. - // https://stackoverflow.com/a/24421834 - e.nativeEvent.stopImmediatePropagation(); - }, closeEqualizerWindow: () => dispatch(closeEqualizerWindow()), toggleEqualizerShadeMode: () => dispatch(toggleEqualizerShadeMode()) }); @@ -122,7 +108,6 @@ const mapDispatchToProps = dispatch => ({ const mapStateToProps = state => ({ doubled: state.display.doubled, selected: state.windows.focused === WINDOWS.EQUALIZER, - contextMenuSelected: state.presetsContextMenu.selected, shade: state.display.equalizerShade, volume: state.media.volume, balance: state.media.balance diff --git a/js/components/MainWindow/MainContextMenu.js b/js/components/MainWindow/MainContextMenu.js index e29fc705..d47b6021 100644 --- a/js/components/MainWindow/MainContextMenu.js +++ b/js/components/MainWindow/MainContextMenu.js @@ -1,6 +1,5 @@ import React from "react"; import { connect } from "react-redux"; -import { CLOSE_CONTEXT_MENU, TOGGLE_CONTEXT_MENU } from "../../actionTypes"; import { close, setSkinFromFilename, @@ -19,10 +18,9 @@ const SKINS = [ const MainContextMenu = props => ( } > ( const mapDispatchToProps = (dispatch, ownProps) => ({ close: () => dispatch(close()), - closeMenu: () => { - dispatch({ type: CLOSE_CONTEXT_MENU }); - }, - openMenu: () => { - dispatch({ type: TOGGLE_CONTEXT_MENU }); - }, openFileDialog: () => dispatch(openFileDialog(ownProps.fileInput)), setSkin: filename => dispatch(setSkinFromFilename(filename)) }); -export default connect( - state => ({ selected: state.contextMenu.selected }), - mapDispatchToProps -)(MainContextMenu); +export default connect(null, mapDispatchToProps)(MainContextMenu); diff --git a/js/components/MainWindow/__snapshots__/index.test.js.snap b/js/components/MainWindow/__snapshots__/index.test.js.snap index 5aeb56a7..75fdd99f 100644 --- a/js/components/MainWindow/__snapshots__/index.test.js.snap +++ b/js/components/MainWindow/__snapshots__/index.test.js.snap @@ -14,102 +14,22 @@ exports[`MainWindow renders to snapshot 1`] = ` id="title-bar" >
-
    -
  • - - Winamp2-js - -
  • -
  • -
    -
  • -
  • - Play File... -
  • -
  • -
      -
    • - Load Skin... -
    • -
    • -
      -
    • -
    • - <Base Skin> -
    • -
    • - Mac OSX v1.5 (Aqua) -
    • -
    • - TopazAmp -
    • -
    • - Vizor -
    • -
    • - XMMS Turquoise -
    • -
    • - Zaxon Remake -
    • -
    - Skins -
  • -
  • -
    -
  • -
  • - Exit -
  • -
+
-
- -
+ {shade && }
@@ -148,12 +146,8 @@ const mapStateToProps = state => { }; const mapDispatchToProps = dispatch => ({ - toggleMenu: e => { - dispatch({ type: TOGGLE_CONTEXT_MENU }); - // TODO: Consider binding to a ref instead. - // https://stackoverflow.com/a/24421834 - e.nativeEvent.stopImmediatePropagation(); - }, - dispatch + setFocus: () => { + dispatch({ type: SET_FOCUSED_WINDOW, window: WINDOWS.MAIN }); + } }); export default connect(mapStateToProps, mapDispatchToProps)(MainWindow); diff --git a/js/reducers.js b/js/reducers.js index 9042f017..222d30cb 100644 --- a/js/reducers.js +++ b/js/reducers.js @@ -1,8 +1,6 @@ import { combineReducers } from "redux"; import { BANDS, WINDOWS } from "./constants"; import { - CLOSE_CONTEXT_MENU, - CLOSE_PRESETS_CONTEXT_MENU, CLOSE_WINAMP, SET_BALANCE, SET_BAND_VALUE, @@ -17,8 +15,6 @@ import { START_WORKING, STEP_MARQUEE, STOP_WORKING, - TOGGLE_CONTEXT_MENU, - TOGGLE_PRESETS_CONTEXT_MENU, TOGGLE_DOUBLESIZE_MODE, TOGGLE_EQUALIZER_WINDOW, CLOSE_EQUALIZER_WINDOW, @@ -137,37 +133,6 @@ const display = (state = defaultDisplayState, action) => { } }; -const defaultContextMenuState = { - selected: false -}; - -const contextMenu = (state = defaultContextMenuState, action) => { - switch (action.type) { - case TOGGLE_CONTEXT_MENU: - return { ...state, selected: !state.selected }; - case CLOSE_CONTEXT_MENU: - return { ...state, selected: false }; - default: - return state; - } -}; - -const presetsContextMenu = (state, action) => { - if (!state) { - return { - selected: false - }; - } - switch (action.type) { - case TOGGLE_PRESETS_CONTEXT_MENU: - return { ...state, selected: !state.selected }; - case CLOSE_PRESETS_CONTEXT_MENU: - return { ...state, selected: false }; - default: - return state; - } -}; - const equalizer = (state, action) => { if (!state) { state = { @@ -255,8 +220,6 @@ const reducer = combineReducers({ userInput, windows, display, - contextMenu, - presetsContextMenu, equalizer, media });