aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/Platform.h
blob: 500c71de3ec02be99d7aa42dc745cb718d6d1340 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
// Scintilla source code edit control
/** @file Platform.h
 ** Interface to platform facilities. Also includes some basic utilities.
 ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef PLATFORM_H
#define PLATFORM_H

// PLAT_GTK = GTK+ on Linux, PLAT_WIN = Win32 API on Win32 OS
// PLAT_WX is wxWindows on any supported platform
// Could also have PLAT_GTKWIN = GTK+ on Win32 OS in future

#define PLAT_GTK 0
#define PLAT_WIN 0
#define PLAT_WX  0

#if defined(__WX__)
#undef PLAT_WX
#define PLAT_WX  1

#elif defined(GTK)
#undef PLAT_GTK
#define PLAT_GTK 1

#else
#undef PLAT_WIN
#define PLAT_WIN 1

#endif


// Include the main header for each platform

#if PLAT_GTK
#ifdef _MSC_VER
#pragma warning(disable: 4505 4514 4710 4800)
#endif
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#endif

#if PLAT_WIN
#define _WIN32_WINNT  0x0400 // Otherwise some required stuff gets ifdef'd out
// Vassili Bourdo: shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4244 4309 4710 4800)
#endif
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#endif

#if PLAT_WX
#include <wx/wx.h>
#endif

// Underlying the implementation of the platform classes are platform specific types.
// Sometimes these need to be passed around by client code so they are defined here

#if PLAT_GTK
typedef GdkColor ColourID;
typedef GdkFont* FontID;
typedef GdkDrawable* SurfaceID;
typedef GtkWidget* WindowID;
typedef GtkItemFactory* MenuID;
#endif

#if PLAT_WIN
typedef COLORREF ColourID;
typedef HFONT FontID;
typedef HDC SurfaceID;
typedef HWND WindowID;
typedef HMENU MenuID;
#endif

#if PLAT_WX
typedef wxColour ColourID;
typedef wxFont* FontID;
typedef wxDC* SurfaceID;
typedef wxWindow* WindowID;
typedef wxMenu* MenuID;
#endif

/**
 * A geometric point class.
 * Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably.
 */
class Point {
public:
	int x;
	int y;

	Point(int x_=0, int y_=0) : x(x_), y(y_) {
	}

	// Other automatically defined methods (assignment, copy constructor, destructor) are fine

	static Point FromLong(long lpoint);
};

/**
 * A geometric rectangle class.
 * PRectangle is exactly the same as the Win32 RECT so can be used interchangeably.
 * PRectangles contain their top and left sides, but not their right and bottom sides.
 */
class PRectangle {
public:
	int left;
	int top;
	int right;
	int bottom;

	PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) :
		left(left_), top(top_), right(right_), bottom(bottom_) {
	}

	// Other automatically defined methods (assignment, copy constructor, destructor) are fine

	bool operator==(PRectangle &rc) {
		return (rc.left == left) && (rc.right == right) &&
			(rc.top == top) && (rc.bottom == bottom);
	}
	bool Contains(Point pt) {
		return (pt.x >= left) && (pt.x <= right) &&
			(pt.y >= top) && (pt.y <= bottom);
	}
	bool Contains(PRectangle rc) {
		return (rc.left >= left) && (rc.right <= right) &&
			(rc.top >= top) && (rc.bottom <= bottom);
	}
	bool Intersects(PRectangle other) {
		return (right >= other.left) && (left <= other.right) &&
			(bottom >= other.top) && (top <= other.bottom);
	}
	int Width() { return right - left; }
	int Height() { return bottom - top; }
};

#if PLAT_WX
wxRect wxRectFromPRectangle(PRectangle prc);
PRectangle PRectangleFromwxRect(wxRect rc);
#endif

/**
 * A colour class.
 */
class Colour {
	ColourID co;
public:
	Colour(long lcol=0);
	Colour(unsigned int red, unsigned int green, unsigned int blue);
	bool operator==(const Colour &other) const;
	long AsLong() const;
	unsigned int GetRed();
	unsigned int GetGreen();
	unsigned int GetBlue();

