265 lines
7.3 KiB
C++
265 lines
7.3 KiB
C++
//
|
|
// Copyright 2005 The Android Open Source Project
|
|
//
|
|
// Displays output from the device.
|
|
//
|
|
|
|
// For compilers that support precompilation, include "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
// Otherwise, include all standard headers
|
|
#ifndef WX_PRECOMP
|
|
# include "wx/wx.h"
|
|
#endif
|
|
#include "wx/image.h" // needed for Windows build
|
|
#include "wx/dcbuffer.h"
|
|
|
|
#include "AssetStream.h"
|
|
#include "DeviceWindow.h"
|
|
#include "MyApp.h"
|
|
#include "Preferences.h"
|
|
|
|
BEGIN_EVENT_TABLE(DeviceWindow, wxWindow)
|
|
EVT_SIZE(DeviceWindow::OnSize)
|
|
EVT_ERASE_BACKGROUND(DeviceWindow::OnErase)
|
|
EVT_PAINT(DeviceWindow::OnPaint)
|
|
EVT_KEY_DOWN(DeviceWindow::OnKeyDown)
|
|
EVT_KEY_UP(DeviceWindow::OnKeyUp)
|
|
|
|
EVT_LEFT_DOWN(DeviceWindow::OnMouseLeftDown)
|
|
EVT_LEFT_DCLICK(DeviceWindow::OnMouseLeftDown)
|
|
EVT_LEFT_UP(DeviceWindow::OnMouseLeftUp)
|
|
EVT_RIGHT_DOWN(DeviceWindow::OnMouseRightDown)
|
|
EVT_RIGHT_DCLICK(DeviceWindow::OnMouseRightDown)
|
|
EVT_RIGHT_UP(DeviceWindow::OnMouseRightUp)
|
|
EVT_MOTION(DeviceWindow::OnMouseMotion)
|
|
|
|
EVT_USER_EVENT(DeviceWindow::OnUserEvent)
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
/*
|
|
* Create a new DeviceWindow. This should be a child of PhoneWindow.
|
|
*
|
|
* Note the DeviceManager may not be fully initialized yet.
|
|
*/
|
|
DeviceWindow::DeviceWindow(wxWindow* parent, DeviceManager* pDM)
|
|
: wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
|
wxNO_BORDER | wxWANTS_CHARS),
|
|
mpDeviceManager(pDM)
|
|
{
|
|
//printf("DW: created (parent=%p DM=%p)\n", parent, pDM);
|
|
|
|
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
|
|
|
// create a trivial bitmap so we have something allocated
|
|
mBitmap.Create(1, 1);
|
|
|
|
}
|
|
|
|
/*
|
|
* Destructor.
|
|
*/
|
|
DeviceWindow::~DeviceWindow(void)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* We don't want to trap key or mouse events here.
|
|
*
|
|
* event.Skip() didn't seem to do the trick, so we call AddPendingEvent()
|
|
* to add it to the parent's input queue.
|
|
*/
|
|
void DeviceWindow::OnKeyDown(wxKeyEvent& event)
|
|
{
|
|
//printf("DW: down: %d\n", event.GetKeyCode());
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
void DeviceWindow::OnKeyUp(wxKeyEvent& event)
|
|
{
|
|
//printf("DW: up: %d\n", event.GetKeyCode());
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
|
|
/*
|
|
* Handle mouse events. We want to pass these up to the PhoneWindow, since
|
|
* that's where the "touch screen" code is.
|
|
*/
|
|
void DeviceWindow::OnMouseLeftDown(wxMouseEvent& event)
|
|
{
|
|
ClampMouse(&event);
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
void DeviceWindow::OnMouseLeftUp(wxMouseEvent& event)
|
|
{
|
|
ClampMouse(&event);
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
void DeviceWindow::OnMouseRightDown(wxMouseEvent& event)
|
|
{
|
|
ClampMouse(&event);
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
void DeviceWindow::OnMouseRightUp(wxMouseEvent& event)
|
|
{
|
|
ClampMouse(&event);
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
void DeviceWindow::OnMouseMotion(wxMouseEvent& event)
|
|
{
|
|
ClampMouse(&event);
|
|
GetParent()->AddPendingEvent(event);
|
|
}
|
|
|
|
/*
|
|
* Clamp the mouse movement to the window bounds.
|
|
*/
|
|
void DeviceWindow::ClampMouse(wxMouseEvent* pEvent)
|
|
{
|
|
wxWindow* pEventWindow = (wxWindow*) pEvent->GetEventObject();
|
|
int width, height;
|
|
|
|
pEventWindow->GetSize(&width, &height);
|
|
if (pEvent->m_x < 0)
|
|
pEvent->m_x = 0;
|
|
else if (pEvent->m_x >= width)
|
|
pEvent->m_x = width-1;
|
|
|
|
if (pEvent->m_y < 0)
|
|
pEvent->m_y = 0;
|
|
else if (pEvent->m_y >= height)
|
|
pEvent->m_y = height-1;
|
|
}
|
|
|
|
|
|
/*
|
|
* Handle a "user event". We get these when the runtime wants us to
|
|
* know that it has a new frame of graphics to display.
|
|
*
|
|
*/
|
|
void DeviceWindow::OnUserEvent(UserEvent& event)
|
|
{
|
|
wxBitmap* pBitmap;
|
|
long displayIndex;
|
|
|
|
displayIndex = (long) event.GetData();
|
|
|
|
//printf("GOT UAE %d\n", displayIndex);
|
|
|
|
// a displayIndex of -1 means just update the onion skin
|
|
if (displayIndex >= 0) {
|
|
/* get a newly-allocated bitmap with converted image data */
|
|
pBitmap = mpDeviceManager->GetImageData(displayIndex);
|
|
|
|
/* do a ptr/refcount assignment to hold the data */
|
|
mBitmap = *pBitmap;
|
|
/* delete the temporary object; does not delete the bitmap storage */
|
|
delete pBitmap;
|
|
}
|
|
|
|
if (displayIndex >= -1) {
|
|
mHasOnionSkinBitmap = false;
|
|
|
|
Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs();
|
|
assert(pPrefs != NULL);
|
|
|
|
bool overlayOnionSkin;
|
|
char* onionSkinFileName = NULL;
|
|
|
|
bool overlayOnionSkinExists = pPrefs->GetBool("overlay-onion-skin", &overlayOnionSkin);
|
|
if (overlayOnionSkinExists && overlayOnionSkin) {
|
|
bool fileNameExists = pPrefs->GetString("onion-skin-file-name", &onionSkinFileName);
|
|
if (fileNameExists && *onionSkinFileName) {
|
|
wxImage onionSkinImage(wxString::FromAscii(onionSkinFileName));
|
|
onionSkinImage.SetAlpha(NULL);
|
|
bool hasAlpha = onionSkinImage.HasAlpha();
|
|
int width = onionSkinImage.GetWidth();
|
|
int height = onionSkinImage.GetHeight();
|
|
if (hasAlpha) {
|
|
unsigned char *alpha = onionSkinImage.GetAlpha();
|
|
int alphaVal = 127;
|
|
pPrefs->GetInt("onion-skin-alpha-value", &alphaVal);
|
|
for (int i = (width * height) - 1; i >= 0; i--) {
|
|
alpha[i] = alphaVal;
|
|
}
|
|
}
|
|
mOnionSkinBitmap = wxBitmap(onionSkinImage);
|
|
mHasOnionSkinBitmap = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* induce an update */
|
|
Refresh();
|
|
}
|
|
|
|
/*
|
|
* Window has been moved or resized.
|
|
*
|
|
* We get this when the model of phone is changed.
|
|
*
|
|
* FIX: in the future this only happens when the phone is rotated 90deg.
|
|
*/
|
|
void DeviceWindow::OnSize(wxSizeEvent& WXUNUSED(event))
|
|
{
|
|
int width, height;
|
|
|
|
GetClientSize(&width, &height);
|
|
printf("Sim: device window resize: %dx%d\n", width, height);
|
|
|
|
mBitmap.Create(width, height);
|
|
|
|
wxMemoryDC memDC;
|
|
memDC.SelectObject(mBitmap);
|
|
|
|
wxColour backColor(96, 122, 121);
|
|
memDC.SetBrush(wxBrush(backColor));
|
|
memDC.SetPen(wxPen(backColor, 1));
|
|
wxRect windowRect(wxPoint(0, 0), GetClientSize());
|
|
memDC.DrawRectangle(windowRect);
|
|
}
|
|
|
|
/*
|
|
* No need to erase the background.
|
|
*/
|
|
void DeviceWindow::OnErase(wxEraseEvent& WXUNUSED(event))
|
|
{
|
|
//printf("erase device\n");
|
|
}
|
|
|
|
/*
|
|
* Repaint the simulator output.
|
|
*/
|
|
void DeviceWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(this);
|
|
|
|
/* draw background image */
|
|
dc.DrawBitmap(mBitmap, 0, 0, TRUE);
|
|
|
|
/* If necessary, draw onion skin image on top */
|
|
if (mHasOnionSkinBitmap) {
|
|
dc.DrawBitmap(mOnionSkinBitmap, 0, 0, TRUE);
|
|
}
|
|
|
|
#if 0
|
|
// debug - draw the corners
|
|
int xoff = 0;
|
|
int yoff = 0;
|
|
int width;
|
|
int height;
|
|
GetClientSize(&width, &height);
|
|
|
|
dc.SetPen(*wxGREEN_PEN);
|
|
dc.DrawLine(xoff, yoff+9, xoff, yoff);
|
|
dc.DrawLine(xoff, yoff, xoff+10, yoff);
|
|
dc.DrawLine(xoff+width-10, yoff, xoff+width, yoff);
|
|
dc.DrawLine(xoff+width-1, yoff, xoff+width-1, yoff+10);
|
|
dc.DrawLine(xoff, yoff+height-10, xoff, yoff+height);
|
|
dc.DrawLine(xoff, yoff+height-1, xoff+10, yoff+height-1);
|
|
dc.DrawLine(xoff+width-1, yoff+height-10, xoff+width-1, yoff+height);
|
|
dc.DrawLine(xoff+width-1, yoff+height-1, xoff+width-11, yoff+height-1);
|
|
#endif
|
|
}
|
|
|