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