Home | History | Annotate | Download | only in app
      1 //
      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 
     22 BEGIN_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)
     38 END_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  */
     46 DeviceWindow::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  */
     63 DeviceWindow::~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  */
     73 void DeviceWindow::OnKeyDown(wxKeyEvent& event)
     74 {
     75     //printf("DW: down: %d\n", event.GetKeyCode());
     76     GetParent()->AddPendingEvent(event);
     77 }
     78 void 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  */
     88 void DeviceWindow::OnMouseLeftDown(wxMouseEvent& event)
     89 {
     90     ClampMouse(&event);
     91     GetParent()->AddPendingEvent(event);
     92 }
     93 void DeviceWindow::OnMouseLeftUp(wxMouseEvent& event)
     94 {
     95     ClampMouse(&event);
     96     GetParent()->AddPendingEvent(event);
     97 }
     98 void DeviceWindow::OnMouseRightDown(wxMouseEvent& event)
     99 {
    100     ClampMouse(&event);
    101     GetParent()->AddPendingEvent(event);
    102 }
    103 void DeviceWindow::OnMouseRightUp(wxMouseEvent& event)
    104 {
    105     ClampMouse(&event);
    106     GetParent()->AddPendingEvent(event);
    107 }
    108 void 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  */
    117 void 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  */
    140 void 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);
    175                 bool hasAlpha = onionSkinImage.HasAlpha();
    176                 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  */
    203 void 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  */
    225 void DeviceWindow::OnErase(wxEraseEvent& WXUNUSED(event))
    226 {
    227     //printf("erase device\n");
    228 }
    229 
    230 /*
    231  * Repaint the simulator output.
    232  */
    233 void 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 
    265