mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
parent
c648735b8a
commit
9a940935af
@ -606,6 +606,9 @@ button:focus {
|
||||
padding: 0;
|
||||
margin-left: 10px;
|
||||
width: 42px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#reset:hover {
|
||||
@ -614,8 +617,11 @@ button:focus {
|
||||
}
|
||||
|
||||
#reset:active {
|
||||
background: #22150A;
|
||||
border: 5px outset #44372C;
|
||||
background-color: #22150A;
|
||||
border-left: 3px solid #44372C;
|
||||
border-top: 3px solid #44372C;
|
||||
border-right: 3px solid #000000;
|
||||
border-bottom: 3px solid #000000;
|
||||
}
|
||||
|
||||
#keyboard .key-OPEN_APPLE.active div {
|
||||
|
@ -49,8 +49,8 @@ export const Apple2 = (props: Apple2Props) => {
|
||||
...props,
|
||||
};
|
||||
const apple2 = new Apple2Impl(options);
|
||||
setApple2(apple2);
|
||||
apple2.ready.then(() => {
|
||||
setApple2(apple2);
|
||||
const io = apple2.getIO();
|
||||
const cpu = apple2.getCPU();
|
||||
setIO(io);
|
||||
|
51
js/components/AudioControl.tsx
Normal file
51
js/components/AudioControl.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { h } from 'preact';
|
||||
import { useCallback, useContext, useEffect, useState } from 'preact/hooks';
|
||||
import { ControlButton } from './ControlButton';
|
||||
import { OptionsContext } from './OptionsContext';
|
||||
import { Audio, SOUND_ENABLED_OPTION } from '../ui/audio';
|
||||
import { Apple2 as Apple2Impl } from '../apple2';
|
||||
|
||||
/**
|
||||
* AudioControl component properties.
|
||||
*/
|
||||
export interface AudioControlProps {
|
||||
apple2: Apple2Impl | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Control that instantiates the Audio object and provides
|
||||
* a control to mute and unmute audio.
|
||||
*
|
||||
* @param apple2 The Apple2 object
|
||||
* @returns AudioControl component
|
||||
*/
|
||||
export const AudioControl = ({ apple2 }: AudioControlProps) => {
|
||||
const [audioEnabled, setAudioEnabled] = useState(false);
|
||||
const [audio, setAudio] = useState<Audio>();
|
||||
const options = useContext(OptionsContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (apple2) {
|
||||
const io = apple2.getIO();
|
||||
const audio = new Audio(io);
|
||||
options.addOptions(audio);
|
||||
setAudio(audio);
|
||||
setAudioEnabled(audio.isEnabled());
|
||||
}
|
||||
}, [apple2]);
|
||||
|
||||
const doToggleSound = useCallback(() => {
|
||||
const on = !audio?.isEnabled();
|
||||
options.setOption(SOUND_ENABLED_OPTION, on);
|
||||
setAudioEnabled(on);
|
||||
}, [audio]);
|
||||
|
||||
return (
|
||||
<ControlButton
|
||||
onClick={doToggleSound}
|
||||
title="Toggle Sound"
|
||||
disabled={!audio}
|
||||
icon={audioEnabled ? 'volume-up' : 'volume-off'}
|
||||
/>
|
||||
);
|
||||
};
|
@ -6,6 +6,7 @@ import { h, JSX } from 'preact';
|
||||
export interface ControlButtonProps {
|
||||
icon: string;
|
||||
title: string;
|
||||
disabled?: boolean;
|
||||
onClick: JSX.MouseEventHandler<HTMLButtonElement>;
|
||||
}
|
||||
|
||||
@ -17,8 +18,8 @@ export interface ControlButtonProps {
|
||||
* @param onClick Click callback
|
||||
* @returns Control Button component
|
||||
*/
|
||||
export const ControlButton = ({ icon, title, onClick }: ControlButtonProps) => (
|
||||
<button onClick={onClick} title={title}>
|
||||
export const ControlButton = ({ icon, title, onClick, ...props }: ControlButtonProps) => (
|
||||
<button onClick={onClick} title={title} {...props} >
|
||||
<i class={`fas fa-${icon}`}></i>
|
||||
</button>
|
||||
);
|
||||
|
@ -3,11 +3,12 @@ import { useCallback, useContext, useEffect, useState } from 'preact/hooks';
|
||||
import { CPUMeter } from './CPUMeter';
|
||||
import { Inset } from './Inset';
|
||||
import { useHotKey } from './hooks/useHotKey';
|
||||
import { Apple2 as Apple2Impl } from '../apple2';
|
||||
import { Audio, SOUND_ENABLED_OPTION } from '../ui/audio';
|
||||
import { AudioControl } from './AudioControl';
|
||||
import { OptionsModal} from './OptionsModal';
|
||||
import { OptionsContext } from './OptionsContext';
|
||||
import { PauseControl } from './PauseControl';
|
||||
import { ControlButton } from './ControlButton';
|
||||
import { Apple2 as Apple2Impl } from '../apple2';
|
||||
import { JoyStick } from '../ui/joystick';
|
||||
import { Screen, SCREEN_FULL_PAGE } from '../ui/screen';
|
||||
import { System } from '../ui/system';
|
||||
@ -29,51 +30,25 @@ interface ControlStripProps {
|
||||
* @returns ControlStrip component
|
||||
*/
|
||||
export const ControlStrip = ({ apple2, e }: ControlStripProps) => {
|
||||
const [running, setRunning] = useState(true);
|
||||
const [audio, setAudio] = useState<Audio>();
|
||||
const [audioEnabled, setAudioEnabled] = useState(false);
|
||||
const [showOptions, setShowOptions] = useState(false);
|
||||
const options = useContext(OptionsContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (apple2) {
|
||||
apple2.ready.then(() => {
|
||||
const io = apple2.getIO();
|
||||
const vm = apple2.getVideoModes();
|
||||
const io = apple2.getIO();
|
||||
const vm = apple2.getVideoModes();
|
||||
|
||||
const system = new System(io, e);
|
||||
options.addOptions(system);
|
||||
const system = new System(io, e);
|
||||
options.addOptions(system);
|
||||
|
||||
const joystick = new JoyStick(io);
|
||||
options.addOptions(joystick);
|
||||
const joystick = new JoyStick(io);
|
||||
options.addOptions(joystick);
|
||||
|
||||
const screen = new Screen(vm);
|
||||
options.addOptions(screen);
|
||||
|
||||
const audio = new Audio(io);
|
||||
options.addOptions(audio);
|
||||
setAudio(audio);
|
||||
setAudioEnabled(audio.isEnabled());
|
||||
}).catch(console.error);
|
||||
const screen = new Screen(vm);
|
||||
options.addOptions(screen);
|
||||
}
|
||||
}, [apple2]);
|
||||
|
||||
const doPause = useCallback(() => {
|
||||
apple2?.stop();
|
||||
setRunning(false);
|
||||
}, [apple2]);
|
||||
|
||||
const doRun = useCallback(() => {
|
||||
apple2?.run();
|
||||
setRunning(true);
|
||||
}, [apple2]);
|
||||
|
||||
const doToggleSound = useCallback(() => {
|
||||
const on = !audio?.isEnabled();
|
||||
options.setOption(SOUND_ENABLED_OPTION, on);
|
||||
setAudioEnabled(on);
|
||||
}, [audio]);
|
||||
|
||||
const doReset = useCallback(() =>
|
||||
apple2?.reset()
|
||||
, [apple2]);
|
||||
@ -106,32 +81,16 @@ export const ControlStrip = ({ apple2, e }: ControlStripProps) => {
|
||||
<OptionsModal isOpen={showOptions} onClose={doCloseOptions} />
|
||||
<Inset>
|
||||
<CPUMeter apple2={apple2} />
|
||||
{running ? (
|
||||
<ControlButton
|
||||
onClick={doPause}
|
||||
title="Pause"
|
||||
icon="pause"
|
||||
/>
|
||||
) : (
|
||||
<ControlButton
|
||||
onClick={doRun}
|
||||
title="Run"
|
||||
icon="play"
|
||||
/>
|
||||
)}
|
||||
<ControlButton
|
||||
onClick={doToggleSound}
|
||||
title="Toggle Sound"
|
||||
icon={audioEnabled ? 'volume-up' : 'volume-off'}
|
||||
/>
|
||||
<PauseControl apple2={apple2} />
|
||||
<AudioControl apple2={apple2} />
|
||||
<div style={{flexGrow: 1}} />
|
||||
<ControlButton onClick={doReadme} title="About" icon="info" />
|
||||
<ControlButton onClick={doShowOptions} title="Options (F4)" icon="cog" />
|
||||
</Inset>
|
||||
{e && (
|
||||
<button id="reset" onClick={doReset}>
|
||||
<div id="reset" onClick={doReset}>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
51
js/components/PauseControl.tsx
Normal file
51
js/components/PauseControl.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { h, Fragment } from 'preact';
|
||||
import { useCallback, useState } from 'preact/hooks';
|
||||
import { Apple2 as Apple2Impl } from 'js/apple2';
|
||||
import { ControlButton } from './ControlButton';
|
||||
|
||||
/**
|
||||
* PauseControl component properties.
|
||||
*/
|
||||
export interface PauseControlProps {
|
||||
apple2: Apple2Impl | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a control to pause and unpause the CPU.
|
||||
*
|
||||
* @param apple2 The Apple2 object
|
||||
* @returns PauseControl component
|
||||
*/
|
||||
export const PauseControl = ({ apple2 }: PauseControlProps) => {
|
||||
const [running, setRunning] = useState(true);
|
||||
|
||||
const doPause = useCallback(() => {
|
||||
apple2?.stop();
|
||||
setRunning(false);
|
||||
}, [apple2]);
|
||||
|
||||
const doRun = useCallback(() => {
|
||||
apple2?.run();
|
||||
setRunning(true);
|
||||
}, [apple2]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{running ? (
|
||||
<ControlButton
|
||||
onClick={doPause}
|
||||
disabled={!apple2}
|
||||
title="Pause"
|
||||
icon="pause"
|
||||
/>
|
||||
) : (
|
||||
<ControlButton
|
||||
onClick={doRun}
|
||||
disabled={!apple2}
|
||||
title="Run"
|
||||
icon="play"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user