Soren Jorvang d14efe561b Import r67258 of the wxWidgets trunk, which I expect will before
long become wxWidgets 2.9.2, which in turn is expected to be the
last 2.9 release before the 3.0 stable release.

Since the full wxWidgets distribution is rather large, I have
imported only the parts that we use, on a subdirectory basis:

art
include/wx/*.*
include/wx/aui
include/wx/cocoa
include/wx/generic
include/wx/gtk
include/wx/meta
include/wx/msw
include/wx/osx
include/wx/persist
include/wx/private
include/wx/protocol
include/wx/unix
src/aui
src/common
src/generic
src/gtk
src/msw
src/osx
src/unix


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7380 8ced0084-cf51-0410-be5f-012b33b47a6e
2011-03-20 18:05:19 +00:00

402 lines
12 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/cursor.cpp
// Purpose: wxCursor class
// Author: Julian Smart
// Modified by:
// Created: 01/02/97
// RCS-ID: $Id: cursor.cpp 65057 2010-07-23 23:32:46Z VZ $
// Copyright: (c) 1997-2003 Julian Smart and Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/cursor.h"
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/bitmap.h"
#include "wx/icon.h"
#include "wx/settings.h"
#include "wx/intl.h"
#include "wx/image.h"
#include "wx/module.h"
#endif
#include "wx/msw/private.h"
#include "wx/msw/missing.h" // IDC_HAND
// define functions missing in MicroWin
#ifdef __WXMICROWIN__
static inline void DestroyCursor(HCURSOR) { }
static inline void SetCursor(HCURSOR) { }
#endif // __WXMICROWIN__
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxCursorRefData : public wxGDIImageRefData
{
public:
// the second parameter is used to tell us to delete the cursor when we're
// done with it (normally we shouldn't call DestroyCursor() this is why it
// doesn't happen by default)
wxCursorRefData(HCURSOR hcursor = 0, bool takeOwnership = false);
virtual ~wxCursorRefData() { Free(); }
virtual void Free();
// return the size of the standard cursor: notice that the system only
// supports the cursors of this size
static wxCoord GetStandardWidth();
static wxCoord GetStandardHeight();
private:
bool m_destroyCursor;
// standard cursor size, computed on first use
static wxSize ms_sizeStd;
};
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject)
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
// Current cursor, in order to hang on to cursor handle when setting the cursor
// globally
static wxCursor *gs_globalCursor = NULL;
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class wxCursorModule : public wxModule
{
public:
virtual bool OnInit()
{
gs_globalCursor = new wxCursor;
return true;
}
virtual void OnExit()
{
wxDELETE(gs_globalCursor);
}
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxCursorRefData
// ----------------------------------------------------------------------------
wxSize wxCursorRefData::ms_sizeStd;
wxCoord wxCursorRefData::GetStandardWidth()
{
if ( !ms_sizeStd.x )
ms_sizeStd.x = wxSystemSettings::GetMetric(wxSYS_CURSOR_X);
return ms_sizeStd.x;
}
wxCoord wxCursorRefData::GetStandardHeight()
{
if ( !ms_sizeStd.y )
ms_sizeStd.y = wxSystemSettings::GetMetric(wxSYS_CURSOR_Y);
return ms_sizeStd.y;
}
wxCursorRefData::wxCursorRefData(HCURSOR hcursor, bool destroy)
{
m_hCursor = (WXHCURSOR)hcursor;
if ( m_hCursor )
{
m_width = GetStandardWidth();
m_height = GetStandardHeight();
}
m_destroyCursor = destroy;
}
void wxCursorRefData::Free()
{
if ( m_hCursor )
{
#ifndef __WXWINCE__
if ( m_destroyCursor )
::DestroyCursor((HCURSOR)m_hCursor);
#endif
m_hCursor = 0;
}
}
// ----------------------------------------------------------------------------
// Cursors
// ----------------------------------------------------------------------------
wxCursor::wxCursor()
{
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage& image)
{
// image has to be of the standard cursor size, otherwise we won't be able
// to create it
const int w = wxCursorRefData::GetStandardWidth();
const int h = wxCursorRefData::GetStandardHeight();
int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
int image_w = image.GetWidth();
int image_h = image.GetHeight();
wxASSERT_MSG( hotSpotX >= 0 && hotSpotX < image_w &&
hotSpotY >= 0 && hotSpotY < image_h,
wxT("invalid cursor hot spot coordinates") );
wxImage imageSized(image); // final image of correct size
// if image is too small then place it in the center, resize it if too big
if ((w > image_w) && (h > image_h))
{
wxPoint offset((w - image_w)/2, (h - image_h)/2);
hotSpotX = hotSpotX + offset.x;
hotSpotY = hotSpotY + offset.y;
imageSized = image.Size(wxSize(w, h), offset);
}
else if ((w != image_w) || (h != image_h))
{
hotSpotX = int(hotSpotX * double(w) / double(image_w));
hotSpotY = int(hotSpotY * double(h) / double(image_h));
imageSized = image.Scale(w, h);
}
HCURSOR hcursor = wxBitmapToHCURSOR( wxBitmap(imageSized),
hotSpotX, hotSpotY );
if ( !hcursor )
{
wxLogWarning(_("Failed to create cursor."));
return;
}
m_refData = new wxCursorRefData(hcursor, true /* delete it later */);
}
#endif // wxUSE_IMAGE
// MicroWin doesn't have support needed for the other ctors
#ifdef __WXMICROWIN__
wxCursor::InitFromStock(wxStockCursor WXUNUSED(cursor_type))
{
}
#else // !__WXMICROWIN__
wxCursor::wxCursor(const wxString& filename,
wxBitmapType kind,
int hotSpotX,
int hotSpotY)
{
HCURSOR hcursor;
switch ( kind )
{
case wxBITMAP_TYPE_CUR_RESOURCE:
hcursor = ::LoadCursor(wxGetInstance(), filename.t_str());
break;
#ifndef __WXWINCE__
case wxBITMAP_TYPE_CUR:
hcursor = ::LoadCursorFromFile(filename.t_str());
break;
#endif
case wxBITMAP_TYPE_ICO:
hcursor = wxBitmapToHCURSOR
(
wxIcon(filename, wxBITMAP_TYPE_ICO),
hotSpotX,
hotSpotY
);
break;
case wxBITMAP_TYPE_BMP:
hcursor = wxBitmapToHCURSOR
(
wxBitmap(filename, wxBITMAP_TYPE_BMP),
hotSpotX,
hotSpotY
);
break;
default:
wxLogError( wxT("unknown cursor resource type '%d'"), kind );
hcursor = NULL;
}
if ( hcursor )
{
m_refData = new wxCursorRefData(hcursor, true /* delete it later */);
}
}
// Cursors by stock number
void wxCursor::InitFromStock(wxStockCursor idCursor)
{
// all wxWidgets standard cursors
static const struct StdCursor
{
// is this a standard Windows cursor?
bool isStd;
// the cursor name or id
LPCTSTR name;
} stdCursors[] =
{
{ true, NULL }, // wxCURSOR_NONE
{ true, IDC_ARROW }, // wxCURSOR_ARROW
{ false, wxT("WXCURSOR_RIGHT_ARROW") }, // wxCURSOR_RIGHT_ARROW
{ false, wxT("WXCURSOR_BULLSEYE") }, // wxCURSOR_BULLSEYE
{ true, IDC_ARROW }, // WXCURSOR_CHAR
// Displays as an I-beam on XP, so use a cursor file
// { true, IDC_CROSS }, // WXCURSOR_CROSS
{ false, wxT("WXCURSOR_CROSS") }, // WXCURSOR_CROSS
// See special handling below for wxCURSOR_HAND
// { false, wxT("WXCURSOR_HAND") }, // wxCURSOR_HAND
{ true, IDC_HAND }, // wxCURSOR_HAND
{ true, IDC_IBEAM }, // WXCURSOR_IBEAM
{ true, IDC_ARROW }, // WXCURSOR_LEFT_BUTTON
{ false, wxT("WXCURSOR_MAGNIFIER") }, // wxCURSOR_MAGNIFIER
{ true, IDC_ARROW }, // WXCURSOR_MIDDLE_BUTTON
{ true, IDC_NO }, // WXCURSOR_NO_ENTRY
{ false, wxT("WXCURSOR_PBRUSH") }, // wxCURSOR_PAINT_BRUSH
{ false, wxT("WXCURSOR_PENCIL") }, // wxCURSOR_PENCIL
{ false, wxT("WXCURSOR_PLEFT") }, // wxCURSOR_POINT_LEFT
{ false, wxT("WXCURSOR_PRIGHT") }, // wxCURSOR_POINT_RIGHT
{ true, IDC_HELP }, // WXCURSOR_QUESTION_ARROW
{ true, IDC_ARROW }, // WXCURSOR_RIGHT_BUTTON
{ true, IDC_SIZENESW }, // WXCURSOR_SIZENESW
{ true, IDC_SIZENS }, // WXCURSOR_SIZENS
{ true, IDC_SIZENWSE }, // WXCURSOR_SIZENWSE
{ true, IDC_SIZEWE }, // WXCURSOR_SIZEWE
{ true, IDC_SIZEALL }, // WXCURSOR_SIZING
{ false, wxT("WXCURSOR_PBRUSH") }, // wxCURSOR_SPRAYCAN
{ true, IDC_WAIT }, // WXCURSOR_WAIT
{ true, IDC_WAIT }, // WXCURSOR_WATCH
{ false, wxT("WXCURSOR_BLANK") }, // wxCURSOR_BLANK
{ true, IDC_APPSTARTING }, // wxCURSOR_ARROWWAIT
// no entry for wxCURSOR_MAX
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(stdCursors) == wxCURSOR_MAX,
CursorsIdArrayMismatch );
wxCHECK_RET( idCursor > 0 && (size_t)idCursor < WXSIZEOF(stdCursors),
wxT("invalid cursor id in wxCursor() ctor") );
const StdCursor& stdCursor = stdCursors[idCursor];
bool deleteLater = !stdCursor.isStd;
HCURSOR hcursor = ::LoadCursor(stdCursor.isStd ? NULL : wxGetInstance(),
stdCursor.name);
// IDC_HAND may not be available on some versions of Windows.
if ( !hcursor && idCursor == wxCURSOR_HAND)
{
hcursor = ::LoadCursor(wxGetInstance(), wxT("WXCURSOR_HAND"));
deleteLater = true;
}
if ( !hcursor )
{
if ( !stdCursor.isStd )
{
// it may be not obvious to the programmer why did loading fail,
// try to help by pointing to the by far the most probable reason
wxFAIL_MSG(wxT("Loading a cursor defined by wxWidgets failed, ")
wxT("did you include include/wx/msw/wx.rc file from ")
wxT("your resource file?"));
}
wxLogLastError(wxT("LoadCursor"));
}
else
{
m_refData = new wxCursorRefData(hcursor, deleteLater);
}
}
#endif // __WXMICROWIN__/!__WXMICROWIN__
wxCursor::~wxCursor()
{
}
// ----------------------------------------------------------------------------
// other wxCursor functions
// ----------------------------------------------------------------------------
wxGDIImageRefData *wxCursor::CreateData() const
{
return new wxCursorRefData;
}
// ----------------------------------------------------------------------------
// Global cursor setting
// ----------------------------------------------------------------------------
const wxCursor *wxGetGlobalCursor()
{
return gs_globalCursor;
}
void wxSetCursor(const wxCursor& cursor)
{
if ( cursor.Ok() )
{
::SetCursor(GetHcursorOf(cursor));
if ( gs_globalCursor )
*gs_globalCursor = cursor;
}
}