1/*
2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef KEYBOARD_LAYOUT_H
6#define KEYBOARD_LAYOUT_H
7
8
9#include <map>
10
11#include <Entry.h>
12#include <ObjectList.h>
13#include <Point.h>
14#include <Rect.h>
15#include <String.h>
16
17
18enum key_shape {
19	kRectangleKeyShape,
20	kCircleKeyShape,
21	kEnterKeyShape
22};
23
24struct Key {
25	uint32		code;
26	uint32		alternate_code[3];
27	uint32		alternate_modifier[3];
28	key_shape	shape;
29	BRect		frame;
30	float		second_row;
31		// this is the width of the second row of a kEnterKeyShape key
32	bool		dark;
33};
34
35struct Indicator {
36	int32		modifier;
37	BRect		frame;
38};
39
40typedef std::map<BString, BString> VariableMap;
41
42class KeyboardLayout {
43public:
44							KeyboardLayout();
45							~KeyboardLayout();
46
47			const char*		Name();
48
49			int32			CountKeys();
50			Key*			KeyAt(int32 index);
51
52			int32			CountIndicators();
53			Indicator*		IndicatorAt(int32 index);
54
55			BRect			Bounds();
56			BSize			DefaultKeySize();
57			int32			IndexForModifier(int32 modifier);
58
59			status_t		Load(const char* path);
60			status_t		Load(entry_ref& ref);
61
62			void			SetDefault();
63			bool			IsDefault() const { return fIsDefault; }
64
65private:
66	enum parse_mode {
67		kPairs,
68		kSize,
69		kRowStart,
70		kKeyShape,
71		kKeyCodes
72	};
73	struct parse_state {
74		parse_mode	mode;
75		int32		line;
76	};
77
78			void			_FreeKeys();
79			void			_Error(const parse_state& state,
80								const char* reason, ...);
81			void			_AddAlternateKeyCode(Key* key, int32 modifier,
82								int32 code);
83			bool			_AddKey(const Key& key);
84			void			_SkipCommentsAndSpace(parse_state& state,
85								const char*& data);
86			void			_Trim(BString& string, bool stripComments);
87			bool			_GetPair(const parse_state& state,
88								const char*& data, BString& name,
89								BString& value);
90			bool			_AddKeyCodes(const parse_state& state,
91								BPoint& rowLeftTop, Key& key, const char* data,
92								int32& lastCount);
93			bool			_GetSize(const parse_state& state, const char* data,
94								float& x, float& y, float* _secondRow = NULL);
95			bool			_GetShape(const parse_state& state,
96								const char* data, Key& key);
97			const char*		_Delimiter(parse_mode mode);
98			bool			_GetTerm(const char*& data, const char* delimiter,
99								BString& term, bool closingBracketAllowed);
100			bool			_SubstituteVariables(BString& term,
101								VariableMap& variables, BString& unknown);
102			bool			_ParseTerm(const parse_state& state,
103								const char*& data, BString& term,
104								VariableMap& variables);
105
106			status_t		_InitFrom(const char* data);
107
108			BString			fName;
109			Key*			fKeys;
110			int32			fKeyCount;
111			int32			fKeyCapacity;
112			BRect			fBounds;
113			BSize			fDefaultKeySize;
114			int32			fAlternateIndex[3];
115			BObjectList<Indicator> fIndicators;
116			bool			fIsDefault;
117};
118
119#endif	// KEYBOARD_LAYOUT_H
120