]> git.saurik.com Git - wxWidgets.git/blob - src/generic/caret.cpp
attempts to implement non blinking caret - failed so far
[wxWidgets.git] / src / generic / caret.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: generic/caret.cpp
3 // Purpose: generic wxCaret class implementation
4 // Author: Vadim Zeitlin (original code by Robert Roebling)
5 // Modified by:
6 // Created: 25.05.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "caret.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_CARET
32
33 #ifndef WX_PRECOMP
34 #include "wx/window.h"
35 #include "wx/dcclient.h"
36 #endif //WX_PRECOMP
37
38 #include "wx/caret.h"
39
40 // ----------------------------------------------------------------------------
41 // global variables for this module
42 // ----------------------------------------------------------------------------
43
44 // the blink time (common to all carets for MSW compatibility)
45 static int gs_blinkTime = 500; // in milliseconds
46
47 // ============================================================================
48 // implementation
49 // ============================================================================
50
51 // ----------------------------------------------------------------------------
52 // timer stuff
53 // ----------------------------------------------------------------------------
54
55 wxCaretTimer::wxCaretTimer(wxCaret *caret)
56 {
57 m_caret = caret;
58 }
59
60 void wxCaretTimer::Notify()
61 {
62 m_caret->OnTimer();
63 }
64
65 void wxCaret::OnTimer()
66 {
67 // don't blink the caret when we don't have the focus
68 if ( m_hasFocus )
69 Blink();
70 }
71
72 // ----------------------------------------------------------------------------
73 // wxCaret static functions and data
74 // ----------------------------------------------------------------------------
75
76 int wxCaretBase::GetBlinkTime()
77 {
78 return gs_blinkTime;
79 }
80
81 void wxCaretBase::SetBlinkTime(int milliseconds)
82 {
83 gs_blinkTime = milliseconds;
84 }
85
86 // ----------------------------------------------------------------------------
87 // initialization and destruction
88 // ----------------------------------------------------------------------------
89
90 void wxCaret::InitGeneric()
91 {
92 m_hasFocus = TRUE;
93 m_blinkedOut = FALSE;
94 }
95
96 wxCaret::~wxCaret()
97 {
98 if ( IsVisible() )
99 {
100 // stop blinking
101 if ( m_timer.IsRunning() )
102 m_timer.Stop();
103 }
104 }
105
106 // ----------------------------------------------------------------------------
107 // showing/hiding/moving the caret (base class interface)
108 // ----------------------------------------------------------------------------
109
110 void wxCaret::DoShow()
111 {
112 int blinkTime = GetBlinkTime();
113 if ( blinkTime )
114 m_timer.Start(blinkTime);
115
116 m_blinkedOut = TRUE;
117 Blink();
118 }
119
120 void wxCaret::DoHide()
121 {
122 m_timer.Stop();
123
124 if ( !m_blinkedOut )
125 {
126 Blink();
127 }
128 }
129
130 void wxCaret::DoMove()
131 {
132 if ( IsVisible() )
133 {
134 if ( !m_blinkedOut )
135 {
136 // hide it right now and it will be shown the next time it blinks
137 // unless it should be shown all the time in which case just show
138 // it at the new position
139 if ( m_timer.IsRunning() )
140 Blink();
141 else
142 Refresh();
143 }
144 }
145 //else: will be shown at the correct location when it is shown
146 }
147
148 // ----------------------------------------------------------------------------
149 // handling the focus
150 // ----------------------------------------------------------------------------
151
152 void wxCaret::OnSetFocus()
153 {
154 m_hasFocus = TRUE;
155
156 Refresh();
157 }
158
159 void wxCaret::OnKillFocus()
160 {
161 m_hasFocus = FALSE;
162
163 if ( IsVisible() )
164 {
165 // the caret must be shown - otherwise, if it is hidden now, it will
166 // stay so until the focus doesn't return because it won't blink any
167 // more
168 m_blinkedOut = FALSE;
169 }
170
171 Refresh();
172 }
173
174 // ----------------------------------------------------------------------------
175 // drawing the caret
176 // ----------------------------------------------------------------------------
177
178 void wxCaret::Blink()
179 {
180 m_blinkedOut = !m_blinkedOut;
181
182 Refresh();
183 }
184
185 void wxCaret::Refresh()
186 {
187 if ( !m_blinkedOut )
188 {
189 wxClientDC dc(GetWindow());
190 DoDraw(&dc);
191 }
192 else
193 {
194 // FIXME can't be less efficient than this... we probably should use
195 // backing store for the caret instead of leaving all the burden
196 // of correct refresh logic handling to the user code
197
198 // NB: +1 is needed!
199 wxRect rect(m_x, m_y, m_width + 1, m_height + 1);
200 GetWindow()->Refresh(FALSE, &rect);
201 }
202 }
203
204 void wxCaret::DoDraw(wxDC *dc)
205 {
206 dc->SetPen( *wxBLACK_PEN );
207
208 // VZ: Robert's code for I-shaped caret - this is nice but doesn't look
209 // at all the same as the MSW version and I don't know how to indicate
210 // that the window has focus or not with such caret
211 #if 0
212 dc->DrawLine( m_x, m_y, m_x+m_width, m_y );
213 dc->DrawLine( m_x, m_y+m_height, m_x+m_width, m_y+m_height );
214 dc->DrawLine( m_x+(m_width/2), m_y, m_x+(m_width/2), m_y+m_height );
215 // dc->DrawLine( m_x+(m_width/2)+1, m_y, m_x+(m_width/2)+1, m_y+m_height );
216 #else // 1
217 if ( m_hasFocus )
218 dc->SetBrush( *wxBLACK_BRUSH );
219 dc->DrawRectangle( m_x, m_y, m_width, m_height );
220 #endif // 0/1
221 }
222
223 #endif // wxUSE_CARET