blob: a15b03ba15041a6b056e6751fa03e70e53610dd1 [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001//
2// Copyright 2005 The Android Open Source Project
3//
4// Displays output from the device.
5//
6
7// For compilers that support precompilation, include "wx/wx.h".
8#include "wx/wxprec.h"
9
10// Otherwise, include all standard headers
11#ifndef WX_PRECOMP
12# include "wx/wx.h"
13#endif
14#include "wx/image.h" // needed for Windows build
15#include "wx/dcbuffer.h"
16
17#include "AssetStream.h"
18#include "DeviceWindow.h"
19#include "MyApp.h"
20#include "Preferences.h"
21
22BEGIN_EVENT_TABLE(DeviceWindow, wxWindow)
23 EVT_SIZE(DeviceWindow::OnSize)
24 EVT_ERASE_BACKGROUND(DeviceWindow::OnErase)
25 EVT_PAINT(DeviceWindow::OnPaint)
26 EVT_KEY_DOWN(DeviceWindow::OnKeyDown)
27 EVT_KEY_UP(DeviceWindow::OnKeyUp)
28
29 EVT_LEFT_DOWN(DeviceWindow::OnMouseLeftDown)
30 EVT_LEFT_DCLICK(DeviceWindow::OnMouseLeftDown)
31 EVT_LEFT_UP(DeviceWindow::OnMouseLeftUp)
32 EVT_RIGHT_DOWN(DeviceWindow::OnMouseRightDown)
33 EVT_RIGHT_DCLICK(DeviceWindow::OnMouseRightDown)
34 EVT_RIGHT_UP(DeviceWindow::OnMouseRightUp)
35 EVT_MOTION(DeviceWindow::OnMouseMotion)
36
37 EVT_USER_EVENT(DeviceWindow::OnUserEvent)
38END_EVENT_TABLE()
39
40
41/*
42 * Create a new DeviceWindow. This should be a child of PhoneWindow.
43 *
44 * Note the DeviceManager may not be fully initialized yet.
45 */
46DeviceWindow::DeviceWindow(wxWindow* parent, DeviceManager* pDM)
47 : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
48 wxNO_BORDER | wxWANTS_CHARS),
49 mpDeviceManager(pDM)
50{
51 //printf("DW: created (parent=%p DM=%p)\n", parent, pDM);
52
53 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
54
55 // create a trivial bitmap so we have something allocated
56 mBitmap.Create(1, 1);
57
58}
59
60/*
61 * Destructor.
62 */
63DeviceWindow::~DeviceWindow(void)
64{
65}
66
67/*
68 * We don't want to trap key or mouse events here.
69 *
70 * event.Skip() didn't seem to do the trick, so we call AddPendingEvent()
71 * to add it to the parent's input queue.
72 */
73void DeviceWindow::OnKeyDown(wxKeyEvent& event)
74{
75 //printf("DW: down: %d\n", event.GetKeyCode());
76 GetParent()->AddPendingEvent(event);
77}
78void DeviceWindow::OnKeyUp(wxKeyEvent& event)
79{
80 //printf("DW: up: %d\n", event.GetKeyCode());
81 GetParent()->AddPendingEvent(event);
82}
83
84/*
85 * Handle mouse events. We want to pass these up to the PhoneWindow, since
86 * that's where the "touch screen" code is.
87 */
88void DeviceWindow::OnMouseLeftDown(wxMouseEvent& event)
89{
90 ClampMouse(&event);
91 GetParent()->AddPendingEvent(event);
92}
93void DeviceWindow::OnMouseLeftUp(wxMouseEvent& event)
94{
95 ClampMouse(&event);
96 GetParent()->AddPendingEvent(event);
97}
98void DeviceWindow::OnMouseRightDown(wxMouseEvent& event)
99{
100 ClampMouse(&event);
101 GetParent()->AddPendingEvent(event);
102}
103void DeviceWindow::OnMouseRightUp(wxMouseEvent& event)
104{
105 ClampMouse(&event);
106 GetParent()->AddPendingEvent(event);
107}
108void DeviceWindow::OnMouseMotion(wxMouseEvent& event)
109{
110 ClampMouse(&event);
111 GetParent()->AddPendingEvent(event);
112}
113
114/*
115 * Clamp the mouse movement to the window bounds.
116 */
117void DeviceWindow::ClampMouse(wxMouseEvent* pEvent)
118{
119 wxWindow* pEventWindow = (wxWindow*) pEvent->GetEventObject();
120 int width, height;
121
122 pEventWindow->GetSize(&width, &height);
123 if (pEvent->m_x < 0)
124 pEvent->m_x = 0;
125 else if (pEvent->m_x >= width)
126 pEvent->m_x = width-1;
127
128 if (pEvent->m_y < 0)
129 pEvent->m_y = 0;
130 else if (pEvent->m_y >= height)
131 pEvent->m_y = height-1;
132}
133
134
135/*
136 * Handle a "user event". We get these when the runtime wants us to
137 * know that it has a new frame of graphics to display.
138 *
139 */
140void DeviceWindow::OnUserEvent(UserEvent& event)
141{
142 wxBitmap* pBitmap;
143 long displayIndex;
144
145 displayIndex = (long) event.GetData();
146
147 //printf("GOT UAE %d\n", displayIndex);
148
149 // a displayIndex of -1 means just update the onion skin
150 if (displayIndex >= 0) {
151 /* get a newly-allocated bitmap with converted image data */
152 pBitmap = mpDeviceManager->GetImageData(displayIndex);
153
154 /* do a ptr/refcount assignment to hold the data */
155 mBitmap = *pBitmap;
156 /* delete the temporary object; does not delete the bitmap storage */
157 delete pBitmap;
158 }
159
160 if (displayIndex >= -1) {
161 mHasOnionSkinBitmap = false;
162
163 Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs();
164 assert(pPrefs != NULL);
165
166 bool overlayOnionSkin;
167 char* onionSkinFileName = NULL;
168
169 bool overlayOnionSkinExists = pPrefs->GetBool("overlay-onion-skin", &overlayOnionSkin);
170 if (overlayOnionSkinExists && overlayOnionSkin) {
171 bool fileNameExists = pPrefs->GetString("onion-skin-file-name", &onionSkinFileName);
172 if (fileNameExists && *onionSkinFileName) {
173 wxImage onionSkinImage(wxString::FromAscii(onionSkinFileName));
174 onionSkinImage.SetAlpha(NULL);
Patrick Scotted149c22010-10-08 10:11:04 -0400175 bool hasAlpha = onionSkinImage.HasAlpha();
The Android Open Source Project52d4c302009-03-03 19:29:09 -0800176 int width = onionSkinImage.GetWidth();
177 int height = onionSkinImage.GetHeight();
178 if (hasAlpha) {
179 unsigned char *alpha = onionSkinImage.GetAlpha();
180 int alphaVal = 127;
181 pPrefs->GetInt("onion-skin-alpha-value", &alphaVal);
182 for (int i = (width * height) - 1; i >= 0; i--) {
183 alpha[i] = alphaVal;
184 }
185 }
186 mOnionSkinBitmap = wxBitmap(onionSkinImage);
187 mHasOnionSkinBitmap = true;
188 }
189 }
190 }
191
192 /* induce an update */
193 Refresh();
194}
195
196/*
197 * Window has been moved or resized.
198 *
199 * We get this when the model of phone is changed.
200 *
201 * FIX: in the future this only happens when the phone is rotated 90deg.
202 */
203void DeviceWindow::OnSize(wxSizeEvent& WXUNUSED(event))
204{
205 int width, height;
206
207 GetClientSize(&width, &height);
208 printf("Sim: device window resize: %dx%d\n", width, height);
209
210 mBitmap.Create(width, height);
211
212 wxMemoryDC memDC;
213 memDC.SelectObject(mBitmap);
214
215 wxColour backColor(96, 122, 121);
216 memDC.SetBrush(wxBrush(backColor));
217 memDC.SetPen(wxPen(backColor, 1));
218 wxRect windowRect(wxPoint(0, 0), GetClientSize());
219 memDC.DrawRectangle(windowRect);
220}
221
222/*
223 * No need to erase the background.
224 */
225void DeviceWindow::OnErase(wxEraseEvent& WXUNUSED(event))
226{
227 //printf("erase device\n");
228}
229
230/*
231 * Repaint the simulator output.
232 */
233void DeviceWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
234{
235 wxPaintDC dc(this);
236
237 /* draw background image */
238 dc.DrawBitmap(mBitmap, 0, 0, TRUE);
239
240 /* If necessary, draw onion skin image on top */
241 if (mHasOnionSkinBitmap) {
242 dc.DrawBitmap(mOnionSkinBitmap, 0, 0, TRUE);
243 }
244
245#if 0
246 // debug - draw the corners
247 int xoff = 0;
248 int yoff = 0;
249 int width;
250 int height;
251 GetClientSize(&width, &height);
252
253 dc.SetPen(*wxGREEN_PEN);
254 dc.DrawLine(xoff, yoff+9, xoff, yoff);
255 dc.DrawLine(xoff, yoff, xoff+10, yoff);
256 dc.DrawLine(xoff+width-10, yoff, xoff+width, yoff);
257 dc.DrawLine(xoff+width-1, yoff, xoff+width-1, yoff+10);
258 dc.DrawLine(xoff, yoff+height-10, xoff, yoff+height);
259 dc.DrawLine(xoff, yoff+height-1, xoff+10, yoff+height-1);
260 dc.DrawLine(xoff+width-1, yoff+height-10, xoff+width-1, yoff+height);
261 dc.DrawLine(xoff+width-1, yoff+height-1, xoff+width-11, yoff+height-1);
262#endif
263}
264