	friend class Surface;
	friend class Palette;
};

/**
 * Colour pairs hold a desired colour and the colour that the graphics engine
 * allocates to approximate the desired colour.
 * To make palette management more automatic, ColourPairs could register at
 * construction time with a palette management object.
 */
struct ColourPair {
	Colour desired;
	Colour allocated;

	ColourPair(Colour desired_=Colour(0,0,0)) {
		desired = desired_;
		allocated = desired;
	}
};

class Window;	// Forward declaration for Palette

/**
 * Colour palette management.
 */
class Palette {
	int used;
	enum {numEntries = 100};
	ColourPair entries[numEntries];
#if PLAT_GTK
	GdkColor *allocatedPalette;
	int allocatedLen;
#elif PLAT_WIN
	HPALETTE hpal;
#elif PLAT_WX
	// wxPalette* pal;  // **** Is this needed?
#endif
public:
	bool allowRealization;

	Palette();
	~Palette();

	void Release();

	/**
	 * This method either adds a colour to the list of wanted colours (want==true)
	 * or retrieves the allocated colour back to the ColourPair.
	 * This is one method to make it easier to keep the code for wanting and retrieving in sync.
	 */
	void WantFind(ColourPair &cp, bool want);

	void Allocate(Window &w);

	friend class Surface;
};

/**
 * Font management.
 */
class Font {
protected:
	FontID id;
#if PLAT_WX
	int ascent;
#endif
	// Private so Font objects can not be copied
	Font(const Font &) {}
	Font &operator=(const Font &) { id=0; return *this; }
public:
	Font();
	virtual ~Font();

	virtual void Create(const char *faceName, int characterSet, int size, bool bold, bool italic);
	virtual void Release();

	FontID GetID() { return id; }
	// Alias another font - caller guarantees not to Release
	void SetID(FontID id_) { id = id_; }
	friend class Surface;
};

/**
 * A surface abstracts a place to draw.
 */
class Surface {
private:
	bool unicodeMode;
#if PLAT_GTK
	GdkDrawable *drawable;
	GdkGC *gc;
	GdkPixmap *ppixmap;
	int x;
	int y;
	bool inited;
	bool createdGC;
#elif PLAT_WIN
	HDC hdc;
	bool hdcOwned;
	HPEN pen;
	HPEN penOld;
	HBRUSH brush;
	HBRUSH brushOld;
	HFONT font;
	HFONT fontOld;
	HBITMAP bitmap;
	HBITMAP bitmapOld;
	HPALETTE paletteOld;
#elif PLAT_WX
	wxDC* hdc;
	bool hdcOwned;
	wxBitmap* bitmap;
	int x;
	int y;
#endif

	// Private so Surface objects can not be copied
	Surface(const Surface &) {}
	Surface &operator=(const Surface &) { return *this; }
#if PLAT_WIN || PLAT_WX
	void BrushColor(Colour back);
	void SetFont(Font &font_);
#endif
public:
	Surface();
	~Surface();

	void Init();
	void Init(SurfaceID hdc_);
	void InitPixMap(int width, int height, Surface *surface_);

	void Release();
	bool Initialised();
	void PenColour(Colour fore);
	int LogPixelsY();
	int DeviceHeightFont(int points);
	void MoveTo(int x_, int y_);
	void LineTo(int x_, int y_);
	void Polygon(Point *pts, int npts, Colour fore, Colour back);
	void RectangleDraw(PRectangle rc, Colour fore, Colour back);
	void FillRectangle(PRectangle rc, Colour back);
	void FillRectangle(PRectangle rc, Surface &surfacePattern);
	void RoundedRectangle(PRectangle rc, Colour fore, Colour back);
	void Ellipse(PRectangle rc, Colour fore, Colour back);
	void Copy(PRectangle rc, Point from, Surface &surfaceSource);

