1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mgl/cursor.cpp 3// Purpose: 4// Author: Vaclav Slavik 5// Id: $Id: cursor.cpp 42752 2006-10-30 19:26:48Z VZ $ 6// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) 7// Licence: wxWindows licence 8///////////////////////////////////////////////////////////////////////////// 9 10// For compilers that support precompilation, includes "wx.h". 11#include "wx/wxprec.h" 12 13#ifdef __BORLANDC__ 14 #pragma hdrstop 15#endif 16 17#include "wx/cursor.h" 18 19#ifndef WX_PRECOMP 20 #include "wx/intl.h" 21 #include "wx/log.h" 22 #include "wx/utils.h" 23 #include "wx/hashmap.h" 24 #include "wx/module.h" 25#endif 26 27#include "wx/mgl/private.h" 28 29 30//----------------------------------------------------------------------------- 31// wxCursor 32//----------------------------------------------------------------------------- 33 34class wxCursorRefData: public wxObjectRefData 35{ 36 public: 37 38 wxCursorRefData(); 39 virtual ~wxCursorRefData(); 40 41 MGLCursor *m_cursor; 42}; 43 44wxCursorRefData::wxCursorRefData() 45{ 46 m_cursor = (MGLCursor*) NULL; 47} 48 49wxCursorRefData::~wxCursorRefData() 50{ 51 delete m_cursor; 52} 53 54#define M_CURSORDATA ((wxCursorRefData *)m_refData) 55 56//----------------------------------------------------------------------------- 57 58WX_DECLARE_HASH_MAP(int, wxCursor, wxIntegerHash, wxIntegerEqual, wxCursorsHash); 59 60static wxCursorsHash *gs_cursorsHash = NULL; 61 62IMPLEMENT_DYNAMIC_CLASS(wxCursor,wxObject) 63 64wxCursor::wxCursor() 65{ 66} 67 68wxCursor::wxCursor(int cursorId) 69{ 70 if ( !gs_cursorsHash ) 71 gs_cursorsHash = new wxCursorsHash; 72 73 if ( gs_cursorsHash->find(cursorId) != gs_cursorsHash->end() ) 74 { 75 wxLogTrace(_T("mglcursor"), _T("cursor id %i fetched from cache"), cursorId); 76 *this = (*gs_cursorsHash)[cursorId]; 77 return; 78 } 79 80 const char *cursorname = NULL; 81 m_refData = new wxCursorRefData(); 82 83 switch (cursorId) 84 { 85 case wxCURSOR_ARROW: cursorname = "arrow.cur"; break; 86 case wxCURSOR_RIGHT_ARROW: cursorname = "rightarr.cur"; break; 87 case wxCURSOR_BULLSEYE: cursorname = "bullseye.cur"; break; 88 case wxCURSOR_CHAR: cursorname = "char.cur"; break; 89 case wxCURSOR_CROSS: cursorname = "cross.cur"; break; 90 case wxCURSOR_HAND: cursorname = "hand.cur"; break; 91 case wxCURSOR_IBEAM: cursorname = "ibeam.cur"; break; 92 case wxCURSOR_LEFT_BUTTON: cursorname = "leftbtn.cur"; break; 93 case wxCURSOR_MAGNIFIER: cursorname = "magnif1.cur"; break; 94 case wxCURSOR_MIDDLE_BUTTON: cursorname = "midbtn.cur"; break; 95 case wxCURSOR_NO_ENTRY: cursorname = "noentry.cur"; break; 96 case wxCURSOR_PAINT_BRUSH: cursorname = "pbrush.cur"; break; 97 case wxCURSOR_PENCIL: cursorname = "pencil.cur"; break; 98 case wxCURSOR_POINT_LEFT: cursorname = "pntleft.cur"; break; 99 case wxCURSOR_POINT_RIGHT: cursorname = "pntright.cur"; break; 100 case wxCURSOR_QUESTION_ARROW: cursorname = "query.cur"; break; 101 case wxCURSOR_RIGHT_BUTTON: cursorname = "rightbtn.cur"; break; 102 case wxCURSOR_SIZENESW: cursorname = "sizenesw.cur"; break; 103 case wxCURSOR_SIZENS: cursorname = "sizens.cur"; break; 104 case wxCURSOR_SIZENWSE: cursorname = "sizenwse.cur"; break; 105 case wxCURSOR_SIZEWE: cursorname = "sizewe.cur"; break; 106 case wxCURSOR_SIZING: cursorname = "size.cur"; break; 107 case wxCURSOR_SPRAYCAN: cursorname = "spraycan.cur"; break; 108 case wxCURSOR_WAIT: cursorname = "wait.cur"; break; 109 case wxCURSOR_WATCH: cursorname = "clock.cur"; break; 110 case wxCURSOR_BLANK: cursorname = "blank.cur"; break; 111 112 case wxCURSOR_NONE: 113 *this = wxNullCursor; 114 return; 115 116 default: 117 wxFAIL_MSG(wxT("unsupported cursor type")); 118 break; 119 } 120 121 M_CURSORDATA->m_cursor = new MGLCursor(cursorname); 122 123 // if we cannot load arrow cursor, use MGL's default arrow cursor: 124 if ( !M_CURSORDATA->m_cursor->valid() && cursorId == wxCURSOR_ARROW ) 125 { 126 delete M_CURSORDATA->m_cursor; 127 M_CURSORDATA->m_cursor = new MGLCursor(MGL_DEF_CURSOR); 128 } 129 130 if ( !M_CURSORDATA->m_cursor->valid() ) 131 { 132 wxLogError(_("Couldn't create cursor.")); 133 UnRef(); 134 } 135 else 136 { 137 (*gs_cursorsHash)[cursorId] = *this; 138 wxLogTrace(_T("mglcursor"), _T("cursor id %i added to cache (%s)"), 139 cursorId, cursorname); 140 } 141} 142 143wxCursor::wxCursor(const char WXUNUSED(bits)[], 144 int WXUNUSED(width), 145 int WXUNUSED(height), 146 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY), 147 const char WXUNUSED(maskBits)[], 148 wxColour * WXUNUSED(fg), wxColour * WXUNUSED(bg) ) 149{ 150 //FIXME_MGL 151} 152 153wxCursor::wxCursor(const wxString& cursor_file, 154 long flags, 155 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY)) 156{ 157 if ( flags == wxBITMAP_TYPE_CUR || flags == wxBITMAP_TYPE_CUR_RESOURCE ) 158 { 159 m_refData = new wxCursorRefData(); 160 M_CURSORDATA->m_cursor = new MGLCursor(cursor_file.mb_str()); 161 if ( !M_CURSORDATA->m_cursor->valid() ) 162 { 163 wxLogError(_("Couldn't create cursor.")); 164 UnRef(); 165 } 166 } 167 else 168 { 169 wxLogError(wxT("Cannot load cursor resource of this type.")); 170 } 171} 172 173wxCursor::~wxCursor() 174{ 175 // wxObject unrefs data 176} 177 178bool wxCursor::IsOk() const 179{ 180 return (m_refData != NULL); 181} 182 183MGLCursor *wxCursor::GetMGLCursor() const 184{ 185 return M_CURSORDATA->m_cursor; 186} 187 188 189 190// ---------------------------------------------------------------------------- 191// Global cursor setting 192// ---------------------------------------------------------------------------- 193 194static wxCursor gs_globalCursor = wxNullCursor; 195 196void wxSetCursor(const wxCursor& cursor) 197{ 198 if ( cursor.Ok() ) 199 { 200 if ( g_winMng ) 201 MGL_wmSetGlobalCursor(g_winMng, *cursor.GetMGLCursor()); 202 gs_globalCursor = cursor; 203 } 204 else 205 { 206 if ( g_winMng ) 207 MGL_wmSetGlobalCursor(g_winMng, NULL); 208 gs_globalCursor = wxNullCursor; 209 } 210} 211 212 213 214//----------------------------------------------------------------------------- 215// busy cursor routines 216//----------------------------------------------------------------------------- 217 218static wxCursor gs_savedCursor = wxNullCursor; 219static int gs_busyCount = 0; 220 221const wxCursor &wxBusyCursor::GetStoredCursor() 222{ 223 return gs_savedCursor; 224} 225 226const wxCursor wxBusyCursor::GetBusyCursor() 227{ 228 return gs_globalCursor; 229} 230 231void wxEndBusyCursor() 232{ 233 if ( --gs_busyCount > 0 ) return; 234 235 wxSetCursor(gs_savedCursor); 236 gs_savedCursor = wxNullCursor; 237} 238 239void wxBeginBusyCursor(const wxCursor *cursor) 240{ 241 if ( gs_busyCount++ > 0 ) return; 242 243 wxASSERT_MSG( !gs_savedCursor.Ok(), 244 wxT("forgot to call wxEndBusyCursor, will leak memory") ); 245 246 gs_savedCursor = gs_globalCursor; 247 if ( cursor->Ok() ) 248 wxSetCursor(*cursor); 249 else 250 wxSetCursor(wxCursor(wxCURSOR_WAIT)); 251} 252 253bool wxIsBusy() 254{ 255 return (gs_busyCount > 0); 256} 257 258 259 260//----------------------------------------------------------------------------- 261// module - clean up code 262//----------------------------------------------------------------------------- 263 264class wxCursorModule : public wxModule 265{ 266public: 267 virtual bool OnInit() { return true; } 268 269 virtual void OnExit() 270 { 271 wxDELETE(gs_cursorsHash); 272 } 273 274private: 275 DECLARE_DYNAMIC_CLASS(wxCursorModule) 276}; 277 278IMPLEMENT_DYNAMIC_CLASS(wxCursorModule, wxModule) 279