X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/29435d814db9ce39543481543de199519e26175e..404b319a85dadd7decf7a5a5331020520031a41c:/src/os2/toolbar.cpp diff --git a/src/os2/toolbar.cpp b/src/os2/toolbar.cpp index 4ed0456193..b2fa1e4840 100644 --- a/src/os2/toolbar.cpp +++ b/src/os2/toolbar.cpp @@ -1,9 +1,9 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: toolbar.cpp +// Name: src/os2/toolbar.cpp // Purpose: wxToolBar // Author: David Webster // Modified by: -// Created: 10/17/99 +// Created: 06/30/02 // RCS-ID: $Id$ // Copyright: (c) David Webster // Licence: wxWindows licence @@ -12,630 +12,1175 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE + +#include "wx/toolbar.h" + #ifndef WX_PRECOMP -#include "wx/wx.h" + #include "wx/settings.h" + #include "wx/window.h" + #include "wx/frame.h" + #include "wx/app.h" + #include "wx/dcclient.h" + #include "wx/dcmemory.h" #endif -#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR +#include "wx/tooltip.h" +#include "wx/os2/dcclient.h" -#include "malloc.h" -#define INCL_PM -#include +bool wxToolBar::m_bInitialized = false; -#include "wx/toolbar.h" -#include "wx/app.h" -#include "wx/os2/private.h" - -// Styles -#ifndef TBSTYLE_FLAT -#define TBSTYLE_LIST 0x1000 -#define TBSTYLE_FLAT 0x0800 -#define TBSTYLE_TRANSPARENT 0x8000 -#endif - // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- -// Messages -#ifndef TB_GETSTYLE -#define TB_GETSTYLE (WM_USER + 57) -#define TB_SETSTYLE (WM_USER + 56) -#endif +class wxToolBarTool : public wxToolBarToolBase +{ +public: + inline wxToolBarTool( wxToolBar* pTbar + ,int vId + ,const wxString& rsLabel + ,const wxBitmap& rBitmap1 + ,const wxBitmap& rBitmap2 + ,wxItemKind vKind + ,wxObject* pClientData + ,const wxString& rsShortHelpString + ,const wxString& rsLongHelpString + ) : wxToolBarToolBase( pTbar + ,vId + ,rsLabel + ,rBitmap1 + ,rBitmap2 + ,vKind + ,pClientData + ,rsShortHelpString + ,rsLongHelpString + ) + { + } + + inline wxToolBarTool( wxToolBar* pTbar + ,wxControl* pControl + ,const wxString& label + ) : wxToolBarToolBase( pTbar + ,pControl + ,label + ) + { + } -/* Hint from a newsgroup for custom flatbar drawing: -Set the TBSTYLE_CUSTOMERASE style, then handle the -NM_CUSTOMDRAW message and do your custom drawing. -*/ + void SetSize(const wxSize& rSize) + { + m_vWidth = rSize.x; + m_vHeight = rSize.y; + } -#define DEFAULTBITMAPX 16 -#define DEFAULTBITMAPY 15 -#define DEFAULTBUTTONX 24 -#define DEFAULTBUTTONY 24 -#define DEFAULTBARHEIGHT 27 + wxCoord GetWidth(void) const { return m_vWidth; } + wxCoord GetHeight(void) const { return m_vHeight; } -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) -#endif + wxCoord m_vX; + wxCoord m_vY; + wxCoord m_vWidth; + wxCoord m_vHeight; +}; // end of CLASS wxToolBarTool + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) + EVT_SIZE(wxToolBar::OnSize) + EVT_PAINT(wxToolBar::OnPaint) + EVT_KILL_FOCUS(wxToolBar::OnKillFocus) EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) - EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged) + EVT_TIMER(-1, wxToolBar::OnTimer) END_EVENT_TABLE() -static void wxMapBitmap(HBITMAP hBitmap, int width, int height); +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// tool bar tools creation +// ---------------------------------------------------------------------------- + +wxToolBarToolBase* wxToolBar::CreateTool( + int nId +, const wxString& rsLabel +, const wxBitmap& rBmpNormal +, const wxBitmap& rBmpDisabled +, wxItemKind eKind +, wxObject* pClientData +, const wxString& rsShortHelp +, const wxString& rsLongHelp +) +{ + return new wxToolBarTool( this + ,nId + ,rsLabel + ,rBmpNormal + ,rBmpDisabled + ,eKind + ,pClientData + ,rsShortHelp + ,rsLongHelp + ); +} // end of wxToolBarSimple::CreateTool + +wxToolBarToolBase *wxToolBar::CreateTool( + wxControl* pControl +, const wxString& label +) +{ + return new wxToolBarTool( this + ,pControl + ,label + ); +} // end of wxToolBarSimple::CreateTool + +// ---------------------------------------------------------------------------- +// wxToolBarSimple creation +// ---------------------------------------------------------------------------- -wxToolBar::wxToolBar() +void wxToolBar::Init() { - m_maxWidth = -1; - m_maxHeight = -1; - m_hBitmap = 0; - m_defaultWidth = DEFAULTBITMAPX; - m_defaultHeight = DEFAULTBITMAPY; -} - -bool wxToolBar::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) + m_nCurrentRowsOrColumns = 0; + + m_vLastX = m_vLastY = 0; + m_vMaxWidth = m_vMaxHeight = 0; + m_nPressedTool = m_nCurrentTool = -1; + m_vXPos = m_vYPos = -1; + m_vTextX = m_vTextY = 0; + + m_toolPacking = 1; + m_toolSeparation = 5; + + m_defaultWidth = 16; + m_defaultHeight = 15; + + m_pToolTip = NULL; +} // end of wxToolBar::Init + +wxToolBarToolBase* wxToolBar::DoAddTool( + int vId +, const wxString& rsLabel +, const wxBitmap& rBitmap +, const wxBitmap& rBmpDisabled +, wxItemKind eKind +, const wxString& rsShortHelp +, const wxString& rsLongHelp +, wxObject* pClientData +, wxCoord vXPos +, wxCoord vYPos +) { - m_hWnd = 0; - m_backgroundColour = *wxWHITE; //TODO: wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), -// GetGValue(GetSysColor(COLOR_BTNFACE)), -// GetBValue(GetSysColor(COLOR_BTNFACE))); - m_foregroundColour = *wxBLACK ; - - wxASSERT_MSG( (style & wxTB_VERTICAL) == 0, - wxT("Sorry, wxToolBar under Windows 95 only " - "supports horizontal orientation.") ); - - m_maxWidth = -1; - m_maxHeight = -1; - - m_hBitmap = 0; - - m_defaultWidth = DEFAULTBITMAPX; - m_defaultHeight = DEFAULTBITMAPY; - SetName(name); - - m_windowStyle = style; - - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - SetParent(parent); - - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; - - if (width <= 0) - width = 100; - if (height <= 0) - height = 30; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - m_windowId = (id < 0 ? NewControlId() : id); - DWORD msflags = 0; -// TODO: -/* - if (style & wxBORDER) - msflags |= WS_BORDER; - msflags |= WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS; - - if (style & wxTB_FLAT) - { - if (wxTheApp->GetComCtl32Version() > 400) - msflags |= TBSTYLE_FLAT; - } - - bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; - - // Even with extended styles, need to combine with WS_BORDER - // for them to look right. - if ( want3D || wxStyleHasBorder(m_windowStyle) ) - msflags |= WS_BORDER; - - // Create the toolbar control. - HWND hWndToolbar = CreateWindowEx - ( - exStyle, // Extended styles. - TOOLBARCLASSNAME, // Class name for the toolbar. - wxT(""), // No default text. - msflags, // Styles - x, y, width, height, // Standard toolbar size and position. - (HWND) parent->GetHWND(), // Parent window of the toolbar. - (HMENU)m_windowId, // Toolbar ID. - wxGetInstance(), // Current instance. - NULL // No class data. - ); - - wxCHECK_MSG( hWndToolbar, FALSE, wxT("Toolbar creation failed") ); - - // Toolbar-specific initialisation - ::SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, - (WPARAM)sizeof(TBBUTTON), (LPARAM)0); - m_hWnd = (WXHWND) hWndToolbar; - - if (parent) - parent->AddChild(this); - - SubclassWin((WXHWND)hWndToolbar); - - return TRUE; -*/ - return FALSE; -} + // + // Rememeber the position for DoInsertTool() + // + m_vXPos = vXPos; + m_vYPos = vYPos; + + return wxToolBarBase::DoAddTool( vId + ,rsLabel + ,rBitmap + ,rBmpDisabled + ,eKind + ,rsShortHelp + ,rsLongHelp + ,pClientData + ,vXPos + ,vYPos + ); +} // end of wxToolBar::DoAddTool + +bool wxToolBar::DeleteTool( + int nId +) +{ + bool bOk = wxToolBarBase::DeleteTool(nId); -wxToolBar::~wxToolBar() + if (bOk) + { + Realize(); + } + return bOk; +} // end of wxToolBar::DeleteTool + +bool wxToolBar::DeleteToolByPos( + size_t nPos +) { - UnsubclassWin(); + bool bOk = wxToolBarBase::DeleteToolByPos(nPos); - if (m_hBitmap) - { -// ::DeleteObject((HBITMAP) m_hBitmap); - m_hBitmap = 0; - } -} + if (bOk) + { + Realize(); + } + return bOk; +} // end of wxToolBar::DeleteTool -bool wxToolBar::CreateTools() +wxToolBarToolBase* wxToolBar::InsertControl( + size_t nPos +, wxControl* pControl +) { - if (m_tools.Number() == 0) - return FALSE; - - HBITMAP oldToolBarBitmap = (HBITMAP) m_hBitmap; - - int totalBitmapWidth = (int)(m_defaultWidth * m_tools.Number()); - int totalBitmapHeight = (int)m_defaultHeight; - -// TODO: -/* - // Create a bitmap for all the tool bitmaps - HDC dc = ::GetDC(NULL); - m_hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap(dc, totalBitmapWidth, totalBitmapHeight); - ::ReleaseDC(NULL, dc); - - // Now blit all the tools onto this bitmap - HDC memoryDC = ::CreateCompatibleDC(NULL); - HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, (HBITMAP) m_hBitmap); - - HDC memoryDC2 = ::CreateCompatibleDC(NULL); - int x = 0; - wxNode *node = m_tools.First(); - int noButtons = 0; - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok() && tool->m_bitmap1.GetHBITMAP()) - { -// wxPalette *palette = tool->m_bitmap1->GetPalette(); - - HBITMAP oldBitmap2 = (HBITMAP) ::SelectObject(memoryDC2, (HBITMAP) tool->m_bitmap1.GetHBITMAP()); - // int bltResult = - BitBlt(memoryDC, x, 0, (int) m_defaultWidth, (int) m_defaultHeight, memoryDC2, - 0, 0, SRCCOPY); - ::SelectObject(memoryDC2, oldBitmap2); - x += (int)m_defaultWidth; - noButtons ++; - } - node = node->Next(); - } - ::SelectObject(memoryDC, oldBitmap); - ::DeleteDC(memoryDC); - ::DeleteDC(memoryDC2); - - // Map to system colours - wxMapBitmap((HBITMAP) m_hBitmap, totalBitmapWidth, totalBitmapHeight); - - if ( oldToolBarBitmap ) - { - TBREPLACEBITMAP replaceBitmap; - replaceBitmap.hInstOld = NULL; - replaceBitmap.hInstNew = NULL; - replaceBitmap.nIDOld = (UINT) oldToolBarBitmap; - replaceBitmap.nIDNew = (UINT) (HBITMAP) m_hBitmap; - replaceBitmap.nButtons = noButtons; - if (::SendMessage((HWND) GetHWND(), TB_REPLACEBITMAP, (WPARAM) 0, (LPARAM) &replaceBitmap) == -1) - { - wxFAIL_MSG(wxT("Could not add bitmap to toolbar")); - } - - ::DeleteObject((HBITMAP) oldToolBarBitmap); - - // Now delete all the buttons - int i = 0; - while ( TRUE ) - { - // TODO: What about separators???? They don't have an id! - if ( ! ::SendMessage( (HWND) GetHWND(), TB_DELETEBUTTON, i, 0 ) ) - break; - } - } - else - { - TBADDBITMAP addBitmap; - addBitmap.hInst = 0; - addBitmap.nID = (UINT)m_hBitmap; - if (::SendMessage((HWND) GetHWND(), TB_ADDBITMAP, (WPARAM) noButtons, (LPARAM) &addBitmap) == -1) - { - wxFAIL_MSG(wxT("Could not add bitmap to toolbar")); - } - } - - // Now add the buttons. - TBBUTTON buttons[50]; - - node = m_tools.First(); - int i = 0; - int bitmapId = 0; - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) - { - buttons[i].iBitmap = 0; - buttons[i].idCommand = 0; - - buttons[i].fsState = TBSTATE_ENABLED; - buttons[i].fsStyle = TBSTYLE_SEP; - buttons[i].dwData = 0L; - buttons[i].iString = 0; + wxToolBarToolBase* pTool = wxToolBarBase::InsertControl( nPos + ,pControl + ); + if (m_bInitialized) + { + Realize(); + Refresh(); } - else + return pTool; +} // end of wxToolBar::InsertControl + +wxToolBarToolBase* wxToolBar::InsertSeparator( + size_t nPos +) +{ + wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos); + + if (m_bInitialized) + { + Realize(); + Refresh(); + } + return pTool; +} // end of wxToolBar::InsertSeparator + +wxToolBarToolBase* wxToolBar::InsertTool( + size_t nPos +, int nId +, const wxString& rsLabel +, const wxBitmap& rBitmap +, const wxBitmap& rBmpDisabled +, wxItemKind eKind +, const wxString& rsShortHelp +, const wxString& rsLongHelp +, wxObject* pClientData +) +{ + wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos + ,nId + ,rsLabel + ,rBitmap + ,rBmpDisabled + ,eKind + ,rsShortHelp + ,rsLongHelp + ,pClientData + ); + if (m_bInitialized) { - buttons[i].iBitmap = bitmapId; - buttons[i].idCommand = tool->m_index; + Realize(); + Refresh(); + } + return pTool; +} // end of wxToolBar::InsertTool + +bool wxToolBar::DoInsertTool( size_t WXUNUSED(nPos), + wxToolBarToolBase* pToolBase ) +{ + wxToolBarTool* pTool = (wxToolBarTool *)pToolBase; + + pTool->m_vX = m_vXPos; + if (pTool->m_vX == -1) + pTool->m_vX = m_xMargin; - buttons[i].fsState = 0; - if (tool->m_enabled) - buttons[i].fsState |= TBSTATE_ENABLED; - if (tool->m_toggleState) - buttons[i].fsState |= TBSTATE_CHECKED; - buttons[i].fsStyle = tool->m_isToggle ? TBSTYLE_CHECK : TBSTYLE_BUTTON; - buttons[i].dwData = 0L; - buttons[i].iString = 0; + pTool->m_vY = m_vYPos; + if (pTool->m_vY == -1) + pTool->m_vX = m_yMargin; - bitmapId ++; + pTool->SetSize(GetToolSize()); + + if (pTool->IsButton()) + { + // + // Calculate reasonable max size in case Layout() not called + // + if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth) + m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin)); + + if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight) + m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin)); } + return true; +} // end of wxToolBar::DoInsertTool - i ++; - node = node->Next(); - } +bool wxToolBar::DoDeleteTool( size_t WXUNUSED(nPos), + wxToolBarToolBase* pTool ) +{ + pTool->Detach(); + Refresh(); + return true; +} // end of wxToolBar::DoDeleteTool + +bool wxToolBar::Create( wxWindow* pParent, + wxWindowID vId, + const wxPoint& rPos, + const wxSize& rSize, + long lStyle, + const wxString& rsName ) +{ + if ( !wxWindow::Create( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rsName + )) + return false; + + // Set it to grey (or other 3D face colour) + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR)); + SetFont(*wxSMALL_FONT); + + if (GetWindowStyleFlag() & (wxTB_LEFT | wxTB_RIGHT)) + { + m_vLastX = 7; + m_vLastY = 3; - long rc = ::SendMessage((HWND) GetHWND(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)& buttons); + m_maxRows = 32000; // a lot + m_maxCols = 1; + } + else + { + m_vLastX = 3; + m_vLastY = 7; - wxCHECK_MSG( rc, FALSE, wxT("failed to add buttons to the toolbar") ); + m_maxRows = 1; + m_maxCols = 32000; // a lot + } + SetCursor(*wxSTANDARD_CURSOR); + + // + // The toolbar's tools, if they have labels and the winTB_TEXT + // style is set, then we need to take into account the size of + // the text when drawing tool bitmaps and the text + // + if (HasFlag(wxTB_TEXT)) + { + wxClientDC vDC(this); - (void)::SendMessage((HWND) GetHWND(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0); + vDC.SetFont(GetFont()); + vDC.GetTextExtent( wxT("XXXX") + ,&m_vTextX + ,&m_vTextY + ); + } - SetRows(m_maxRows); -*/ - return TRUE; -} + // + // Position it + // + int nX = rPos.x; + int nY = rPos.y; + int nWidth = rSize.x; + int nHeight = rSize.y; -bool wxToolBar::OS2Command(WXUINT cmd, WXWORD id) + if (lStyle & (wxTB_TOP | wxTB_BOTTOM)) + { + if (nWidth <= 0) + { + nWidth = pParent->GetClientSize().x; + } + if (nHeight <= 0) + { + if (lStyle & wxTB_TEXT) + nHeight = m_defaultHeight + m_vTextY; + else + nHeight = m_defaultHeight; + } + } + else + { + if (nHeight <= 0) + { + nHeight = pParent->GetClientSize().y; + } + if (nWidth <= 0) + { + if (lStyle & wxTB_TEXT) + nWidth = m_vTextX + (int)(m_vTextX/2); // a little margin + else + nWidth = m_defaultWidth + (int)(m_defaultWidth/2); // a little margin + } + } + if (nX < 0) + nX = 0; + if (nY < 0) + nY = 0; + + SetSize( nX + ,nY + ,nWidth + ,nHeight + ); + return true; +} // end of wxToolBar::Create + +wxToolBar::~wxToolBar() { - wxNode *node = m_tools.Find((long)id); - if (!node) - return FALSE; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); -// TODO: -/* - if (tool->m_isToggle) - tool->m_toggleState = (1 == (1 & (int)::SendMessage((HWND) GetHWND(), TB_GETSTATE, (WPARAM) id, (LPARAM) 0))); - - BOOL ret = OnLeftClick((int)id, tool->m_toggleState); - if (ret == FALSE && tool->m_isToggle) - { - tool->m_toggleState = !tool->m_toggleState; - ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)id, (LPARAM)MAKELONG(tool->m_toggleState, 0)); - } - return TRUE; -*/ - return FALSE; -} - -bool wxToolBar::OS2OnNotify(int WXUNUSED(idCtrl), - WXLPARAM lParam, - WXLPARAM *result) + wxDELETE(m_pToolTip); +} // end of wxToolBar::~wxToolBar + +bool wxToolBar::Realize() { -// TODO: -/* - // First check if this applies to us - NMHDR *hdr = (NMHDR *)lParam; + int nMaxToolWidth = 0; + int nMaxToolHeight = 0; + + m_nCurrentRowsOrColumns = 0; + m_vLastX = m_xMargin; + m_vLastY = m_yMargin; + m_vMaxWidth = 0; + m_vMaxHeight = 0; + - // the tooltips control created by the toolbar is sometimes Unicode, even in - // an ANSI application - int code = (int)hdr->code; - if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) ) - return FALSE; + // + // Find the maximum tool width and height + // + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + + while (node ) + { + wxToolBarTool* pTool = (wxToolBarTool *)node->GetData(); + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty()) + { + // + // Set the height according to the font and the border size + // + if (pTool->GetWidth() > m_vTextX) + nMaxToolWidth = pTool->GetWidth() + 4; + else + nMaxToolWidth = m_vTextX; + if (pTool->GetHeight() + m_vTextY > nMaxToolHeight) + nMaxToolHeight = pTool->GetHeight() + m_vTextY; + } + else + { + if (pTool->GetWidth() > nMaxToolWidth ) + nMaxToolWidth = pTool->GetWidth() + 4; + if (pTool->GetHeight() > nMaxToolHeight) + nMaxToolHeight = pTool->GetHeight(); + } + node = node->GetNext(); + } - HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0); - if ( toolTipWnd != hdr->hwndFrom ) - return FALSE; + wxCoord vTbWidth = 0L; + wxCoord vTbHeight = 0L; - LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam; - int id = (int)ttText->hdr.idFrom; - wxNode *node = m_tools.Find((long)id); - if (!node) - return FALSE; + GetSize( &vTbWidth + ,&vTbHeight + ); + if (vTbHeight < nMaxToolHeight) + { + SetSize( -1L + ,-1L + ,vTbWidth + ,nMaxToolHeight + 4 + ); + if (GetParent()->IsKindOf(CLASSINFO(wxFrame))) + { + wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame); - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + if (pFrame) + pFrame->PositionToolBar(); + } + } - const wxString& help = tool->m_shortHelpString; + int nSeparatorSize = m_toolSeparation; - if ( !help.IsEmpty() ) + node = m_tools.GetFirst(); + while (node) { - if ( code == TTN_NEEDTEXTA ) + wxToolBarTool* pTool = (wxToolBarTool *)node->GetData(); + + if (pTool->IsSeparator()) { - ttText->lpszText = (wxChar *)help.c_str(); + if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM)) + { + pTool->m_vX = m_vLastX + nSeparatorSize; + pTool->m_vHeight = m_defaultHeight + m_vTextY; + if (m_nCurrentRowsOrColumns >= m_maxCols) + m_vLastY += nSeparatorSize; + else + m_vLastX += nSeparatorSize * 4; + } + else + { + pTool->m_vY = m_vLastY + nSeparatorSize; + pTool->m_vHeight = m_defaultHeight + m_vTextY; + if (m_nCurrentRowsOrColumns >= m_maxRows) + m_vLastX += nSeparatorSize; + else + m_vLastY += nSeparatorSize * 4; + } + } + else if (pTool->IsButton()) + { + if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM)) + { + if (m_nCurrentRowsOrColumns >= m_maxCols) + { + m_nCurrentRowsOrColumns = 0; + m_vLastX = m_xMargin; + m_vLastY += nMaxToolHeight + m_toolPacking; + } + pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2))); + if (HasFlag(wxTB_TEXT)) + pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment + else + pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2)); + m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation; + } + else + { + if (m_nCurrentRowsOrColumns >= m_maxRows) + { + m_nCurrentRowsOrColumns = 0; + m_vLastX += (nMaxToolWidth + m_toolPacking); + m_vLastY = m_yMargin; + } + pTool->m_vX = m_vLastX + pTool->GetWidth(); + if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() ) + pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking; + else + pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2)); + m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation; + } + m_nCurrentRowsOrColumns++; } -#if (_WIN32_IE >= 0x0300) else { - // FIXME this is a temp hack only until I understand better what - // must be done in both ANSI and Unicode builds - - size_t lenAnsi = help.Len(); - #ifdef __MWERKS__ - // MetroWerks doesn't like calling mbstowcs with NULL argument - size_t lenUnicode = 2*lenAnsi; - #else - size_t lenUnicode = mbstowcs(NULL, help, lenAnsi); - #endif - - // using the pointer of right type avoids us doing all sorts of - // pointer arithmetics ourselves - wchar_t *dst = (wchar_t *)ttText->szText, - *pwz = new wchar_t[lenUnicode + 1]; - mbstowcs(pwz, help, lenAnsi + 1); - memcpy(dst, pwz, lenUnicode*sizeof(wchar_t)); - - // put the terminating _wide_ NUL - dst[lenUnicode] = 0; - - delete [] pwz; + // TODO: support the controls } -#endif // _WIN32_IE >= 0x0300 + + if (m_vLastX > m_maxWidth) + m_maxWidth = m_vLastX; + if (m_vLastY > m_maxHeight) + m_maxHeight = m_vLastY; + + node = node->GetNext(); } - // For backward compatibility... - OnMouseEnter(tool->m_index); + if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM)) + m_maxWidth += nMaxToolWidth; + else + m_maxHeight += nMaxToolHeight; + + m_maxWidth += m_xMargin; + m_maxHeight += m_yMargin; + m_bInitialized = true; + return true; +} // end of wxToolBar::Realize - return TRUE; -*/ - return FALSE; -} +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- -void wxToolBar::SetToolBitmapSize(const wxSize& size) +void wxToolBar::OnPaint ( + wxPaintEvent& WXUNUSED(rEvent) +) { - m_defaultWidth = size.x; - m_defaultHeight = size.y; -// ::SendMessage((HWND) GetHWND(), TB_SETBITMAPSIZE, 0, (LPARAM) MAKELONG ((int)size.x, (int)size.y)); -} + wxPaintDC vDc(this); + + PrepareDC(vDc); + + static int nCount = 0; + + // + // Prevent reentry of OnPaint which would cause wxMemoryDC errors. + // + if (nCount > 0) + return; + nCount++; + + wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl(); + ::WinFillRect(impl->GetHPS(), &impl->m_vRclPaint, GetBackgroundColour().GetPixel()); + for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + node; + node = node->GetNext() ) + { + wxToolBarTool* pTool = (wxToolBarTool*)node->GetData(); -void wxToolBar::SetRows(int nRows) + if (pTool->IsButton() ) + DrawTool(vDc, pTool); + if (pTool->IsSeparator()) + { + wxColour gray85(85, 85, 85); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + int nX; + int nY; + int nHeight = 0; + int nWidth = 0; + + vDc.SetPen(vDarkGreyPen); + if (HasFlag(wxTB_TEXT)) + { + if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM)) + { + nX = pTool->m_vX; + nY = pTool->m_vY - (m_vTextY - 6); + nHeight = (m_vTextY - 2) + pTool->GetHeight(); + } + else + { + nX = pTool->m_vX + m_xMargin + 10; + nY = pTool->m_vY + m_vTextY + m_toolSeparation; + nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX; + } + } + else + { + nX = pTool->m_vX; + nY = pTool->m_vY; + if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM)) + nHeight = pTool->GetHeight() - 2; + else + { + nX += m_xMargin + 10; + nY += m_yMargin + m_toolSeparation; + nWidth = pTool->GetWidth(); + } + } + vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight); + } + } + nCount--; +} // end of wxToolBar::OnPaint + +void wxToolBar::OnSize ( + wxSizeEvent& WXUNUSED(rEvent) +) { -// TODO: -/* - RECT rect; - ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(nRows, TRUE), (LPARAM) & rect); - m_maxWidth = (rect.right - rect.left + 2); - m_maxHeight = (rect.bottom - rect.top + 2); -*/ -} - -wxSize wxToolBar::GetMaxSize() const +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif +} // end of wxToolBar::OnSize + +void wxToolBar::OnKillFocus( + wxFocusEvent& WXUNUSED(rEvent) +) { -// TODO: -/* - if ((m_maxWidth == -1) || (m_maxHeight == -1)) - { - RECT rect; - ::SendMessage((HWND) GetHWND(), TB_SETROWS, MAKEWPARAM(m_maxRows, TRUE), (LPARAM) & rect); - ((wxToolBar *)this)->m_maxWidth = (rect.right - rect.left + 2); // ??? - ((wxToolBar *)this)->m_maxHeight = (rect.bottom - rect.top + 2); // ??? - } -*/ - return wxSize(m_maxWidth, m_maxHeight); -} - -// The button size is bigger than the bitmap size -wxSize wxToolBar::GetToolSize() const + OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1); +} // end of wxToolBar::OnKillFocus + +void wxToolBar::OnMouseEvent( + wxMouseEvent& rEvent +) { - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); -} + POINTL vPoint; + HWND hWnd; + wxCoord vX; + wxCoord vY; + HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE); + + ::WinSetPointer(HWND_DESKTOP, hPtr); + ::WinQueryPointerPos(HWND_DESKTOP, &vPoint); + hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE); + if (hWnd != (HWND)GetHwnd()) + { + m_vToolTimer.Stop(); + return; + } + + rEvent.GetPosition(&vX, &vY); + + wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX + ,vY + ); + + if (rEvent.LeftDown()) + { + CaptureMouse(); + } + if (rEvent.LeftUp()) + { + ReleaseMouse(); + } + + if (!pTool) + { + m_vToolTimer.Stop(); + if (m_nCurrentTool > -1) + { + if (rEvent.LeftIsDown()) + SpringUpButton(m_nCurrentTool); + pTool = (wxToolBarTool *)FindById(m_nCurrentTool); + if (pTool && !pTool->IsToggled()) + { + RaiseTool( pTool, FALSE ); + } + m_nCurrentTool = -1; + OnMouseEnter(-1); + } + return; + } + if (!rEvent.IsButton()) + { + if (pTool->GetId() != m_nCurrentTool) + { + // + // If the left button is kept down and moved over buttons, + // press those buttons. + // + if (rEvent.LeftIsDown() && pTool->IsEnabled()) + { + SpringUpButton(m_nCurrentTool); + if (pTool->CanBeToggled()) + { + pTool->Toggle(); + } + DrawTool(pTool); + } + wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool); + + if (pOldTool && !pTool->IsToggled()) + RaiseTool( pOldTool, FALSE ); + m_nCurrentTool = pTool->GetId(); + OnMouseEnter(m_nCurrentTool); + if (!pTool->GetShortHelp().empty()) + { + if (m_pToolTip) + delete m_pToolTip; + m_pToolTip = new wxToolTip(pTool->GetShortHelp()); + m_vXMouse = (wxCoord)vPoint.x; + m_vYMouse = (wxCoord)vPoint.y; + m_vToolTimer.Start(1000L, TRUE); + } + if (!pTool->IsToggled()) + RaiseTool(pTool); + } + return; + } + + // Left button pressed. + if (rEvent.LeftDown() && pTool->IsEnabled()) + { + if (pTool->CanBeToggled()) + { + pTool->Toggle(); + } + DrawTool(pTool); + } + else if (rEvent.RightDown()) + { + OnRightClick( pTool->GetId() + ,vX + ,vY + ); + } -void wxToolBar::EnableTool(int toolIndex, bool enable) + // + // Left Button Released. Only this action confirms selection. + // If the button is enabled and it is not a toggle tool and it is + // in the pressed state, then raise the button and call OnLeftClick. + // + if (rEvent.LeftUp() && pTool->IsEnabled() ) + { + // + // Pass the OnLeftClick event to tool + // + if (!OnLeftClick( pTool->GetId() + ,pTool->IsToggled()) && + pTool->CanBeToggled()) + { + // + // If it was a toggle, and OnLeftClick says No Toggle allowed, + // then change it back + // + pTool->Toggle(); + } + DrawTool(pTool); + } +} // end of wxToolBar::OnMouseEvent + +// ---------------------------------------------------------------------------- +// drawing +// ---------------------------------------------------------------------------- + +void wxToolBar::DrawTool( wxToolBarToolBase* pTool ) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; -// ::SendMessage((HWND) GetHWND(), TB_ENABLEBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(enable, 0)); - } -} - -void wxToolBar::ToggleTool(int toolIndex, bool toggle) + wxClientDC vDc(this); + + DrawTool( vDc, pTool ); +} // end of wxToolBar::DrawTool + +void wxToolBar::DrawTool( wxDC& rDc, wxToolBarToolBase* pToolBase ) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) + wxToolBarTool* pTool = (wxToolBarTool *)pToolBase; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + wxBitmap vBitmap = pTool->GetNormalBitmap(); + bool bUseMask = false; + wxMask* pMask = NULL; + + PrepareDC(rDc); + + if (!vBitmap.IsOk()) + return; + if ((pMask = vBitmap.GetMask()) != NULL) + if (pMask->GetMaskBitmap() != NULLHANDLE) + bUseMask = true; + + if (!pTool->IsToggled()) + { + LowerTool(pTool, FALSE); + if (!pTool->IsEnabled()) + { + wxColour vColor(wxT("GREY")); + + rDc.SetTextForeground(vColor); + if (!pTool->GetDisabledBitmap().IsOk()) + pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap + ,(long)GetBackgroundColour().GetPixel() + )); + rDc.DrawBitmap( pTool->GetDisabledBitmap() + ,pTool->m_vX + ,pTool->m_vY + ,bUseMask + ); + } + else + { + rDc.SetTextForeground(*wxBLACK); + rDc.DrawBitmap( vBitmap + ,pTool->m_vX + ,pTool->m_vY + ,bUseMask + ); + } + if (m_windowStyle & wxTB_3DBUTTONS) + { + RaiseTool(pTool); + } + if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() ) + { + wxCoord vX; + wxCoord vY; + wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2); + + rDc.SetFont(GetFont()); + rDc.GetTextExtent( pTool->GetLabel() + ,&vX + ,&vY + ); + if (pTool->GetWidth() > vX) // large tools + { + vLeft = pTool->m_vX + (pTool->GetWidth() - vX); + GetSize(&vX, &vY); + rDc.DrawText( pTool->GetLabel() + ,vLeft + ,vY - m_vTextY - 1 + ); + } + else // normal tools + { + vLeft += (wxCoord)((m_vTextX - vX)/2); + rDc.DrawText( pTool->GetLabel() + ,vLeft + ,pTool->m_vY + m_vTextY - 1 // a bit of margin + ); + } + } + } + else { - tool->m_toggleState = toggle; -// ::SendMessage((HWND) GetHWND(), TB_CHECKBUTTON, (WPARAM)toolIndex, (LPARAM)MAKELONG(toggle, 0)); + wxColour vColor(wxT("GREY")); + + LowerTool(pTool); + rDc.SetTextForeground(vColor); + if (!pTool->GetDisabledBitmap().IsOk()) + pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap + ,(long)GetBackgroundColour().GetPixel() + )); + rDc.DrawBitmap( pTool->GetDisabledBitmap() + ,pTool->m_vX + ,pTool->m_vY + ,bUseMask + ); + if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() ) + { + wxCoord vX; + wxCoord vY; + wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2); + + rDc.SetFont(GetFont()); + rDc.GetTextExtent( pTool->GetLabel() + ,&vX + ,&vY + ); + vLeft += (wxCoord)((m_vTextX - vX)/2); + rDc.DrawText( pTool->GetLabel() + ,vLeft + ,pTool->m_vY + m_vTextY - 1 // a bit of margin + ); + } } - } -} +} // end of wxToolBar::DrawTool -bool wxToolBar::GetToolState(int toolIndex) const -{ -// return (::SendMessage((HWND) GetHWND(), TB_ISBUTTONCHECKED, (WPARAM)toolIndex, (LPARAM)0) != 0); - return FALSE; -} +// ---------------------------------------------------------------------------- +// toolbar geometry +// ---------------------------------------------------------------------------- -void wxToolBar::ClearTools() +void wxToolBar::SetRows( + int nRows +) { - // TODO: Don't know how to reset the toolbar bitmap, as yet. - // But adding tools and calling CreateTools should probably - // recreate a buttonbar OK. - wxToolBarBase::ClearTools(); -} - -// If pushedBitmap is NULL, a reversed version of bitmap is -// created and used as the pushed/toggled image. -// If toggle is TRUE, the button toggles between the two states. -wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap, - bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2) + wxCHECK_RET( nRows != 0, wxT("max number of rows must be > 0") ); + + m_maxCols = (GetToolsCount() + nRows - 1) / nRows; + Refresh(); +} // end of wxToolBar::SetRows + +wxToolBarToolBase* wxToolBar::FindToolForPosition( + wxCoord vX +, wxCoord vY +) const { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2); - tool->m_clientData = clientData; + wxCoord vTBarHeight = 0; + + GetSize( NULL + ,&vTBarHeight + ); + vY = vTBarHeight - vY; + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + while (node) + { + wxToolBarTool* pTool = (wxToolBarTool *)node->GetData(); - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; + if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() ) + { + if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) && + (vY >= (pTool->m_vY - 2)) && + (vX <= (pTool->m_vX + pTool->GetWidth())) && + (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2))) + { + return pTool; + } + } + else + { + if ((vX >= pTool->m_vX) && + (vY >= pTool->m_vY) && + (vX <= (pTool->m_vX + pTool->GetWidth())) && + (vY <= (pTool->m_vY + pTool->GetHeight()))) + { + return pTool; + } + } + node = node->GetNext(); + } + return NULL; +} // end of wxToolBar::FindToolForPosition - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; +// ---------------------------------------------------------------------------- +// tool state change handlers +// ---------------------------------------------------------------------------- - tool->SetSize(GetToolSize().x, GetToolSize().y); +void wxToolBar::DoEnableTool( + wxToolBarToolBase* pTool +, bool WXUNUSED(bEnable) +) +{ + DrawTool(pTool); +} // end of wxToolBar::DoEnableTool - m_tools.Append((long)index, tool); - return tool; -} +void wxToolBar::DoToggleTool( + wxToolBarToolBase* pTool +, bool WXUNUSED(bToggle) +) +{ + DrawTool(pTool); +} // end of wxToolBar::DoToggleTool -// Responds to colour changes, and passes event on to children. -void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxToolBar::DoSetToggle( + wxToolBarToolBase* WXUNUSED(pTool) +, bool WXUNUSED(bToggle) +) { -// TODO: -/* - m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), - GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); -*/ - // Remap the buttons - CreateTools(); + // nothing to do +} // end of wxToolBar::DoSetToggle + +// +// Okay, so we've left the tool we're in ... we must check if the tool we're +// leaving was a 'sprung push button' and if so, spring it back to the up +// state. +// +void wxToolBar::SpringUpButton( + int vId +) +{ + wxToolBarToolBase* pTool = FindById(vId); - Refresh(); + if (pTool && pTool->CanBeToggled()) + { + if (pTool->IsToggled()) + pTool->Toggle(); - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); -} + DrawTool(pTool); + } +} // end of wxToolBar::SpringUpButton -void wxToolBar::OnMouseEvent(wxMouseEvent& event) +// ---------------------------------------------------------------------------- +// private helpers +// ---------------------------------------------------------------------------- + +void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase, + bool bLower ) { - if (event.RightDown()) + wxToolBarTool* pTool = (wxToolBarTool*)pToolBase; + wxCoord vX; + wxCoord vY; + wxCoord vWidth; + wxCoord vHeight; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID ); + wxClientDC vDC(this); + + if (!pTool) + return; + + if (pTool->IsSeparator()) + return; + + // + // We only do this for flat toolbars + // + if (!HasFlag(wxTB_FLAT)) + return; + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty()) { - // For now, we don't have an id. Later we could - // try finding the tool. - OnRightClick((int)-1, event.GetX(), event.GetY()); + if (pTool->GetWidth() > m_vTextX) + { + vX = pTool->m_vX - 2; + vWidth = pTool->GetWidth() + 4; + } + else + { + vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2); + vWidth = m_vTextX + 4; + } + vY = pTool->m_vY - 2; + vHeight = pTool->GetHeight() + m_vTextY + 2; } else { - event.Skip(); + vX = pTool->m_vX - 2; + vY = pTool->m_vY - 2; + vWidth = pTool->GetWidth() + 4; + vHeight = pTool->GetHeight() + 4; } -} - -// These are the default colors used to map the bitmap colors -// to the current system colors - -#define BGR_BUTTONTEXT (RGB(000,000,000)) // black -#define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey -#define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey -#define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white -#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue -#define BGR_BACKGROUND (RGB(255,000,255)) // magenta + if (bLower) + { + vDC.SetPen(*wxWHITE_PEN); + vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight); + vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight); + vDC.SetPen(vDarkGreyPen); + vDC.DrawLine(vX, vY, vX + vWidth, vY); + vDC.DrawLine(vX, vY + vHeight, vX, vY); + } + else + { + vDC.SetPen(vClearPen); + vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight); + vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight); + vDC.DrawLine(vX, vY, vX + vWidth, vY); + vDC.DrawLine(vX, vY + vHeight, vX, vY); + } +} // end of WinGuiBase_CToolBarTool::LowerTool -void wxMapBitmap(HBITMAP hBitmap, int width, int height) +void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase, + bool bRaise ) { -// TODO: -/* - COLORMAP ColorMap[] = { - {BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black - {BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey - {BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey - {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white - {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue - {BGR_BACKGROUND, COLOR_WINDOW} // magenta - }; - - int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP)); - int n; - for ( n = 0; n < NUM_MAPS; n++) - { - ColorMap[n].to = ::GetSysColor(ColorMap[n].to); - } - - HBITMAP hbmOld; - HDC hdcMem = CreateCompatibleDC(NULL); - - if (hdcMem) - { - hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap); - - int i, j, k; - for ( i = 0; i < width; i++) - { - for ( j = 0; j < height; j++) + wxToolBarTool* pTool = (wxToolBarTool*)pToolBase; + wxCoord vX; + wxCoord vY; + wxCoord vWidth; + wxCoord vHeight; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID ); + wxClientDC vDC(this); + + if (!pTool) + return; + + if (pTool->IsSeparator()) + return; + + if (!pTool->IsEnabled()) + return; + + // + // We only do this for flat toolbars + // + if (!HasFlag(wxTB_FLAT)) + return; + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty()) + { + if (pTool->GetWidth() > m_vTextX) { - COLORREF pixel = ::GetPixel(hdcMem, i, j); - BYTE red = GetRValue(pixel); - BYTE green = GetGValue(pixel); - BYTE blue = GetBValue(pixel); - - for ( k = 0; k < NUM_MAPS; k ++) - { - if ( ColorMap[k].from == pixel ) - { - COLORREF actualPixel = ::SetPixel(hdcMem, i, j, ColorMap[k].to); - break; - } - } + vX = pTool->m_vX - 2; + vWidth = pTool->GetWidth() + 4; + } + else + { + vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2); + vWidth = m_vTextX + 4; } + vY = pTool->m_vY - 2; + vHeight = pTool->GetHeight() + m_vTextY + 2; } + else + { + vX = pTool->m_vX - 2; + vY = pTool->m_vY - 2; + vWidth = pTool->GetWidth() + 4; + vHeight = pTool->GetHeight() + 4; + } + if (bRaise) + { + vDC.SetPen(vDarkGreyPen); + vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight); + vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight); + vDC.SetPen(*wxWHITE_PEN); + vDC.DrawLine(vX, vY, vX + vWidth, vY); + vDC.DrawLine(vX, vY + vHeight, vX, vY); + } + else + { + vDC.SetPen(vClearPen); + vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight); + vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight); + vDC.DrawLine(vX, vY, vX + vWidth, vY); + vDC.DrawLine(vX, vY + vHeight, vX, vY); + } +} // end of wxToolBar::RaiseTool - SelectObject(hdcMem, hbmOld); - DeleteObject(hdcMem); - } -*/ -} - -// Some experiments... -#if 0 - // What we want to do is create another bitmap which has a depth of 4, - // and set the bits. So probably we want to convert this HBITMAP into a - // DIB, then call SetDIBits. - // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of - // the screen), then SetDIBits fails. - HBITMAP newBitmap = ::CreateBitmap(totalBitmapWidth, totalBitmapHeight, 1, 4, NULL); - HANDLE newDIB = ::BitmapToDIB((HBITMAP) m_hBitmap, NULL); - LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) GlobalLock(newDIB); - - dc = ::GetDC(NULL); -// LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB; - - int result = ::SetDIBits(dc, newBitmap, 0, lpbmi->biHeight, FindDIBBits((LPSTR)lpbmi), (LPBITMAPINFO)lpbmi, - DIB_PAL_COLORS); - DWORD err = GetLastError(); - - ::ReleaseDC(NULL, dc); - - // Delete the DIB - GlobalUnlock (newDIB); - GlobalFree (newDIB); - -// WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap); - // Substitute our new bitmap for the old one - ::DeleteObject((HBITMAP) m_hBitmap); - m_hBitmap = (WXHBITMAP) newBitmap; -#endif +void wxToolBar::OnTimer ( wxTimerEvent& rEvent ) +{ + if (rEvent.GetId() == m_vToolTimer.GetId()) + { + wxPoint vPos( m_vXMouse, m_vYMouse ); + m_pToolTip->DisplayToolTipWindow(vPos); + m_vToolTimer.Stop(); + m_vToolExpTimer.Start(4000L, TRUE); + } + else if (rEvent.GetId() == m_vToolExpTimer.GetId()) + { + m_pToolTip->HideToolTipWindow(); + GetParent()->Refresh(); + m_vToolExpTimer.Stop(); + } +} // end of wxToolBar::OnTimer -#endif +#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE