mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-11-04 00:16:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			92 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
//  Keyboard.hpp
 | 
						|
//  Clock Signal
 | 
						|
//
 | 
						|
//  Created by Thomas Harte on 10/9/17.
 | 
						|
//  Copyright 2017 Thomas Harte. All rights reserved.
 | 
						|
//
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <vector>
 | 
						|
#include <set>
 | 
						|
 | 
						|
namespace Inputs {
 | 
						|
 | 
						|
/*!
 | 
						|
	Provides an intermediate idealised model of a modern-era computer keyboard
 | 
						|
	(so, heavily indebted to the current Windows and Mac layouts), allowing a host
 | 
						|
	machine to toggle states, while an interested party either observes or polls.
 | 
						|
*/
 | 
						|
class Keyboard {
 | 
						|
public:
 | 
						|
	enum class Key {
 | 
						|
		Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PrintScreen, ScrollLock, Pause,
 | 
						|
		BackTick, k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, Hyphen, Equals, Backspace,
 | 
						|
		Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, Backslash,
 | 
						|
		CapsLock, A, S, D, F, G, H, J, K, L, Semicolon, Quote, Hash, Enter,
 | 
						|
		LeftShift, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift,
 | 
						|
		LeftControl, LeftOption, LeftMeta, Space, RightMeta, RightOption, RightControl,
 | 
						|
		Left, Right, Up, Down,
 | 
						|
		Insert, Home, PageUp, Delete, End, PageDown,
 | 
						|
		NumLock, KeypadSlash, KeypadAsterisk, KeypadDelete,
 | 
						|
		Keypad7, Keypad8, Keypad9, KeypadPlus,
 | 
						|
		Keypad4, Keypad5, Keypad6, KeypadMinus,
 | 
						|
		Keypad1, Keypad2, Keypad3, KeypadEnter,
 | 
						|
		Keypad0, KeypadDecimalPoint, KeypadEquals,
 | 
						|
		Help,
 | 
						|
 | 
						|
		Max = Help
 | 
						|
	};
 | 
						|
 | 
						|
	/// Constructs a Keyboard that declares itself to observe all keys.
 | 
						|
	Keyboard(const std::set<Key> &essential_modifiers = {});
 | 
						|
 | 
						|
	/// Constructs a Keyboard that declares itself to observe only members of @c observed_keys.
 | 
						|
	Keyboard(const std::set<Key> &observed_keys, const std::set<Key> &essential_modifiers);
 | 
						|
 | 
						|
	virtual ~Keyboard() = default;
 | 
						|
 | 
						|
	// Host interface.
 | 
						|
 | 
						|
	/// @returns @c true if the key press affects the machine; @c false otherwise.
 | 
						|
	virtual bool set_key_pressed(Key key, char value, bool is_pressed, bool is_repeat);
 | 
						|
	virtual void reset_all_keys();
 | 
						|
 | 
						|
	/// @returns a set of all Keys that this keyboard responds to.
 | 
						|
	virtual const std::set<Key> &observed_keys() const;
 | 
						|
 | 
						|
	/// @returns the list of modifiers that this keyboard considers 'essential' (i.e. both mapped and highly used).
 | 
						|
	virtual const std::set<Inputs::Keyboard::Key> &get_essential_modifiers() const;
 | 
						|
 | 
						|
	/*!
 | 
						|
		@returns @c true if this keyboard, on its original machine, looked
 | 
						|
		like a complete keyboard — i.e. if a user would expect this keyboard
 | 
						|
		to be the only thing a real keyboard maps to.
 | 
						|
 | 
						|
		So this would be true of something like the Amstrad CPC, which has a full
 | 
						|
		keyboard, but it would be false of something like the Sega Master System
 | 
						|
		which has some buttons that you'd expect an emulator to map to its host
 | 
						|
		keyboard but which does not offer a full keyboard.
 | 
						|
	*/
 | 
						|
	virtual bool is_exclusive() const;
 | 
						|
 | 
						|
	// Delegate interface.
 | 
						|
	struct Delegate {
 | 
						|
		virtual bool keyboard_did_change_key(Keyboard &, Key, bool is_pressed) = 0;
 | 
						|
		virtual void reset_all_keys(Keyboard &) = 0;
 | 
						|
	};
 | 
						|
	void set_delegate(Delegate *);
 | 
						|
	bool get_key_state(Key) const;
 | 
						|
 | 
						|
private:
 | 
						|
	std::set<Key> observed_keys_;
 | 
						|
	const std::set<Key> essential_modifiers_;
 | 
						|
	const bool is_exclusive_ = true;
 | 
						|
 | 
						|
	std::vector<bool> key_states_;
 | 
						|
	Delegate *delegate_ = nullptr;
 | 
						|
};
 | 
						|
 | 
						|
}
 |