]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/screenshotgen/src/ctrlmaskout.cpp
patch from Utensil Candel: remove ctrlmaskout.h/cpp; clear some more code; erase...
[wxWidgets.git] / utils / screenshotgen / src / ctrlmaskout.cpp
diff --git a/utils/screenshotgen/src/ctrlmaskout.cpp b/utils/screenshotgen/src/ctrlmaskout.cpp
deleted file mode 100644 (file)
index 3db49ee..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        ctrlmaskout.cpp
-// Purpose:     Implement CtrlMaskOut class
-// Author:      Utensil Candel (UtensilCandel@@gmail.com)
-// RCS-ID:      $Id$
-// Licence:     wxWindows license
-/////////////////////////////////////////////////////////////////////////////
-
-// For compilers that support precompilation, includes "wx/wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-// for all others, include the necessary headers wxWidgets headers)
-#ifndef WX_PRECOMP
-#include "wx/wx.h"
-#endif
-
-#include "ctrlmaskout.h"
-
-#ifdef __WXMAC__ // See CreateMask()
-#include <wx/minifram.h>
-#include <cstdlib>
-#endif
-
-// use a set to make sure the same control won't be inserted twice
-#include "wx/hashset.h"
-WX_DECLARE_HASH_SET(wxWindow*, wxPointerHash, wxPointerEqual, CtrlSet);
-
-
-// It's copied from src/aui/framemanager.cpp and modified, a failed attempt to
-// visualize the process of taking the screenshot when wxTopLevelWindow::CanSetTransparent
-// returns false. see CtrlMaskOut::CreateMask for more info
-// now it shows nothing and does nothing
-/////////////////////////////////////////////////////////////////////////////
-
-class wxPseudoTransparentFrame : public wxFrame
-{
-public:
-    wxPseudoTransparentFrame(wxWindow* parent = NULL,
-                wxWindowID id = wxID_ANY,
-                const wxString& title = wxEmptyString,
-                const wxPoint& pos = wxDefaultPosition,
-                const wxSize& size = wxDefaultSize,
-                long style = wxDEFAULT_FRAME_STYLE,
-                const wxString &name = wxT("frame"))
-                    : wxFrame(parent, id, title, pos, size, style | wxFRAME_SHAPED, name)
-    {
-        m_lastWidth=0;
-        m_lastHeight=0;
-    }
-
-    virtual bool SetTransparent(wxByte alpha)
-    {
-        return true;
-    }
-
-    void OnPaint(wxPaintEvent& WXUNUSED(event)){}
-
-    virtual void SetSize(const wxRect& rect){}
-    virtual void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO){}
-    virtual void SetSize(int width, int height){}
-    virtual void SetSize(const wxSize& size){}
-
-    virtual bool Show(bool show = true){ return true;}
-
-    void OnSize(wxSizeEvent& event)
-    {
-//        // We sometimes get surplus size events
-//        if ((event.GetSize().GetWidth() == m_lastWidth) &&
-//            (event.GetSize().GetHeight() == m_lastHeight))
-//        {
-//            event.Skip();
-//            return;
-//        }
-//
-//         Show(false);
-//
-//         GetParent()->Update();
-//
-//         Show(true);
-//
-//
-//        m_lastWidth = event.GetSize().GetWidth();
-//        m_lastHeight = event.GetSize().GetHeight();
-    }
-
-private:
-    int m_lastWidth,m_lastHeight;
-
-    DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
-    DECLARE_EVENT_TABLE()
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxPseudoTransparentFrame, wxFrame)
-
-BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame)
-    EVT_PAINT(wxPseudoTransparentFrame::OnPaint)
-    EVT_SIZE(wxPseudoTransparentFrame::OnSize)
-END_EVENT_TABLE()
-
-
-
-// ----------------------------------------------------------------------------
-// CtrlMaskOut
-// ----------------------------------------------------------------------------
-
-CtrlMaskOut::CtrlMaskOut()
-      : m_defaultDir(_T("screenshots")),
-        m_controlName(_T("")),
-        m_currentRect(0, 0, 0, 0),
-        m_inflateBorder(5),
-        m_mask(NULL),
-        m_isTiming(false)
-{
-}
-
-CtrlMaskOut::~CtrlMaskOut()
-{
-    if (m_mask != NULL)
-    {
-        m_mask->Destroy();
-        m_mask = NULL;
-    }
-}
-
-void CtrlMaskOut::OnLeftButtonDown(wxMouseEvent& event)
-{
-    if (m_isTiming) event.Skip();
-
-    // Start draging at the left-top corner.
-    wxWindow * thePanel = (wxWindow *)event.GetEventObject();
-    m_currentRect.SetPosition(thePanel->ClientToScreen(event.GetPosition()));
-    m_currentRect.SetSize(wxSize(1, 1));
-
-    // Create a transparent mask to visulize the process of specifying a rect region..
-    CreateMask(thePanel);
-}
-
-void CtrlMaskOut::OnMouseMoving(wxMouseEvent& event)
-{
-    if (!event.Dragging())
-    {
-        event.Skip();
-        return;
-    }
-
-    wxWindow * thePanel = (wxWindow *)event.GetEventObject();
-
-    // Determine the current rect region
-    m_currentRect.SetBottomRight(thePanel->ClientToScreen(event.GetPosition()) - wxPoint(5, 5));
-    // /Because Mac can't get the left btn up event fired if we don't minus wxPoint(5, 5),
-    // /May fix it by making the panel handle this event later
-    // /This is the current trick
-    // /See also line 200 in CreateMask
-
-    // Visualize the current rect region
-    m_mask->SetSize(m_currentRect);
-}
-
-void CtrlMaskOut::OnLeftButtonUp(wxMouseEvent& event)
-{
-    if (m_mask == NULL)// Which means it's not after specifying a rect region
-    {
-        event.Skip();
-        return;
-    }
-
-    DestroyMask();
-
-    // End dragging at the right-bottom corner.
-    wxWindow * thePanel = (wxWindow *)event.GetEventObject();
-    m_currentRect.SetRightBottom(thePanel->ClientToScreen(event.GetPosition()));
-
-    if (event.ControlDown())
-    {
-        m_isTiming = true;
-        (new wxTimer(this))->Start(3000, wxTIMER_ONE_SHOT);
-        this->Connect(wxEVT_TIMER, wxTimerEventHandler( CtrlMaskOut::OnTimingFinished ), NULL, this);
-    }
-    else
-    {
-        // The final rect region is determined.
-        DetermineCtrlNameAndRect();
-
-        Capture(m_currentRect, m_controlName);
-    }
-}
-
-void CtrlMaskOut::OnTimingFinished(wxTimerEvent& event)
-{
-    // The final rect region is determined.
-    DetermineCtrlNameAndRect();
-
-    Capture(m_currentRect, m_controlName);
-
-    m_isTiming = false;
-    this->Disconnect(wxEVT_TIMER, wxTimerEventHandler( CtrlMaskOut::OnTimingFinished ), NULL, this);
-}
-
-void CtrlMaskOut::Capture(int x, int y, int width, int height, wxString fileName)
-{
-    // Somehow wxScreenDC.Blit() doesn't work under Mac for now. Here is a trick.
-#ifdef __WXMAC__
-
-    // wxExecute(_T("screencapture -x ") + tempfile, wxEXEC_SYNC);
-
-    system("screencapture -x /tmp/wx_screen_capture.png");
-
-    wxBitmap fullscreen;
-
-    do
-    {
-        fullscreen = wxBitmap(_T("/tmp/wx_screen_capture.png"), wxBITMAP_TYPE_PNG);
-    }
-    while(!fullscreen.IsOk());
-
-    wxBitmap screenshot = fullscreen.GetSubBitmap(wxRect(x,y,width,height));
-
-    #else // Under other paltforms, take a real screenshot
-
-    // Create a DC for the whole screen area
-    wxScreenDC dcScreen;
-
-    // Create a Bitmap that will later on hold the screenshot image
-    // Note that the Bitmap must have a size big enough to hold the screenshot
-    // -1 means using the current default colour depth
-    wxBitmap screenshot(width, height, -1);
-
-    // Create a memory DC that will be used for actually taking the screenshot
-    wxMemoryDC memDC;
-    // Tell the memory DC to use our Bitmap
-    // all drawing action on the memory DC will go to the Bitmap now
-    memDC.SelectObject(screenshot);
-    // Blit (in this case copy) the actual screen on the memory DC
-    // and thus the Bitmap
-    memDC.Blit( 0, // Copy to this X coordinate
-                0, // Copy to this Y coordinate
-                width, // Copy this width
-                height, // Copy this height
-                &dcScreen, // From where do we copy?
-                x, // What's the X offset in the original DC?
-                y  // What's the Y offset in the original DC?
-                    );
-    // Select the Bitmap out of the memory DC by selecting a new
-    // uninitialized Bitmap
-    memDC.SelectObject(wxNullBitmap);
-
-#endif // #ifdef __WXMAC__
-
-    // Check if m_defaultDir already existed
-    if (!wxDirExists(m_defaultDir))
-        wxMkdir(m_defaultDir);
-
-    // Our Bitmap now has the screenshot, so let's save it as an png
-    // The filename itself is without extension.
-    screenshot.SaveFile(m_defaultDir + wxFileName::GetPathSeparator() +
-    fileName + _T(".png"), wxBITMAP_TYPE_PNG);
-}
-
-void CtrlMaskOut::Capture(wxRect rect, wxString fileName)
-{
-    wxPoint origin = rect.GetPosition();
-    Capture(origin.x, origin.y, rect.GetWidth(), rect.GetHeight(), fileName);
-}
-
-void CtrlMaskOut::DetermineCtrlNameAndRect()
-{
-    // Detect windows using (n-1)*(n-1) points
-    const int n = 5;
-
-    wxPoint pt0 = m_currentRect.GetPosition();
-
-    int dx = m_currentRect.GetWidth() / n;
-    int dy = m_currentRect.GetHeight() / n;
-
-    wxPoint pt;
-    wxWindow * ctrl;
-    wxString ctrlName;
-    wxRect ctrlSize;
-
-    CtrlSet ctrls;
-
-    int i, j;
-    for (i = 1; i <= n - 1; ++i)
-    {
-        for (j = 1; j <= n - 1; ++j)
-        {
-            pt = wxPoint(pt0.x + i * dx, pt0.y + j * dy);
-            ctrls.insert(wxFindWindowAtPoint(pt));
-        }
-    }
-
-    // Store the manual specified rect region, we might need it
-    wxRect backup = m_currentRect;
-
-    // Reset the control region and control name
-    m_currentRect = wxRect(0, 0, 0, 0);
-    m_controlName = _T("");
-
-    for (CtrlSet::iterator it = ctrls.begin(); it != ctrls.end(); ++it )
-    {
-        ctrl = *it;
-        if (ctrl == NULL)
-        // which means no control was detected.
-        // This seldom happens, but without dealing with it, it will CRASH the program
-        {
-            static int count = 0;
-            ++count;
-            m_controlName = _T("nothing_");
-            m_controlName << count;
-            m_currentRect = backup;
-            return;
-        }
-        ctrlName = ctrl->GetClassInfo()->GetClassName();
-
-        if (ctrlName != _T("wxPanel")) // Avoid detecting "wxPanel", which is only the backgroud
-        {
-            // Get a rect region to contain every window detected by unioning one by one.
-            m_currentRect.Union(ctrl->GetScreenRect());
-
-            // Get the name of the control, cut off "wx" and change them into lowercase.
-            // e.g. wxButton will have a filename of "button" and be saved as "button.png"
-            ctrlName.StartsWith(_T("wx"), &ctrlName);
-            ctrlName.MakeLower();
-
-            if (m_controlName.IsEmpty() || m_controlName == ctrlName)
-            {
-                m_controlName = ctrlName;
-            }
-            else // more than one types of controls are in the region selected
-            {
-                m_controlName += _T("_");
-                m_controlName += ctrlName;
-            }
-        }
-    }
-
-    if (m_controlName.IsEmpty() && backup.GetHeight() > 15 && backup.GetWidth() > 15)
-    // which means no control other than the wxPanel was detected.
-    // if the size of the specified rect(backup) is smaller than 15x15,
-    // then it could be just an accident
-    {
-        static int count = 0;
-        ++count;
-        m_controlName = _T("unknown_");
-        m_controlName << count;
-        m_currentRect = backup;
-        return;
-    }
-
-    // Increase its border so that it looks nicer.
-    m_currentRect.Inflate(m_inflateBorder);
-}
-
-void CtrlMaskOut::CreateMask(wxWindow* parent)
-{
-    if (m_mask != NULL)
-        m_mask->Destroy();
-
-    // Make a frame to visualize the process of specifying the rect region.
-#if defined(__WXMSW__) || defined(__WXGTK__)
-    m_mask = new wxFrame(parent, wxID_ANY, wxEmptyString,
-                                m_currentRect.GetPosition(), m_currentRect.GetSize(),
-                                wxFRAME_TOOL_WINDOW |
-                                wxFRAME_FLOAT_ON_PARENT |
-                                wxFRAME_NO_TASKBAR);
-//                                 wxNO_BORDER);
-// with the border, it looks better under windows
-
-    m_mask->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
-
-#elif defined(__WXMAC__)
-    // Using a miniframe with float and tool styles keeps the parent
-    // frame activated and highlighted as such...
-    m_mask = new wxMiniFrame(parent, wxID_ANY, wxEmptyString,
-                                m_currentRect.GetPosition(), m_currentRect.GetSize(),
-                                wxFRAME_FLOAT_ON_PARENT
-                                | wxFRAME_TOOL_WINDOW );
-
-    // Can't set the bg colour of a Frame in wxMac
-    wxPanel* p = new wxPanel(m_mask);
-
-    // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver
-    // color that is really hard to see, especially transparent.
-    // Until a better system color is decided upon we'll just use
-    // blue.
-    p->SetBackgroundColour(*wxBLUE);
-
-    // So that even if the cursor run into the mask, the events are still correctly processed.
-    p->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonDown ), NULL, this);
-    p->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonUp ), NULL, this);
-    p->Connect( wxEVT_MOTION, wxMouseEventHandler( CtrlMaskOut::OnMouseMoving ), NULL, this);
-#endif
-
-    // If the platform doesn't support SetTransparent()
-    // we will use a dummy mask(which does and shows nothing)
-    // /this is the current trick, shall make it visible later
-    if (!m_mask->CanSetTransparent())
-    {
-        m_mask->Destroy();
-
-        m_mask = new wxPseudoTransparentFrame(parent,
-                                    wxID_ANY,
-                                    wxEmptyString,
-                                    wxDefaultPosition,
-                                    wxSize(1,1),
-                                            wxFRAME_TOOL_WINDOW |
-                                            wxFRAME_FLOAT_ON_PARENT |
-                                            wxFRAME_NO_TASKBAR
-                                            );
-
-    }
-
-    m_mask->SetTransparent(100); // Full value is 255
-    m_mask->Show(true);
-
-    // So that even if the cursor run into the mask, the events are still correctly processed.
-    m_mask->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonDown ), NULL, this);
-    m_mask->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonUp ), NULL, this);
-    m_mask->Connect( wxEVT_MOTION, wxMouseEventHandler( CtrlMaskOut::OnMouseMoving ), NULL, this);
-}
-
-void CtrlMaskOut::DestroyMask()
-{
-    m_mask->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonDown ), NULL, this);
-    m_mask->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CtrlMaskOut::OnLeftButtonUp ), NULL, this);
-    m_mask->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CtrlMaskOut::OnMouseMoving ), NULL, this);
-    wxWindow * parent = m_mask->GetParent();
-//    m_mask->Destroy();
-    delete m_mask;
-
-    parent->Update();
-    m_mask = NULL;
-}
-