1 
2 // madedit: changed DoDraw() function (2005/08/17)
3 
4 ///////////////////////////////////////////////////////////////////////////////
5 // Name:        generic/caret.cpp
6 // Purpose:     generic wxCaret class implementation
7 // Author:      Vadim Zeitlin (original code by Robert Roebling)
8 // Modified by:
9 // Created:     25.05.99
10 // RCS-ID:      $Id: caret.cpp,v 1.15 2005/09/23 12:53:25 MR Exp $
11 // Copyright:   (c) wxWidgets team
12 // Licence:     wxWindows licence
13 ///////////////////////////////////////////////////////////////////////////////
14 
15 // ============================================================================
16 // declarations
17 // ============================================================================
18 
19 // ----------------------------------------------------------------------------
20 // headers
21 // ----------------------------------------------------------------------------
22 
23 // For compilers that support precompilation, includes "wx.h".
24 #include <wx/wxprec.h>
25 
26 #ifdef __BORLANDC__
27     #pragma hdrstop
28 #endif
29 
30 #if wxUSE_CARET
31 
32 #ifndef WX_PRECOMP
33     #include <wx/window.h>
34     #include <wx/dcclient.h>
35     #include <wx/dcmemory.h>
36 #endif //WX_PRECOMP
37 
38 #include <wx/caret.h>
39 
40 #include "caret_new.h"
41 
42 // ----------------------------------------------------------------------------
43 // global variables for this module
44 // ----------------------------------------------------------------------------
45 
46 // the blink time (common to all carets for MSW compatibility)
47 static int gs_blinkTime = 500;  // in milliseconds
48 
49 // ============================================================================
50 // implementation
51 // ============================================================================
52 
53 // ----------------------------------------------------------------------------
54 // timer stuff
55 // ----------------------------------------------------------------------------
56 
wxCaretTimerNew(wxCaretNew * caret)57 wxCaretTimerNew::wxCaretTimerNew(wxCaretNew *caret)
58 {
59     m_caret = caret;
60 }
61 
Notify()62 void wxCaretTimerNew::Notify()
63 {
64     m_caret->OnTimer();
65 }
66 
OnTimer()67 void wxCaretNew::OnTimer()
68 {
69     // don't blink the caret when we don't have the focus
70     if ( m_hasFocus )
71         Blink();
72 }
73 
74 // ----------------------------------------------------------------------------
75 // wxCaretNew static functions and data
76 // ----------------------------------------------------------------------------
77 /***
78 int wxCaretBase::GetBlinkTime()
79 {
80     return gs_blinkTime;
81 }
82 
83 void wxCaretBase::SetBlinkTime(int milliseconds)
84 {
85     gs_blinkTime = milliseconds;
86 }
87 ***/
88 // ----------------------------------------------------------------------------
89 // initialization and destruction
90 // ----------------------------------------------------------------------------
91 
InitGeneric()92 void wxCaretNew::InitGeneric()
93 {
94     m_hasFocus = true;
95     m_blinkedOut = true;
96 
97     m_xOld =
98     m_yOld = -1;
99     m_bmpUnderCaret.Create(m_width, m_height);
100 }
101 
~wxCaretNew()102 wxCaretNew::~wxCaretNew()
103 {
104     if ( IsVisible() )
105     {
106         // stop blinking
107         if ( m_timer.IsRunning() )
108             m_timer.Stop();
109     }
110 }
111 
112 // ----------------------------------------------------------------------------
113 // showing/hiding/moving the caret (base class interface)
114 // ----------------------------------------------------------------------------
115 
DoShow()116 void wxCaretNew::DoShow()
117 {
118     int blinkTime = GetBlinkTime();
119     if ( blinkTime )
120         m_timer.Start(blinkTime);
121 
122     if ( m_blinkedOut )
123         Blink();
124 }
125 
DoHide()126 void wxCaretNew::DoHide()
127 {
128     m_timer.Stop();
129 
130     if ( !m_blinkedOut )
131     {
132         Blink();
133     }
134 }
135 
DoMove()136 void wxCaretNew::DoMove()
137 {
138     if ( IsVisible() )
139     {
140         if ( !m_blinkedOut )
141         {
142             // hide it right now and it will be shown the next time it blinks
143             Blink();
144 
145             // but if the caret is not blinking, we should blink it back into
146             // visibility manually
147             if ( !m_timer.IsRunning() )
148                 Blink();
149         }
150     }
151     //else: will be shown at the correct location when it is shown
152 }
153 
DoSize()154 void wxCaretNew::DoSize()
155 {
156     int countVisible = m_countVisible;
157     if (countVisible > 0)
158     {
159         m_countVisible = 0;
160         DoHide();
161     }
162     // Change bitmap size
163     m_bmpUnderCaret = wxBitmap(m_width, m_height);
164     if (countVisible > 0)
165     {
166         m_countVisible = countVisible;
167         DoShow();
168     }
169 }
170 
171 // ----------------------------------------------------------------------------
172 // handling the focus
173 // ----------------------------------------------------------------------------
174 
OnSetFocus()175 void wxCaretNew::OnSetFocus()
176 {
177     m_hasFocus = true;
178 
179     if ( IsVisible() )
180         Refresh();
181 }
182 
OnKillFocus()183 void wxCaretNew::OnKillFocus()
184 {
185     m_hasFocus = false;
186 
187     if ( IsVisible() )
188     {
189         // the caret must be shown - otherwise, if it is hidden now, it will
190         // stay so until the focus doesn't return because it won't blink any
191         // more
192 
193         // hide it first if it isn't hidden ...
194         if ( !m_blinkedOut )
195             Blink();
196 
197         // .. and show it in the new style
198         Blink();
199     }
200 }
201 
202 // ----------------------------------------------------------------------------
203 // drawing the caret
204 // ----------------------------------------------------------------------------
205 
Blink()206 void wxCaretNew::Blink()
207 {
208     m_blinkedOut = !m_blinkedOut;
209 
210     Refresh();
211 }
212 
Refresh()213 void wxCaretNew::Refresh()
214 {
215     wxClientDC dcWin(GetWindow());
216     wxMemoryDC dcMem;
217     dcMem.SelectObject(m_bmpUnderCaret);
218     if ( m_blinkedOut )
219     {
220         // restore the old image
221         dcWin.Blit(m_xOld, m_yOld, m_width, m_height,
222                    &dcMem, 0, 0);
223         m_xOld =
224         m_yOld = -1;
225     }
226     else
227     {
228         if ( m_xOld == -1 && m_yOld == -1 )
229         {
230             // save the part we're going to overdraw
231 
232             int x = m_x,
233                 y = m_y;
234 #if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__)
235             wxPoint pt = dcWin.GetDeviceOrigin();
236             x += pt.x;
237             y += pt.y;
238 #endif // broken wxGTK wxDC::Blit
239             dcMem.Blit(0, 0, m_width, m_height,
240                        &dcWin, x, y);
241 
242             m_xOld = m_x;
243             m_yOld = m_y;
244         }
245         //else: we already saved the image below the caret, don't do it any
246         //      more
247 
248         // and draw the caret there
249         DoDraw(&dcWin);
250     }
251 }
252 
253 
254 #include "MadEdit.h"
255 
256 #ifndef FIXINVERT
257 //#   ifdef __WXMSW__
258 #       define FIXINVERT 0
259 //#   else
260 //#       define FIXINVERT 1
261 //#   endif
262 #endif
263 
DoDraw(wxDC * dc)264 void wxCaretNew::DoDraw(wxDC *dc)
265 {
266 
267     if(m_hasFocus)
268     {
269 
270 #if   FIXINVERT == 0
271         dc->Blit(m_x, m_y, m_width, m_height, dc, m_x, m_y, wxINVERT);
272 #elif FIXINVERT == 1
273         MadEdit *me=(MadEdit*)GetWindow();
274         (me->*(me->InvertRect))(dc, m_x, m_y, m_width, m_height);
275 #elif FIXINVERT == 2
276         ((MadEdit*)GetWindow())->InvertRectManual(dc, m_x, m_y, m_width, m_height);
277 #else
278 #     error FIXINVERT not defined
279 #endif
280 
281     }
282 }
283 
284 #endif // wxUSE_CARET
285