wxComboControl and wxOwnerDrawnComboBox (patch 1479938)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39113 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-05-08 23:42:45 +00:00
parent cd4e32afe7
commit a340b80d8a
27 changed files with 6416 additions and 581 deletions

364
src/generic/combog.cpp Normal file
View File

@@ -0,0 +1,364 @@
/////////////////////////////////////////////////////////////////////////////
// Name: combog.cpp
// Purpose: Generic wxComboControl
// Author: Jaakko Salli
// Modified by:
// Created: Apr-30-2006
// RCS-ID: $Id$
// Copyright: (c) 2005 Jaakko Salli
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_COMBOCONTROL
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/combobox.h"
#include "wx/dcclient.h"
#include "wx/settings.h"
#endif
#include "wx/dcbuffer.h"
#include "wx/combo.h"
// ----------------------------------------------------------------------------
// Some constant adjustments to make the generic more bearable
#if defined(__WXUNIVERSAL__)
#define TEXTCTRLXADJUST 0 // position adjustment for wxTextCtrl, with zero indent
#define TEXTCTRLYADJUST 0
#define TEXTXADJUST 0 // how much is read-only text's x adjusted
#define DEFAULT_DROPBUTTON_WIDTH 19
#elif defined(__WXMSW__)
#define TEXTCTRLXADJUST 2 // position adjustment for wxTextCtrl, with zero indent
#define TEXTCTRLYADJUST 3
#define TEXTXADJUST 0 // how much is read-only text's x adjusted
#define DEFAULT_DROPBUTTON_WIDTH 17
#elif defined(__WXGTK__)
#define TEXTCTRLXADJUST -1 // position adjustment for wxTextCtrl, with zero indent
#define TEXTCTRLYADJUST 0
#define TEXTXADJUST 1 // how much is read-only text's x adjusted
#define DEFAULT_DROPBUTTON_WIDTH 23
#elif defined(__WXMAC__)
#define TEXTCTRLXADJUST 0 // position adjustment for wxTextCtrl, with zero indent
#define TEXTCTRLYADJUST 0
#define TEXTXADJUST 0 // how much is read-only text's x adjusted
#define DEFAULT_DROPBUTTON_WIDTH 19
#else
#define TEXTCTRLXADJUST 0 // position adjustment for wxTextCtrl, with zero indent
#define TEXTCTRLYADJUST 0
#define TEXTXADJUST 0 // how much is read-only text's x adjusted
#define DEFAULT_DROPBUTTON_WIDTH 19
#endif
// ============================================================================
// implementation
// ============================================================================
// Only implement if no native or it wasn't fully featured
#ifndef wxCOMBOCONTROL_FULLY_FEATURED
// ----------------------------------------------------------------------------
// wxGenericComboControl
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxGenericComboControl, wxComboControlBase)
EVT_PAINT(wxGenericComboControl::OnPaintEvent)
EVT_MOUSE_EVENTS(wxGenericComboControl::OnMouseEvent)
END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(wxGenericComboControl, wxComboControlBase)
void wxGenericComboControl::Init()
{
}
bool wxGenericComboControl::Create(wxWindow *parent,
wxWindowID id,
const wxString& value,
const wxPoint& pos,
const wxSize& size,
long style,
const wxValidator& validator,
const wxString& name)
{
// Set border
long border = style & wxBORDER_MASK;
if ( !border )
{
#if defined(__WXUNIVERSAL__)
border = wxBORDER_SIMPLE;
#elif defined(__WXMSW__)
// For XP, have 1-width custom border, for older version use sunken
if ( wxUxThemeEngine::GetIfActive() )
{
border = wxBORDER_NONE;
m_widthCustomBorder = 1;
}
else
border = wxBORDER_SUNKEN;
#elif defined(__WXGTK__)
border = wxBORDER_NONE;
//m_widthCustomBorder = 2;
m_widthCustomBorder = 1;
#else
border = wxBORDER_SIMPLE;
#endif
style = (style & ~(wxBORDER_MASK)) | border;
}
#if defined(__WXGTK__)
Customize( wxCC_BUTTON_OUTSIDE_BORDER |
wxCC_NO_TEXT_AUTO_SELECT );
#endif
if ( style & wxCC_STD_BUTTON )
m_iFlags |= wxCC_POPUP_ON_MOUSE_UP;
// create main window
if ( !wxComboControlBase::Create(parent,
id,
value,
wxDefaultPosition,
wxDefaultSize,
style | wxFULL_REPAINT_ON_RESIZE,
wxDefaultValidator,
name) )
return false;
// Create textctrl, if necessary
CreateTextCtrl( wxNO_BORDER, validator );
// Add keyboard input handlers for main control and textctrl
InstallInputHandlers( true );
// Set background
SetBackgroundStyle( wxBG_STYLE_CUSTOM ); // for double-buffering
// SetSize should be called last
SetSize(pos.x,pos.y,size.x,size.y);
return true;
}
wxGenericComboControl::~wxGenericComboControl()
{
}
void wxGenericComboControl::OnResize()
{
// Recalculates button and textctrl areas
CalculateAreas(DEFAULT_DROPBUTTON_WIDTH);
#if 0
// Move separate button control, if any, to correct position
if ( m_btn )
{
wxSize sz = GetClientSize();
m_btn->SetSize( m_btnArea.x + m_btnSpacingX,
(sz.y-m_btnSize.y)/2,
m_btnSize.x,
m_btnSize.y );
}
#endif
// Move textctrl, if any, accordingly
PositionTextCtrl( TEXTCTRLXADJUST, TEXTCTRLYADJUST );
}
void wxGenericComboControl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
{
wxSize sz = GetClientSize();
wxBufferedPaintDC dc(this,GetBufferBitmap(sz));
const wxRect& rectb = m_btnArea;
wxRect rect = m_tcArea;
// artificial simple border
if ( m_widthCustomBorder )
{
int customBorder = m_widthCustomBorder;
// Set border colour
wxPen pen1( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT),
customBorder,
wxSOLID );
dc.SetPen( pen1 );
// area around both controls
wxRect rect2(0,0,sz.x,sz.y);
if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
{
rect2 = m_tcArea;
if ( customBorder == 1 )
{
rect2.Inflate(1);
}
else
{
#ifdef __WXGTK__
rect2.x -= 1;
rect2.y -= 1;
#else
rect2.x -= customBorder;
rect2.y -= customBorder;
#endif
rect2.width += 1 + customBorder;
rect2.height += 1 + customBorder;
}
}
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle(rect2);
}
wxColour winCol = GetBackgroundColour();
dc.SetBrush(winCol);
dc.SetPen(winCol);
//wxLogDebug(wxT("hei: %i tcy: %i tchei: %i"),GetClientSize().y,m_tcArea.y,m_tcArea.height);
//wxLogDebug(wxT("btnx: %i tcx: %i tcwid: %i"),m_btnArea.x,m_tcArea.x,m_tcArea.width);
// clear main background
dc.DrawRectangle(rect);
if ( !m_btn )
// Standard button rendering
DrawButton(dc,rectb,true);
// paint required portion on the control
if ( !m_text || m_widthCustomPaint )
{
wxASSERT( m_widthCustomPaint >= 0 );
// this is intentionally here to allow drawed rectangle's
// right edge to be hidden
if ( m_text )
rect.width = m_widthCustomPaint;
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
m_popupInterface->PaintComboControl(dc,rect);
}
}
void wxGenericComboControl::OnMouseEvent( wxMouseEvent& event )
{
bool isOnButtonArea = m_btnArea.Inside(event.m_x,event.m_y);
int handlerFlags = isOnButtonArea ? wxCC_MF_ON_BUTTON : 0;
// Preprocessing fabricates double-clicks and prevents
// (it may also do other common things in future)
if ( PreprocessMouseEvent(event,handlerFlags) )
return;
if ( (m_windowStyle & (wxCC_SPECIAL_DCLICK|wxCB_READONLY)) == wxCB_READONLY )
{
// if no textctrl and no special double-click, then the entire control acts
// as a button
handlerFlags |= wxCC_MF_ON_BUTTON;
if ( HandleButtonMouseEvent(event,handlerFlags) )
return;
}
else
{
if ( isOnButtonArea || HasCapture() )
{
if ( HandleButtonMouseEvent(event,handlerFlags) )
return;
}
else if ( m_btnState )
{
// otherwise need to clear the hover status
m_btnState = 0;
RefreshRect(m_btnArea);
}
}
//
// This will handle left_down and left_dclick events outside button in a Windows/GTK-like manner.
// See header file for further information on this method.
HandleNormalMouseEvent(event);
}
#ifdef __WXUNIVERSAL__
bool wxGenericComboControl::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
bool processed = false;
if ( action == wxACTION_COMBOBOX_POPUP )
{
if ( !m_isPopupShown )
{
ShowPopup();
processed = true;
}
}
else if ( action == wxACTION_COMBOBOX_DISMISS )
{
if ( m_isPopupShown )
{
HidePopup();
processed = true;
}
}
if ( !processed )
{
// pass along
return wxControl::PerformAction(action, numArg, strArg);
}
return true;
}
#endif // __WXUNIVERSAL__
// If native wxComboControl was not defined, then prepare a simple
// front-end so that wxRTTI works as expected.
#ifndef _WX_COMBOCONTROL_H_
IMPLEMENT_DYNAMIC_CLASS(wxComboControl, wxGenericComboControl)
#endif
#endif // !wxCOMBOCONTROL_FULLY_FEATURED
#endif // wxUSE_COMBOCONTROL