Initial wxInfoBar implementation.

Add generic implementation, documentation and examples showing the use of the
new class in the samples.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62268 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-10-05 22:54:13 +00:00
parent ffa50e7361
commit a92b5dfe8c
34 changed files with 1001 additions and 4 deletions

235
src/generic/infobar.cpp Normal file
View File

@@ -0,0 +1,235 @@
///////////////////////////////////////////////////////////////////////////////
// Name: src/generic/infobar.cpp
// Purpose: generic wxInfoBar implementation
// Author: Vadim Zeitlin
// Created: 2009-07-28
// RCS-ID: $Id: wxhead.cpp,v 1.10 2009-06-29 10:23:04 zeitlin Exp $
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_INFOBAR
#ifndef WX_PRECOMP
#include "wx/artprov.h"
#include "wx/bmpbuttn.h"
#include "wx/settings.h"
#include "wx/statbmp.h"
#include "wx/stattext.h"
#endif // WX_PRECOMP
#include "wx/infobar.h"
#include "wx/scopeguard.h"
#include "wx/sizer.h"
// ============================================================================
// implementation
// ============================================================================
void wxInfoBar::Init()
{
m_icon = NULL;
m_text = NULL;
m_button = NULL;
m_showEffect = wxSHOW_EFFECT_SLIDE_TO_BOTTOM;
m_hideEffect = wxSHOW_EFFECT_SLIDE_TO_TOP;
// use default effect duration
m_effectDuration = 0;
}
bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
{
// calling Hide() before Create() ensures that we're created initially
// hidden
Hide();
if ( !wxWindow::Create(parent, winid) )
return false;
// use special, easy to notice, colours
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK));
SetOwnForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
// create the controls: icon, text and the button to dismiss the
// message.
// the icon is not shown unless it's assigned a valid bitmap
m_icon = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap);
// by default, the text uses a larger, more noticeable, font
m_text = new wxStaticText(this, wxID_ANY, "");
m_text->SetFont(m_text->GetFont().Bold().Larger());
m_button = new wxBitmapButton
(
this,
wxID_ANY,
wxArtProvider::GetBitmap(wxART_CROSS_MARK),
wxDefaultPosition,
wxDefaultSize,
wxBORDER_NONE
);
m_button->SetToolTip(_("Hide this notification message."));
Connect
(
wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(wxInfoBar::OnButton),
NULL,
this
);
// Center the text inside the sizer.
wxSizer * const sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->AddStretchSpacer();
sizer->Add(m_icon, wxSizerFlags().Centre().DoubleBorder());
sizer->Add(m_text, wxSizerFlags().Centre().DoubleBorder());
sizer->AddStretchSpacer();
sizer->Add(m_button, wxSizerFlags().Centre().DoubleBorder());
SetSizer(sizer);
return true;
}
void wxInfoBar::UpdateParent()
{
wxWindow * const parent = wxGetTopLevelParent(GetParent());
parent->Layout();
}
void wxInfoBar::ChangeParentBackground()
{
wxWindow * const parent = GetParent();
m_origParentBgCol = parent->GetBackgroundColour();
wxSizer * const sizer = GetContainingSizer();
if ( !sizer )
return;
wxWindow *sibling = NULL;
for ( wxSizerItemList::compatibility_iterator
node = sizer->GetChildren().GetFirst();
node;
node = node->GetNext() )
{
if ( node->GetData()->GetWindow() == this )
{
// find the next window following us
for ( node = node->GetNext();
node;
node = node->GetNext() )
{
wxSizerItem * const item = node->GetData();
if ( item->IsWindow() )
{
sibling = item->GetWindow();
break;
}
}
break;
}
}
if ( sibling )
parent->SetOwnBackgroundColour(sibling->GetBackgroundColour());
}
void wxInfoBar::RestoreParentBackground()
{
GetParent()->SetOwnBackgroundColour(m_origParentBgCol);
}
void wxInfoBar::DoHide()
{
ChangeParentBackground();
wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground );
HideWithEffect(m_hideEffect, m_effectDuration);
UpdateParent();
}
void wxInfoBar::DoShow()
{
// re-layout the parent first so that the window expands into an already
// unoccupied by the other controls area: for this we need to change our
// internal visibility flag to force Layout() to take us into account (an
// alternative solution to this hack would be to temporarily set
// wxRESERVE_SPACE_EVEN_IF_HIDDEN flag but it's not really batter)
// just change the internal flag indicating that the window is visible,
// without really showing it
wxWindowBase::Show();
// an extra hack: we want the temporarily uncovered area in which we're
// going to expand to look like part of this sibling for a better effect so
// temporarily change the background of our parent to the same colour
ChangeParentBackground();
wxON_BLOCK_EXIT_THIS0( wxInfoBar::RestoreParentBackground );
// adjust the parent layout to account for us
UpdateParent();
// reset the flag back before really showing the window or it wouldn't be
// shown at all because it would believe itself already visible
wxWindowBase::Show(false);
// finally do really show the window.
ShowWithEffect(m_showEffect, m_effectDuration);
}
void wxInfoBar::ShowMessage(const wxString& msg, int flags)
{
// first update the controls
const int icon = flags & wxICON_MASK;
if ( !icon || (icon == wxICON_NONE) )
{
m_icon->Hide();
}
else // do show an icon
{
m_icon->SetBitmap(wxArtProvider::GetMessageBoxIcon(icon));
m_icon->Show();
}
// notice the use of EscapeMnemonics() to ensure that "&" come through
// correctly
m_text->SetLabel(wxControl::EscapeMnemonics(msg));
// then show this entire window if not done yet
if ( !IsShown() )
{
DoShow();
}
else // we're already shown
{
// just update the layout to correspond to the new message
Layout();
}
}
void wxInfoBar::OnButton(wxCommandEvent& WXUNUSED(event))
{
DoHide();
}
#endif // wxUSE_INFOBAR