~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/generic/caret.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

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