combog.cpp

Go to the documentation of this file.
00001 // $Id: combog.cpp 1417 2006-07-06 19:56:27Z alex $
00002 /* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */
00003 // The following line makes normalize.pl skip type fixing
00004 /* SKIPFIXTYPES: START */
00005 
00007 // Name:        combog.cpp
00008 // Purpose:     Generic wxComboControl
00009 // Author:      Jaakko Salli
00010 // Modified by:
00011 // Created:     Apr-30-2006
00012 // RCS-ID:
00013 // Copyright:   (c) 2005 Jaakko Salli
00014 // Licence:     wxWindows licence
00016 
00017 // ============================================================================
00018 // declarations
00019 // ============================================================================
00020 
00021 // ----------------------------------------------------------------------------
00022 // headers
00023 // ----------------------------------------------------------------------------
00024 
00025 #include "combog.h"
00026 
00027 #if wxXTRA_COMBOCTRL
00028 #include "combo.h"
00029 #include <wx/dcbuffer.h>
00030 
00031 // ----------------------------------------------------------------------------
00032 // Some constant adjustments to make the generic more bearable
00033 
00034 #if defined(__WXUNIVERSAL__)
00035 
00036 #define TEXTCTRLXADJUST                 0 // position adjustment for wxTextCtrl, with zero indent
00037 #define TEXTCTRLYADJUST                 0
00038 #define TEXTXADJUST                     0 // how much is read-only text's x adjusted
00039 #define DEFAULT_DROPBUTTON_WIDTH        19
00040 
00041 #elif defined(__WXMSW__)
00042 
00043 #define TEXTCTRLXADJUST                 2 // position adjustment for wxTextCtrl, with zero indent
00044 #define TEXTCTRLYADJUST                 3
00045 #define TEXTXADJUST                     0 // how much is read-only text's x adjusted
00046 #define DEFAULT_DROPBUTTON_WIDTH        17
00047 
00048 #elif defined(__WXGTK__)
00049 
00050 #define TEXTCTRLXADJUST                 -1 // position adjustment for wxTextCtrl, with zero indent
00051 #define TEXTCTRLYADJUST                 0
00052 #define TEXTXADJUST                     1 // how much is read-only text's x adjusted
00053 #define DEFAULT_DROPBUTTON_WIDTH        23
00054 
00055 #elif defined(__WXMAC__)
00056 
00057 #define TEXTCTRLXADJUST                 0 // position adjustment for wxTextCtrl, with zero indent
00058 #define TEXTCTRLYADJUST                 0
00059 #define TEXTXADJUST                     0 // how much is read-only text's x adjusted
00060 #define DEFAULT_DROPBUTTON_WIDTH        19
00061 
00062 #else
00063 
00064 #define TEXTCTRLXADJUST                 0 // position adjustment for wxTextCtrl, with zero indent
00065 #define TEXTCTRLYADJUST                 0
00066 #define TEXTXADJUST                     0 // how much is read-only text's x adjusted
00067 #define DEFAULT_DROPBUTTON_WIDTH        19
00068 
00069 #endif
00070 
00071 
00072 // ============================================================================
00073 // implementation
00074 // ============================================================================
00075 
00076 // Only implement if no native or it wasn't fully featured
00077 #ifndef wxCOMBOCONTROL_FULLY_FEATURED
00078 
00079 
00080 // ----------------------------------------------------------------------------
00081 // wxGenericComboControl
00082 // ----------------------------------------------------------------------------
00083 
00084 BEGIN_EVENT_TABLE(wxGenericComboControl, wxComboCtrlBase)
00085     EVT_PAINT(wxGenericComboControl::OnPaintEvent)
00086     EVT_MOUSE_EVENTS(wxGenericComboControl::OnMouseEvent)
00087 END_EVENT_TABLE()
00088 
00089 
00090 IMPLEMENT_DYNAMIC_CLASS(wxGenericComboControl, wxComboCtrlBase)
00091 
00092 void wxGenericComboControl::Init()
00093 {
00094 }
00095 
00096 bool wxGenericComboControl::Create(wxWindow *parent,
00097                                    wxWindowID id,
00098                                    const wxString& value,
00099                                    const wxPoint& pos,
00100                                    const wxSize& size,
00101                                    long style,
00102                                    const wxValidator& validator,
00103                                    const wxString& name)
00104 {
00105 
00106     // Set border
00107     long border = style & wxBORDER_MASK;
00108 
00109     if ( !border )
00110     {
00111 #if defined(__WXUNIVERSAL__)
00112         border = wxBORDER_SIMPLE;
00113 #elif defined(__WXMSW__)
00114         // For XP, have 1-width custom border, for older version use sunken
00115         if ( wxUxThemeEngine::GetIfActive() )
00116         {
00117             border = wxBORDER_NONE;
00118             m_widthCustomBorder = 1;
00119         }
00120         else
00121             border = wxBORDER_SUNKEN;
00122 #elif defined(__WXGTK__)
00123         border = wxBORDER_NONE;
00124         //m_widthCustomBorder = 2;
00125         m_widthCustomBorder = 1;
00126 #else
00127         border = wxBORDER_SIMPLE;
00128 #endif
00129 
00130         style = (style & ~(wxBORDER_MASK)) | border;
00131     }
00132 
00133 #if defined(__WXGTK__)
00134     Customize( wxCC_BUTTON_OUTSIDE_BORDER |
00135                wxCC_NO_TEXT_AUTO_SELECT );
00136 #endif
00137 
00138     if ( style & wxCC_STD_BUTTON )
00139         m_iFlags |= wxCC_POPUP_ON_MOUSE_UP;
00140 
00141     // create main window
00142     if ( !wxComboCtrlBase::Create(parent,
00143                                   id,
00144                                   value,
00145                                   pos,
00146                                   size,
00147                                   style | wxFULL_REPAINT_ON_RESIZE,
00148                                   wxDefaultValidator,
00149                                   name) )
00150         return false;
00151 
00152     // Create textctrl, if necessary
00153     CreateTextCtrl( wxNO_BORDER, validator );
00154 
00155     // Add keyboard input handlers for main control and textctrl
00156     InstallInputHandlers( true );
00157 
00158     // Set background
00159     SetBackgroundStyle( wxBG_STYLE_CUSTOM ); // for double-buffering
00160 
00161     // SetBestSize should be called last
00162     SetBestSize(size);
00163 
00164     return true;
00165 }
00166 
00167 wxGenericComboControl::~wxGenericComboControl()
00168 {
00169 }
00170 
00171 void wxGenericComboControl::OnResize()
00172 {
00173 
00174     // Recalculates button and textctrl areas
00175     CalculateAreas(DEFAULT_DROPBUTTON_WIDTH);
00176 
00177 #if 0
00178     // Move separate button control, if any, to correct position
00179     if ( m_btn )
00180     {
00181         wxSize sz = GetClientSize();
00182         m_btn->SetSize( m_btnArea.x + m_btnSpacingX,
00183                         (sz.y-m_btnSize.y)/2,
00184                         m_btnSize.x,
00185                         m_btnSize.y );
00186     }
00187 #endif
00188 
00189     // Move textctrl, if any, accordingly
00190     PositionTextCtrl( TEXTCTRLXADJUST, TEXTCTRLYADJUST );
00191 }
00192 
00193 void wxGenericComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
00194 {
00195     wxSize sz = GetClientSize();
00196     wxBufferedPaintDC dc(this,GetBufferBitmap(sz));
00197 
00198     const wxRect& rectb = m_btnArea;
00199     wxRect rect = m_tcArea;
00200 
00201     // artificial simple border
00202     if ( m_widthCustomBorder )
00203     {
00204         int customBorder = m_widthCustomBorder;
00205 
00206         // Set border colour
00207         wxPen pen1( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT),
00208                     customBorder,
00209                     wxSOLID );
00210         dc.SetPen( pen1 );
00211 
00212         // area around both controls
00213         wxRect rect2(0,0,sz.x,sz.y);
00214         if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
00215         {
00216             rect2 = m_tcArea;
00217             if ( customBorder == 1 )
00218             {
00219                 rect2.Inflate(1);
00220             }
00221             else
00222             {
00223             #ifdef __WXGTK__
00224                 rect2.x -= 1;
00225                 rect2.y -= 1;
00226             #else
00227                 rect2.x -= customBorder;
00228                 rect2.y -= customBorder;
00229             #endif
00230                 rect2.width += 1 + customBorder;
00231                 rect2.height += 1 + customBorder;
00232             }
00233         }
00234 
00235         dc.SetBrush( *wxTRANSPARENT_BRUSH );
00236         dc.DrawRectangle(rect2);
00237     }
00238 
00239     wxColour winCol = GetBackgroundColour();
00240     dc.SetBrush(winCol);
00241     dc.SetPen(winCol);
00242 
00243     //wxLogDebug(wxT("hei: %i tcy: %i tchei: %i"),GetClientSize().y,m_tcArea.y,m_tcArea.height);
00244     //wxLogDebug(wxT("btnx: %i tcx: %i tcwid: %i"),m_btnArea.x,m_tcArea.x,m_tcArea.width);
00245 
00246     // clear main background
00247     dc.DrawRectangle(rect);
00248 
00249     if ( !m_btn )
00250         // Standard button rendering
00251         DrawButton(dc,rectb,true);
00252 
00253     // paint required portion on the control
00254     if ( (!m_text || m_widthCustomPaint) )
00255     {
00256         wxASSERT( m_widthCustomPaint >= 0 );
00257 
00258         // this is intentionally here to allow drawed rectangle's
00259         // right edge to be hidden
00260         if ( m_text )
00261             rect.width = m_widthCustomPaint;
00262 
00263         dc.SetFont( GetFont() );
00264 
00265         dc.SetClippingRegion(rect);
00266         if ( m_popupInterface )
00267             m_popupInterface->PaintComboControl(dc,rect);
00268         else
00269             wxComboPopup::DefaultPaintComboControl(this,dc,rect);
00270     }
00271 }
00272 
00273 void wxGenericComboControl::OnMouseEvent( wxMouseEvent& event )
00274 {
00275     bool isOnButtonArea = m_btnArea.Inside(event.m_x,event.m_y);
00276     int handlerFlags = isOnButtonArea ? wxCC_MF_ON_BUTTON : 0;
00277 
00278     // Preprocessing fabricates double-clicks and prevents
00279     // (it may also do other common things in future)
00280     if ( PreprocessMouseEvent(event,handlerFlags) )
00281         return;
00282 
00283 #ifdef __WXMSW__
00284     const bool ctrlIsButton = true;
00285 #else
00286     const bool ctrlIsButton = false;
00287 #endif
00288 
00289     if ( ctrlIsButton &&
00290          (m_windowStyle & (wxCC_SPECIAL_DCLICK|wxCB_READONLY)) == wxCB_READONLY )
00291     {
00292         // if no textctrl and no special double-click, then the entire control acts
00293         // as a button
00294         handlerFlags |= wxCC_MF_ON_BUTTON;
00295         if ( HandleButtonMouseEvent(event,handlerFlags) )
00296             return;
00297     }
00298     else
00299     {
00300         if ( isOnButtonArea || HasCapture() )
00301         {
00302             if ( HandleButtonMouseEvent(event,handlerFlags) )
00303                 return;
00304         }
00305         else if ( m_btnState )
00306         {
00307             // otherwise need to clear the hover status
00308             m_btnState = 0;
00309             RefreshRect(m_btnArea);
00310         }
00311     }
00312 
00313     //
00314     // This will handle left_down and left_dclick events outside button in a Windows/GTK-like manner.
00315     // See header file for further information on this method.
00316     HandleNormalMouseEvent(event);
00317 
00318 }
00319 
00320 #ifdef __WXUNIVERSAL__
00321 
00322 bool wxGenericComboControl::PerformAction(const wxControlAction& action,
00323                                           long numArg,
00324                                           const wxString& strArg)
00325 {
00326     bool processed = false;
00327     if ( action == wxACTION_COMBOBOX_POPUP )
00328     {
00329         if ( !m_isPopupShown )
00330         {
00331             ShowPopup();
00332 
00333             processed = true;
00334         }
00335     }
00336     else if ( action == wxACTION_COMBOBOX_DISMISS )
00337     {
00338         if ( m_isPopupShown )
00339         {
00340             HidePopup();
00341 
00342             processed = true;
00343         }
00344     }
00345 
00346     if ( !processed )
00347     {
00348         // pass along
00349         return wxControl::PerformAction(action, numArg, strArg);
00350     }
00351 
00352     return true;
00353 }
00354 
00355 #endif // __WXUNIVERSAL__
00356 
00357 // If native wxComboControl was not defined, then prepare a simple
00358 // front-end so that wxRTTI works as expected.
00359 #ifndef _WXXTRA_COMBOCONTROL_H_
00360 IMPLEMENT_DYNAMIC_CLASS(wxComboCtrl, wxGenericComboControl)
00361 #endif
00362 
00363 #endif // !wxCOMBOCONTROL_FULLY_FEATURED
00364 
00365 #endif // wxUSE_COMBOCONTROL

Generated on Sat Nov 10 03:49:00 2007 for Camelot by  doxygen 1.4.4