Trying to get native header button right
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49331 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -63,7 +63,7 @@ static const int EXPANDER_MARGIN = 4;
|
|||||||
// wxDataViewHeaderWindow
|
// wxDataViewHeaderWindow
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define USE_NATIVE_HEADER_WINDOW 0
|
#define USE_NATIVE_HEADER_WINDOW 1
|
||||||
|
|
||||||
//Below is the compare stuff
|
//Below is the compare stuff
|
||||||
//For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
|
//For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
|
||||||
@@ -134,23 +134,31 @@ public:
|
|||||||
|
|
||||||
~wxDataViewHeaderWindowMSW();
|
~wxDataViewHeaderWindowMSW();
|
||||||
|
|
||||||
|
void OnPaint(wxPaintEvent &event);
|
||||||
|
|
||||||
// called when any column setting is changed and/or changed
|
// called when any column setting is changed and/or changed
|
||||||
// the column count
|
// the column count
|
||||||
virtual void UpdateDisplay();
|
virtual void UpdateDisplay();
|
||||||
|
|
||||||
// called when the main window gets scrolled
|
// called Refresh afterwards
|
||||||
virtual void ScrollWindow(int dx, int dy, const wxRect *rect = NULL);
|
virtual void ScrollWindow(int dx, int dy, const wxRect *rect = NULL);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
|
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
|
||||||
|
|
||||||
virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags);
|
virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags);
|
||||||
|
|
||||||
|
wxSize DoGetBestSize() const;
|
||||||
|
|
||||||
unsigned int GetColumnIdxFromHeader(NMHEADER *nmHDR);
|
unsigned int GetColumnIdxFromHeader(NMHEADER *nmHDR);
|
||||||
|
|
||||||
wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR)
|
wxDataViewColumn *GetColumnFromHeader(NMHEADER *nmHDR)
|
||||||
{ return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
|
{ return GetColumn(GetColumnIdxFromHeader(nmHDR)); }
|
||||||
|
|
||||||
|
int m_scrollOffsetX;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
|
DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindowMSW)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1192,23 +1200,33 @@ int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick);
|
|||||||
|
|
||||||
IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindowMSW, wxWindow)
|
IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindowMSW, wxWindow)
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxDataViewHeaderWindowMSW, wxDataViewHeaderWindowBase)
|
||||||
|
// EVT_PAINT (wxDataViewHeaderWindowMSW::OnPaint)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id,
|
bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id,
|
||||||
const wxPoint &pos, const wxSize &size,
|
const wxPoint &pos, const wxSize &size,
|
||||||
const wxString &name )
|
const wxString &name )
|
||||||
{
|
{
|
||||||
m_owner = parent;
|
m_owner = parent;
|
||||||
|
|
||||||
if ( !CreateControl(parent, id, pos, size, 0, wxDefaultValidator, name) )
|
m_scrollOffsetX = 0;;
|
||||||
return false;
|
|
||||||
|
|
||||||
int x = pos.x == wxDefaultCoord ? 0 : pos.x,
|
int x = pos.x == wxDefaultCoord ? 0 : pos.x,
|
||||||
y = pos.y == wxDefaultCoord ? 0 : pos.y,
|
y = pos.y == wxDefaultCoord ? 0 : pos.y,
|
||||||
w = size.x == wxDefaultCoord ? 1 : size.x,
|
w = size.x == wxDefaultCoord ? 1 : size.x,
|
||||||
h = size.y == wxDefaultCoord ? 22 : size.y;
|
h = size.y == wxDefaultCoord ? 22 : size.y;
|
||||||
|
|
||||||
|
if ( !CreateControl(parent, id, pos, size, 0, wxDefaultValidator, name) )
|
||||||
|
return false;
|
||||||
|
|
||||||
// create the native WC_HEADER window:
|
// create the native WC_HEADER window:
|
||||||
WXHWND hwndParent = (HWND)parent->GetHandle();
|
WXHWND hwndParent = (HWND)parent->GetHandle();
|
||||||
WXDWORD msStyle = WS_CHILD | HDS_BUTTONS | HDS_HORZ | HDS_HOTTRACK | HDS_FULLDRAG;
|
WXDWORD msStyle = WS_CHILD | HDS_BUTTONS | HDS_HORZ | HDS_HOTTRACK | HDS_FULLDRAG;
|
||||||
|
|
||||||
|
if ( m_isShown )
|
||||||
|
msStyle |= WS_VISIBLE;
|
||||||
|
|
||||||
m_hWnd = CreateWindowEx(0,
|
m_hWnd = CreateWindowEx(0,
|
||||||
WC_HEADER,
|
WC_HEADER,
|
||||||
(LPCTSTR) NULL,
|
(LPCTSTR) NULL,
|
||||||
@@ -1231,37 +1249,7 @@ bool wxDataViewHeaderWindowMSW::Create( wxDataViewCtrl *parent, wxWindowID id,
|
|||||||
// the following is required to get the default win's font for
|
// the following is required to get the default win's font for
|
||||||
// header windows and must be done befor sending the HDM_LAYOUT msg
|
// header windows and must be done befor sending the HDM_LAYOUT msg
|
||||||
SetFont(GetFont());
|
SetFont(GetFont());
|
||||||
|
|
||||||
RECT rcParent;
|
|
||||||
HDLAYOUT hdl;
|
|
||||||
WINDOWPOS wp;
|
|
||||||
|
|
||||||
// Retrieve the bounding rectangle of the parent window's
|
|
||||||
// client area, and then request size and position values
|
|
||||||
// from the header control.
|
|
||||||
::GetClientRect((HWND)hwndParent, &rcParent);
|
|
||||||
|
|
||||||
hdl.prc = &rcParent;
|
|
||||||
hdl.pwpos = ℘
|
|
||||||
if (!SendMessage((HWND)m_hWnd, HDM_LAYOUT, 0, (LPARAM) &hdl))
|
|
||||||
{
|
|
||||||
wxLogLastError(_T("SendMessage"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the size, position, and visibility of the header control.
|
|
||||||
SetWindowPos((HWND)m_hWnd,
|
|
||||||
wp.hwndInsertAfter,
|
|
||||||
wp.x, wp.y,
|
|
||||||
wp.cx, wp.cy,
|
|
||||||
wp.flags | SWP_SHOWWINDOW);
|
|
||||||
|
|
||||||
// set our size hints: wxDataViewCtrl will put this wxWindow inside
|
|
||||||
// a wxBoxSizer and in order to avoid super-big header windows,
|
|
||||||
// we need to set our height as fixed
|
|
||||||
SetMinSize(wxSize(-1, wp.cy));
|
|
||||||
SetMaxSize(wxSize(-1, wp.cy));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1270,6 +1258,61 @@ wxDataViewHeaderWindowMSW::~wxDataViewHeaderWindow()
|
|||||||
UnsubclassWin();
|
UnsubclassWin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxSize wxDataViewHeaderWindowMSW::DoGetBestSize() const
|
||||||
|
{
|
||||||
|
return wxSize(80, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDataViewHeaderWindowMSW::OnPaint(wxPaintEvent &event)
|
||||||
|
{
|
||||||
|
wxClientDC dc(this);
|
||||||
|
|
||||||
|
int sortArrow = wxHDR_SORT_ICON_UP;
|
||||||
|
|
||||||
|
wxRect rect(0,0,80,22);
|
||||||
|
|
||||||
|
// Draw an up or down arrow
|
||||||
|
int arrowSpace = 0;
|
||||||
|
if (sortArrow != wxHDR_SORT_ICON_NONE )
|
||||||
|
{
|
||||||
|
wxRect ar = rect;
|
||||||
|
|
||||||
|
// make a rect for the arrow
|
||||||
|
ar.height = 4;
|
||||||
|
ar.width = 8;
|
||||||
|
ar.y += (rect.height - ar.height)/2;
|
||||||
|
ar.x = ar.x + rect.width - 3*ar.width/2;
|
||||||
|
arrowSpace = 3*ar.width/2; // space to preserve when drawing the label
|
||||||
|
|
||||||
|
wxPoint triPt[3];
|
||||||
|
if ( sortArrow & wxHDR_SORT_ICON_UP )
|
||||||
|
{
|
||||||
|
triPt[0].x = ar.width / 2;
|
||||||
|
triPt[0].y = 0;
|
||||||
|
triPt[1].x = ar.width;
|
||||||
|
triPt[1].y = ar.height;
|
||||||
|
triPt[2].x = 0;
|
||||||
|
triPt[2].y = ar.height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
triPt[0].x = 0;
|
||||||
|
triPt[0].y = 0;
|
||||||
|
triPt[1].x = ar.width;
|
||||||
|
triPt[1].y = 0;
|
||||||
|
triPt[2].x = ar.width / 2;
|
||||||
|
triPt[2].y = ar.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxColour c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW);
|
||||||
|
dc.SetPen(wxPen(c));
|
||||||
|
dc.SetBrush(wxBrush(c));
|
||||||
|
dc.DrawPolygon( 3, triPt, ar.x, ar.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
void wxDataViewHeaderWindowMSW::UpdateDisplay()
|
void wxDataViewHeaderWindowMSW::UpdateDisplay()
|
||||||
{
|
{
|
||||||
// remove old columns
|
// remove old columns
|
||||||
@@ -1279,7 +1322,6 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
|
|||||||
// add the updated array of columns to the header control
|
// add the updated array of columns to the header control
|
||||||
unsigned int cols = GetOwner()->GetColumnCount();
|
unsigned int cols = GetOwner()->GetColumnCount();
|
||||||
unsigned int added = 0;
|
unsigned int added = 0;
|
||||||
wxDataViewModel * model = GetOwner()->GetModel();
|
|
||||||
for (unsigned int i = 0; i < cols; i++)
|
for (unsigned int i = 0; i < cols; i++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *col = GetColumn( i );
|
wxDataViewColumn *col = GetColumn( i );
|
||||||
@@ -1294,13 +1336,14 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
|
|||||||
hdi.fmt = HDF_LEFT | HDF_STRING;
|
hdi.fmt = HDF_LEFT | HDF_STRING;
|
||||||
//hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
|
//hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
|
||||||
|
|
||||||
//sorting support
|
if (col->IsSortable() && GetOwner()->GetSortingColumn() == col)
|
||||||
if(model && m_owner->GetSortingColumn() == col)
|
|
||||||
{
|
{
|
||||||
//The Microsoft Comctrl32.dll 6.0 support SORTUP/SORTDOWN, but they are not default
|
//The Microsoft Comctrl32.dll 6.0 support SORTUP/SORTDOWN, but they are not default
|
||||||
//see http://msdn2.microsoft.com/en-us/library/ms649534.aspx for more detail
|
//see http://msdn2.microsoft.com/en-us/library/ms649534.aspx for more detail
|
||||||
//hdi.fmt |= model->GetSortOrderAscending()? HDF_SORTUP:HDF_SORTDOWN;
|
|
||||||
;
|
// if (col->IsSortOrderAscending())
|
||||||
|
// hdi.fmt |= col->IsSortOrderAscending() ? HDF_SORTUP : HDF_SORTDOWN;
|
||||||
|
// ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lParam is reserved for application's use:
|
// lParam is reserved for application's use:
|
||||||
@@ -1505,32 +1548,18 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataViewHeaderWindowMSW::ScrollWindow(int WXUNUSED(dx), int WXUNUSED(dy),
|
void wxDataViewHeaderWindowMSW::ScrollWindow(int dx, int dy, const wxRect *rect )
|
||||||
const wxRect *WXUNUSED(rect))
|
|
||||||
{
|
{
|
||||||
wxSize ourSz = GetClientSize();
|
m_scrollOffsetX += dx;
|
||||||
wxSize ownerSz = m_owner->GetClientSize();
|
|
||||||
|
GetParent()->Layout();
|
||||||
// where should the (logical) origin of this window be placed?
|
|
||||||
int x1 = 0, y1 = 0;
|
|
||||||
m_owner->CalcUnscrolledPosition(0, 0, &x1, &y1);
|
|
||||||
|
|
||||||
// put this window on top of our parent and
|
|
||||||
SetWindowPos((HWND)m_hWnd, HWND_TOP, -x1, 0,
|
|
||||||
ownerSz.GetWidth() + x1, ourSz.GetHeight(),
|
|
||||||
SWP_SHOWWINDOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataViewHeaderWindowMSW::DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
void wxDataViewHeaderWindowMSW::DoSetSize(int x, int y,
|
||||||
int WXUNUSED(w), int WXUNUSED(h),
|
int w, int h,
|
||||||
int WXUNUSED(f))
|
int f)
|
||||||
{
|
{
|
||||||
// the wxDataViewCtrl's internal wxBoxSizer will call this function when
|
wxControl::DoSetSize( x+m_scrollOffsetX, y, w-m_scrollOffsetX, h, f );
|
||||||
// the wxDataViewCtrl window gets resized: the following dummy call
|
|
||||||
// to ScrollWindow() is required in order to get this header window
|
|
||||||
// correctly repainted when it's (horizontally) scrolled:
|
|
||||||
|
|
||||||
ScrollWindow(0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !defined(__WXMSW__)
|
#else // !defined(__WXMSW__)
|
||||||
|
Reference in New Issue
Block a user