	void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, Colour fore, Colour back);
	void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, Colour fore, Colour back);
	void MeasureWidths(Font &font_, const char *s, int len, int *positions);
	int WidthText(Font &font_, const char *s, int len);
	int WidthChar(Font &font_, char ch);
	int Ascent(Font &font_);
	int Descent(Font &font_);
	int InternalLeading(Font &font_);
	int ExternalLeading(Font &font_);
	int Height(Font &font_);
	int AverageCharWidth(Font &font_);

	int SetPalette(Palette *pal, bool inBackGround);
	void SetClip(PRectangle rc);
	void FlushCachedState();

	void SetUnicodeMode(bool unicodeMode_) {
		unicodeMode=unicodeMode_;
	}
};

/**
 * Class to hide the details of window manipulation.
 * Does not own the window which will normally have a longer life than this object.
 */
class Window {
	friend class ListBox;
protected:
	WindowID id;
public:
	Window() : id(0) {}
	Window(const Window &source) : id(source.id) {}
	virtual ~Window();
	Window &operator=(WindowID id_) {
		id = id_;
		return *this;
	}
	WindowID GetID() { return id; }
	bool Created() { return id != 0; }
	void Destroy();
	bool HasFocus();
	PRectangle GetPosition();
	void SetPosition(PRectangle rc);
	void SetPositionRelative(PRectangle rc, Window relativeTo);
	PRectangle GetClientPosition();
	void Show(bool show=true);
	void InvalidateAll();
	void InvalidateRectangle(PRectangle rc);
	virtual void SetFont(Font &font);
	enum Cursor { cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow };
	void SetCursor(Cursor curs);
	void SetTitle(const char *s);
#if PLAT_WIN
	LRESULT SendMessage(UINT msg, WPARAM wParam=0, LPARAM lParam=0);
	int GetDlgCtrlID();
	HINSTANCE GetInstance();
#endif
};

/**
 * Listbox management.
 */
class ListBox : public Window {
#if PLAT_GTK
	WindowID list;
	WindowID scroller;
	int current;
#endif
	int desiredVisibleRows;
	unsigned int maxItemCharacters;
	unsigned int aveCharWidth;
public:
	ListBox();
	virtual ~ListBox();
	void Create(Window &parent, int ctrlID);
	virtual void SetFont(Font &font);
	void SetAverageCharWidth(int width);
	void SetVisibleRows(int rows);
	PRectangle GetDesiredRect();
	void Clear();
	void Append(char *s);
	int Length();
	void Select(int n);
	int GetSelection();
	int Find(const char *prefix);
	void GetValue(int n, char *value, int len);
	void Sort();
};

/**
 * Menu management.
 */
class Menu {
	MenuID id;
public:
	Menu();
	MenuID GetID() { return id; }
	void CreatePopUp();
	void Destroy();
	void Show(Point pt, Window &w);
};

/**
 * Platform class used to retrieve system wide parameters such as double click speed
 * and chrome colour. Not a creatable object, more of a module with several functions.
 */
class Platform {
	// Private so Platform objects can not be copied
	Platform(const Platform &) {}
	Platform &operator=(const Platform &) { return *this; }
public:
	// Should be private because no new Platforms are ever created
	// but gcc warns about this
	Platform() {}
	~Platform() {}
	static Colour Chrome();
	static Colour ChromeHighlight();
	static const char *DefaultFont();
	static int DefaultFontSize();
	static unsigned int DoubleClickTime();
	static void DebugDisplay(const char *s);
	static bool IsKeyDown(int key);
	static long SendScintilla(
		WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0);

	// These are utility functions not really tied to a platform
	static int Minimum(int a, int b);
	static int Maximum(int a, int b);
	// Next three assume 16 bit shorts and 32 bit longs
	static long LongFromTwoShorts(short a,short b) {
		return (a) | ((b) << 16);
	}
	static short HighShortFromLong(long x) {
		return static_cast<short>(x >> 16);
	}
	static short LowShortFromLong(long x) {
		return static_cast<short>(x & 0xffff);
	}
	static void DebugPrintf(const char *format, ...);
	static bool ShowAssertionPopUps(bool assertionPopUps_);
	static void Assert(const char *c, const char *file, int line);
	static int Clamp(int val, int minVal, int maxVal);
};

#ifdef  NDEBUG
#define PLATFORM_ASSERT(c) ((void)0)
#else
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__))
#endif

#endif