X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7509fa8caa43a1327175dd5fa8b7caf6b647e81b..44d130a35e7973911686d664bcf275a538990d52:/src/msw/tbar95.cpp diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index e0c800a45a..3748168d9e 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -101,6 +101,10 @@ #define TBSTYLE_TRANSPARENT 0x8000 #endif +#ifndef TBSTYLE_TOOLTIPS + #define TBSTYLE_TOOLTIPS 0x0100 +#endif + // Messages #ifndef TB_GETSTYLE #define TB_SETSTYLE (WM_USER + 56) @@ -138,14 +142,15 @@ class wxToolBarTool : public wxToolBarToolBase public: wxToolBarTool(wxToolBar *tbar, int id, - const wxBitmap& bitmap1, - const wxBitmap& bitmap2, - bool toggle, + const wxString& label, + const wxBitmap& bmpNormal, + const wxBitmap& bmpDisabled, + wxItemKind kind, wxObject *clientData, - const wxString& shortHelpString, - const wxString& longHelpString) - : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, - clientData, shortHelpString, longHelpString) + const wxString& shortHelp, + const wxString& longHelp) + : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind, + clientData, shortHelp, longHelp) { m_nSepCount = 0; } @@ -156,6 +161,19 @@ public: m_nSepCount = 1; } + virtual void SetLabel(const wxString& label) + { + if ( label == m_label ) + return; + + wxToolBarToolBase::SetLabel(label); + + // we need to update the label shown in the toolbar because it has a + // pointer to the internal buffer of the old label + // + // TODO: use TB_SETBUTTONINFO + } + // set/get the number of separators which we use to cover the space used by // a control in the toolbar void SetSeparatorsCount(size_t count) { m_nSepCount = count; } @@ -175,15 +193,16 @@ private: // ---------------------------------------------------------------------------- wxToolBarToolBase *wxToolBar::CreateTool(int id, - const wxBitmap& bitmap1, - const wxBitmap& bitmap2, - bool toggle, + const wxString& label, + const wxBitmap& bmpNormal, + const wxBitmap& bmpDisabled, + wxItemKind kind, wxObject *clientData, - const wxString& shortHelpString, - const wxString& longHelpString) + const wxString& shortHelp, + const wxString& longHelp) { - return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle, - clientData, shortHelpString, longHelpString); + return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind, + clientData, shortHelp, longHelp); } wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) @@ -224,16 +243,12 @@ bool wxToolBar::Create(wxWindow *parent, return FALSE; // prepare flags - DWORD msflags = 0; // WS_VISIBLE | WS_CHILD always included + DWORD msflags = TBSTYLE_TOOLTIPS; // WS_VISIBLE | WS_CHILD always included if ( style & wxCLIP_SIBLINGS ) msflags |= WS_CLIPSIBLINGS; -#ifdef TBSTYLE_TOOLTIPS - msflags |= TBSTYLE_TOOLTIPS; -#endif - - if (style & wxTB_FLAT) + if ( style & wxTB_FLAT ) { // static as it doesn't change during the program lifetime static int s_verComCtl = wxTheApp->GetComCtl32Version(); @@ -247,6 +262,10 @@ bool wxToolBar::Create(wxWindow *parent, msflags |= TBSTYLE_FLAT | TBSTYLE_TRANSPARENT; } } + if (style & wxTB_NODIVIDER) + msflags |= CCS_NODIVIDER; + if (style & wxTB_NOALIGN) + msflags |= CCS_NOPARENTALIGN; // MSW-specific initialisation if ( !wxControl::MSWCreateControl(TOOLBARCLASSNAME, msflags) ) @@ -541,7 +560,6 @@ bool wxToolBar::Realize() wxLogDebug(wxT("TB_DELETEBUTTON failed")); } } - } if ( addBitmap ) // no old bitmap or we can't replace it @@ -564,6 +582,7 @@ bool wxToolBar::Realize() // this array will hold the indices of all controls in the toolbar wxArrayInt controlIds; + bool lastWasRadio = FALSE; int i = 0; for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { @@ -577,6 +596,7 @@ bool wxToolBar::Realize() wxZeroMemory(button); + bool isRadio = FALSE; switch ( tool->GetStyle() ) { case wxTOOL_STYLE_CONTROL: @@ -590,6 +610,12 @@ bool wxToolBar::Realize() case wxTOOL_STYLE_BUTTON: button.iBitmap = bitmapId; + + if ( HasFlag(wxTB_TEXT) && !tool->GetLabel().empty() ) + { + button.iString = (int)tool->GetLabel().c_str(); + } + button.idCommand = tool->GetId(); if ( tool->IsEnabled() ) @@ -597,18 +623,46 @@ bool wxToolBar::Realize() if ( tool->IsToggled() ) button.fsState |= TBSTATE_CHECKED; - button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK - : TBSTYLE_BUTTON; + switch ( tool->GetKind() ) + { + case wxITEM_RADIO: + button.fsStyle = TBSTYLE_CHECKGROUP; + + if ( !lastWasRadio ) + { + // the first item in the radio group is checked by + // default to be consistent with wxGTK and the menu + // radio items + button.fsState |= TBSTATE_CHECKED; + + tool->Toggle(TRUE); + } + + isRadio = TRUE; + break; + + case wxITEM_CHECK: + button.fsStyle = TBSTYLE_CHECK; + break; + + default: + wxFAIL_MSG( _T("unexpected toolbar button kind") ); + // fall through + + case wxITEM_NORMAL: + button.fsStyle = TBSTYLE_BUTTON; + } bitmapId++; break; } + lastWasRadio = isRadio; + i++; } - if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS, - (WPARAM)i, (LPARAM)buttons) ) + if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS, (WPARAM)i, (LPARAM)buttons) ) { wxLogLastError(wxT("TB_ADDBUTTONS")); } @@ -781,15 +835,20 @@ bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id) bool toggled = tool->IsToggled(); - // OnLeftClick() can veto the button state change - for buttons which may - // be toggled only, of couse - if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() ) + // avoid sending the event when a radio button is released, this is not + // interesting + if ( !tool->CanBeToggled() || tool->GetKind() != wxITEM_RADIO || toggled ) { - // revert back - toggled = !toggled; - tool->SetToggle(toggled); + // OnLeftClick() can veto the button state change - for buttons which + // may be toggled only, of couse + if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() ) + { + // revert back + toggled = !toggled; + tool->SetToggle(toggled); - ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0)); + ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0)); + } } return TRUE; @@ -804,7 +863,7 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), // the tooltips control created by the toolbar is sometimes Unicode, even // in an ANSI application - this seems to be a bug in comctl32.dll v5 - int code = (int)hdr->code; + UINT code = hdr->code; if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) ) return FALSE; @@ -819,51 +878,7 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), if ( !tool ) return FALSE; - const wxString& help = tool->GetShortHelp(); - - if ( !help.IsEmpty() ) - { - if ( code == TTN_NEEDTEXTA ) - { - ttText->lpszText = (wxChar *)help.c_str(); - } - else - { -#if wxUSE_UNICODE - ttText->lpszText = (wxChar *)help.c_str(); -#else - // VZ: I don't know why it happens, but the versions of - // comctl32.dll starting from 4.70 sometimes send TTN_NEEDTEXTW - // even to ANSI programs (normally, this message is supposed - // to be sent to Unicode programs only) - hence we need to - // handle it as well, otherwise no tooltips will be shown in - // this case - - size_t lenAnsi = help.Len(); - #if defined( __MWERKS__ ) || defined( __CYGWIN__ ) - // MetroWerks doesn't like calling mbstowcs with NULL argument - // neither Cygwin does - 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; -#endif - } - } - - return TRUE; + return HandleTooltipNotify(code, lParam, tool->GetShortHelp()); } // ---------------------------------------------------------------------------- @@ -980,6 +995,67 @@ void wxToolBar::UpdateSize() } } +// ---------------------------------------------------------------------------- +// toolbar styles +// --------------------------------------------------------------------------- + +void wxToolBar::SetWindowStyleFlag(long style) +{ + // there doesn't seem to be any reasonably simple way to prevent the + // toolbar from showing the icons so for now we don't honour wxTB_NOICONS + if ( (style & wxTB_TEXT) != (GetWindowStyle() & wxTB_TEXT) ) + { + // update the strings of all toolbar buttons + // + // NB: we can only do it using TB_SETBUTTONINFO which is available + // in comctl32.dll >= 4.71 only +#if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 ) + if ( wxTheApp->GetComCtl32Version() >= 471 ) + { + // set the (underlying) separators width to be that of the + // control + TBBUTTONINFO tbbi; + tbbi.cbSize = sizeof(tbbi); + tbbi.dwMask = TBIF_TEXT; + if ( !(style & wxTB_TEXT) ) + { + // don't show the text - remove the labels + tbbi.pszText = NULL; + } + + for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); + node; + node = node->GetNext() ) + { + wxToolBarToolBase *tool = node->GetData(); + if ( !tool->IsButton() ) + { + continue; + } + + if ( style & wxTB_TEXT ) + { + // cast is harmless + tbbi.pszText = (wxChar *)tool->GetLabel().c_str(); + } + + if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO, + tool->GetId(), (LPARAM)&tbbi) ) + { + // the id is probably invalid? + wxLogLastError(wxT("TB_SETBUTTONINFO")); + } + } + + UpdateSize(); + Refresh(); + } +#endif // comctl32.dll 4.71 + } + + wxToolBarBase::SetWindowStyleFlag(style); +} + // ---------------------------------------------------------------------------- // tool state // ---------------------------------------------------------------------------- @@ -1028,6 +1104,13 @@ void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event) void wxToolBar::OnMouseEvent(wxMouseEvent& event) { + if (event.Leaving() && m_pInTool) + { + OnMouseEnter( -1 ); + event.Skip(); + return; + } + if (event.RightDown()) { // For now, we don't have an id. Later we could @@ -1061,11 +1144,18 @@ bool wxToolBar::HandleSize(WXWPARAM wParam, WXLPARAM lParam) else { w = LOWORD(lParam); - h = r.bottom - r.top; + if (HasFlag( wxTB_FLAT )) + h = r.bottom - r.top - 3; + else + h = r.bottom - r.top; if ( m_maxRows ) { // FIXME: 6 is hardcoded separator line height... - h += 6; + //h += 6; + if (HasFlag(wxTB_NODIVIDER)) + h += 3; + else + h += 6; h *= m_maxRows; } } @@ -1136,8 +1226,6 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam) // get the control rect in our client coords wxControl *control = tool->GetControl(); wxRect rectCtrl = control->GetRect(); - control->ClientToScreen(&rectCtrl.x, &rectCtrl.y); - ScreenToClient(&rectCtrl.x, &rectCtrl.y); // iterate over all buttons TBBUTTON tbb;