1#include <stdio.h>
2
3#include <Application.h>
4#include <Region.h>
5#include <View.h>
6#include <Window.h>
7
8enum {
9	MSG_REDRAW = 'shhd'
10};
11
12#define TEST_DELAYS 0
13
14class View : public BView {
15public:
16	View(BRect frame, uint8 r, uint8 g, uint8 b, uint8 a)
17		: BView(frame, "view", B_FOLLOW_ALL, B_WILL_DRAW)
18	{
19		SetDrawingMode(B_OP_ALPHA);
20		SetHighColor(r, g, b, a);
21	}
22
23	virtual void Draw(BRect updateRect)
24	{
25		BRegion region;
26		GetClippingRegion(&region);
27		BMessage message(MSG_REDRAW);
28		int32 count = region.CountRects();
29		for (int32 i = 0; i < count; i++)
30			message.AddRect("rect", region.RectAt(i));
31		be_app->PostMessage(&message);
32	}
33
34	void AsyncRedraw(BRegion& region)
35	{
36		if (!LockLooper())
37			return;
38
39#if 0
40		ConstrainClippingRegion(&region);
41		FillRect(Bounds());
42		ConstrainClippingRegion(NULL);
43#else
44		PushState();
45		ConstrainClippingRegion(&region);
46		FillRect(Bounds());
47		PopState();
48#endif
49
50		UnlockLooper();
51	}
52};
53
54
55class Application : public BApplication {
56public:
57	Application()
58		: BApplication("application/x-vnd.stippi-async.drawing")
59		, fDelay(true)
60	{
61		BWindow* window = new BWindow(BRect(50, 50, 350, 250),
62			"Test Window", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
63			B_QUIT_ON_WINDOW_CLOSE);
64		fView = new View(window->Bounds(), 255, 80, 155, 128);
65		window->AddChild(fView);
66		window->Show();
67
68		window = new BWindow(BRect(150, 150, 450, 350),
69			"Drag Window", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
70			B_QUIT_ON_WINDOW_CLOSE);
71		window->Show();
72
73		SetPulseRate(100000);
74	}
75
76	virtual void Pulse()
77	{
78		fDelay = true;
79	}
80
81	virtual void MessageReceived(BMessage* message)
82	{
83		switch (message->what) {
84			case MSG_REDRAW:
85			{
86#if TEST_DELAYS
87				if (fDelay) {
88					snooze(200000);
89					fDelay = false;
90				}
91#endif
92				BRegion region;
93				BRect rect;
94				for (int32 i = 0;
95					message->FindRect("rect", i, &rect) == B_OK; i++)
96					region.Include(rect);
97				fView->AsyncRedraw(region);
98				break;
99			}
100
101			default:
102				BApplication::MessageReceived(message);
103				break;
104		}
105	}
106private:
107	View*		fView;
108	bool		fDelay;
109};
110
111
112int
113main(int argc, char* argv[])
114{
115	Application app;
116	app.Run();
117	return 0;
118}
119
120
121