📄 foldpanelbar.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: foldpanelbar.cpp
// Purpose:
// Author: Jorgen Bodde
// Modified by: ABX - 19/12/2004 : possibility of horizontal orientation
// : wxWidgets coding standards
// Created: 22/06/2004
// RCS-ID: $Id: foldpanelbar.cpp,v 1.7 2005/07/28 23:23:27 VZ Exp $
// Copyright: (c) Jorgen Bodde
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/foldbar/foldpanelbar.h"
#include "icon_collapsed.xpm"
#include "icon_expanded.xpm"
#include "icon_theresmore.xpm"
//----------------------------------------------------------------------------
// wxFoldPanelBar
//----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS( wxFoldPanelBar, wxPanel )
BEGIN_EVENT_TABLE(wxFoldPanelBar,wxPanel)
EVT_SIZE(wxFoldPanelBar::OnSizePanel)
//EVT_PAINT(wxFoldPanelBar::OnPaint)
EVT_CAPTIONBAR(wxID_ANY, wxFoldPanelBar::OnPressCaption)
END_EVENT_TABLE()
wxFoldPanelBar::wxFoldPanelBar()
: wxPanel()
, m_foldPanel(NULL)
, m_bottomPanel(NULL)
, m_controlCreated(false)
{
}
wxFoldPanelBar::wxFoldPanelBar( wxWindow *parent, wxWindowID id, const wxPoint &position,
const wxSize& size, long style, long extraStyle)
: wxPanel()
, m_foldPanel(NULL)
, m_bottomPanel(NULL)
, m_controlCreated(false)
{
Create( parent, id, position, size, style, extraStyle);
}
void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
const wxSize& size, long style, long extraStyle )
{
m_extraStyle = extraStyle;
// make sure there is any orientation
if ( ( style & wxFPB_HORIZONTAL ) != wxFPB_HORIZONTAL )
style |= wxFPB_VERTICAL;
// create the panel (duh!). This causes a size event, which we are going
// to skip when we are not initialised
wxPanel::Create(parent, id, position, size, style);
// the fold panel area
m_foldPanel = new wxPanel(this, wxID_ANY, position, size, wxNO_BORDER|wxTAB_TRAVERSAL);
// the extra area for some icons / context menu etc
#if 0
m_bottomPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22), wxNO_BORDER|wxTAB_TRAVERSAL);
m_bottomPanel->SetBackgroundColour(*wxWHITE);
#endif
// create the fold icons to be used in the captions
m_images = new wxImageList(16, 16);
wxBitmap *bmp = new wxBitmap(icon_expanded);
m_images->Add(*bmp);
delete bmp;
bmp = new wxBitmap(icon_collapsed);
m_images->Add(*bmp);
delete bmp;
m_moreBmp = new wxBitmap(icon_theresmore);
// do this as last, to check if create is already called
m_controlCreated = true;
}
wxFoldPanelBar::~wxFoldPanelBar()
{
delete m_images;
delete m_moreBmp;
}
wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
{
wxASSERT(m_controlCreated);
// create a fold panel item, which is first only the caption.
// the user can now add a panel area which will be folded in
// when pressed.
wxFoldPanelItem *item = new wxFoldPanelItem(m_foldPanel, caption, m_images, collapsedInitially, style);
// look at the last added one and reposition this one
int pos = 0;
if(m_panels.GetCount() > 0)
pos = m_panels.Last()->GetItemPos() + m_panels.Last()->GetPanelLength();
item->Reposition(pos);
m_panels.Add(item);
//return wxFoldPanel(item);
return wxFoldPanel(item);
}
int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
int rightSpacing)
{
wxCHECK(panel.IsOk(), -1);
panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
// TODO: Take old and new height, and if difference, reposition all the lower panels
// this is because the user can add new wxWindow controls somewhere in between
// when other panels are already present.
return 0;
}
int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
int rightSpacing)
{
wxCHECK(panel.IsOk(), -1);
panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
return 0;
}
void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
{
// skip all stuff when we are not initialised yet
if(!m_controlCreated)
{
event.Skip();
return;
}
// now size the fold panel area and the
// lower bar in such a way that the bar is always
// visible
wxRect foldrect = GetRect();
// fold panel itself. If too little space,
// don't show it
#if 0
if(foldrect.GetHeight() < 23)
foldrect.SetHeight(0);
else
foldrect.SetHeight(foldrect.GetHeight() - 22);
#endif
foldrect.SetX(0);
foldrect.SetY(0);
m_foldPanel->SetSize(foldrect);
if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
{
wxRect rect = RepositionCollapsedToBottom();
bool vertical = IsVertical();
if((vertical && rect.GetHeight() > 0) || (!vertical && rect.GetWidth() > 0))
RefreshRect(rect);
}
// TODO: A smart way to check wether the old - new width of the
// panel changed, if so no need to resize the fold panel items
RedisplayFoldPanelItems();
// tool panel for icons and other stuff
#if 0
wxRect bottomrect = GetRect();
if(bottomrect.GetHeight() < 22)
bottomrect.SetY(0);
else
bottomrect.SetY(bottomrect.GetHeight() - 22);
bottomrect.SetHeight(22);
bottomrect.SetX(0);
m_bottomPanel->SetSize(bottomrect);
// TODO: redraw the bitmap properly
// use the captionbar algorithm for that
m_bottomPanel->Refresh();
#endif
}
void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
{
if(!m_controlCreated)
return;
#if 0
// paint the bottom panel only, where the
// arrow is shown when there is more to show the user
// just as informative icon
wxPaintDC dc(m_bottomPanel);
wxSize size = m_bottomPanel->GetSize();
int offset = (size.GetHeight() - m_moreBmp->GetHeight()) / 2;
dc.DrawBitmap(*m_moreBmp, size.GetWidth() - m_moreBmp->GetWidth() - 2, offset, true);
#endif
event.Skip();
}
void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
{
// act upon the folding or expanding status of the bar
// to expand or collapse the panel(s)
if(event.GetFoldStatus())
Collapse(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
else
Expand(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
}
void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
{
wxASSERT(item);
int i = m_panels.Index(item);
if(i != wxNOT_FOUND)
RefreshPanelsFrom(i);
}
void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
{
Freeze();
// if collapse to bottom is on, the panels that are not expanded
// should be drawn at the bottom. All panels that are expanded
// are drawn on top. The last expanded panel gets all the extra space
if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
{
int offset = 0;
for(size_t j = 0; j < m_panels.GetCount(); j++)
{
if(m_panels.Item(j)->IsExpanded())
offset += m_panels.Item(j)->Reposition(offset);
}
// put all non collapsed panels at the bottom where there is space, else
// put them right behind the expanded ones
RepositionCollapsedToBottom();
}
else
{
int pos = m_panels.Item(i)->GetItemPos() + m_panels.Item(i)->GetPanelLength();
for(i++; i < m_panels.GetCount(); i++)
pos += m_panels.Item(i)->Reposition(pos);
}
Thaw();
}
void wxFoldPanelBar::RedisplayFoldPanelItems()
{
// resize them all. No need to reposition
wxFoldPanelItem *item;
for(size_t i = 0; i < m_panels.GetCount(); i++)
{
item = m_panels.Item(i);
wxASSERT(item);
item->ResizePanel();
}
}
wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
{
wxRect value(0,0,0,0);
bool vertical = IsVertical();
// determine wether the number of panels left
// times the size of their captions is enough
// to be placed in the left over space
int expanded = 0, collapsed = 0, offset;
GetPanelsLength(collapsed, expanded);
// if no room stick them behind the normal ones, else
// at the bottom
if(((vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - expanded - collapsed) < 0)
offset = expanded;
else
{
// value is the region which is left unpainted
// I will send it back as 'slack' so it does not need to
// be recalulated.
value.SetHeight(GetSize().GetHeight());
value.SetWidth(GetSize().GetWidth());
if(vertical)
{
value.SetY(expanded);
value.SetHeight(value.GetHeight() - expanded);
}
else
{
value.SetX(expanded);
value.SetWidth(value.GetWidth() - expanded);
}
offset = (vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - collapsed;
}
// go reposition
for(size_t i = 0; i < m_panels.GetCount(); i++)
{
if(!m_panels.Item(i)->IsExpanded())
offset += m_panels.Item(i)->Reposition(offset);
}
return value;
}
int wxFoldPanelBar::GetPanelsLength(int &collapsed, int &expanded)
{
int value = 0;
// assumed here that all the panels that are expanded
// are positioned after each other from 0,0 to end.
for(size_t j = 0; j < m_panels.GetCount(); j++)
{
int offset = m_panels.Item(j)->GetPanelLength();
value += offset;
if(m_panels.Item(j)->IsExpanded())
expanded += offset;
else
collapsed += offset;
}
return value;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -