wxWidgets 中的动画滑动 Panel/Window
Animating Sliding Panel/Window in wxWidgets
您好,我有一个 wxWindow,它有两个箭头(左箭头和右箭头),中间有一个 wxPanel(附有屏幕截图)。现在,当用户点击向右箭头按钮时,当前显示在屏幕上的面板应该向左滑动,一个新的 wxPanel 应该从右侧出现并向左移动,这样它就会取代第一个 wxPanel .我附上了 4 个屏幕截图,显示了用户单击右箭头按钮后的中间阶段。类似地,当用户单击左箭头按钮时,但这次是在相反的方向上。我知道如何创建箭头并赋予它点击功能,但我不知道如何在 wxWidgets 中制作它的动画,或者这种动画在 wxWidgets 中是否可行。
屏幕上最初显示的是:
下一步当用户点击右箭头按钮时:
接下来 page1 仍然向左移动并离开屏幕,而 page2 从右侧进入屏幕但仍未占据全空间。这是一个中间阶段:
最后第2页取代了第1页。这是结束阶段。
请注意,当用户单击向右箭头时,滑动动画应该需要一些时间,比如 0.5 秒或 1 秒,以便用户可以看到下一个面板滑入屏幕。
我认为对于 wxWidgets,你能做的最好的事情就是用一个 simplebook 来模拟它。这是一个例子:
#include "wx/wx.h"
#include <wx/simplebook.h>
#include <wx/spinctrl.h>
class MyFrame: public wxFrame
{
public:
MyFrame();
private:
void ChangePage(wxShowEffect);
void SetLabel();
wxSimplebook* m_simplebook;
wxStaticText* m_pageIndicator;
};
MyFrame::MyFrame():wxFrame(NULL, wxID_ANY, "Sliding Demo", wxDefaultPosition,
wxSize(400, 300))
{
const int initialEffectTimout = 200;
wxPanel* bg = new wxPanel(this,wxID_ANY);
// Create the simple booka and add 3 dummy pages.
m_simplebook = new wxSimplebook(bg,wxID_ANY);
m_simplebook->SetEffectTimeout(initialEffectTimout);
wxPanel* page1 = new wxPanel(m_simplebook,wxID_ANY);
wxPanel* page2 = new wxPanel(m_simplebook,wxID_ANY);
wxPanel* page3 = new wxPanel(m_simplebook,wxID_ANY);
page1->SetBackgroundColour(*wxRED);
page2->SetBackgroundColour(*wxGREEN);
page3->SetBackgroundColour(*wxBLUE);
m_simplebook->AddPage(page1,wxString());
m_simplebook->AddPage(page2,wxString());
m_simplebook->AddPage(page3,wxString());
// create left and right arrows.
wxButton* leftArrow = new wxButton(bg, wxID_ANY, wxUniChar(0x276E),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
wxButton* rightArrow = new wxButton(bg, wxID_ANY, wxUniChar(0x276F),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
// create the label for the page indicator.
m_pageIndicator = new wxStaticText(bg,wxID_ANY,wxString());
SetLabel();
// add a spin control to change the duration of the slide animation.
wxStaticText* spinLabel = new wxStaticText(bg,wxID_ANY,"Transition time:");
wxSpinCtrl* spin = new wxSpinCtrl(bg,wxID_ANY);
spin->SetRange(0,1000);
spin->SetValue(initialEffectTimout);
// Layout the controls
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* bookSizer = new wxBoxSizer(wxHORIZONTAL);
bookSizer->Add(leftArrow,wxSizerFlags(0).Border(wxALL).CenterVertical());
bookSizer->Add(m_simplebook,wxSizerFlags(1).Expand().Border(wxTOP|wxBOTTOM));
bookSizer->Add(rightArrow,wxSizerFlags(0).Border(wxALL).Center());
mainSizer->Add(bookSizer,wxSizerFlags(1).Expand());
mainSizer->Add(m_pageIndicator,wxSizerFlags().Border(wxBOTTOM).Center());
wxSizer* spinSizer = new wxBoxSizer(wxHORIZONTAL);
spinSizer->Add(spinLabel,wxSizerFlags().Center());
spinSizer->Add(spin,wxSizerFlags());
mainSizer->Add(spinSizer, wxSizerFlags().Center().Border(wxBOTTOM));
bg->SetSizer(mainSizer);
Layout();
// Event handlers for the left arrow, right arrow, and spin control.
leftArrow->Bind(wxEVT_BUTTON,
[this](wxCommandEvent&){ChangePage(wxSHOW_EFFECT_SLIDE_TO_RIGHT);});
rightArrow->Bind(wxEVT_BUTTON,
[this](wxCommandEvent&){ChangePage(wxSHOW_EFFECT_SLIDE_TO_LEFT);});
spin->Bind(wxEVT_SPINCTRL,
[this](wxSpinEvent& event)
{m_simplebook->SetEffectTimeout(event.GetPosition());});
}
void MyFrame::SetLabel()
{
int curPage = m_simplebook->GetSelection();
int totalPages = m_simplebook->GetPageCount();
wxString label;
for ( int i = 0 ; i < totalPages ; ++i )
{
// U+2B24 = "Black Large Circle"
// U+2B58 = "Heavy Circle"
label << ((i == curPage) ? wxUniChar(0x2B24) : wxUniChar(0x2B58));
}
m_pageIndicator->SetLabel(label);
}
void MyFrame::ChangePage(wxShowEffect effect)
{
m_simplebook->SetEffect(effect);
m_simplebook->AdvanceSelection(effect == wxSHOW_EFFECT_SLIDE_TO_LEFT);
SetLabel();
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
在 windows 上看起来像这样:
我知道这不是您想要的,因为它会在滑动下一页之前完全滑出 1 页,而不是在滑动时让页面彼此相邻。但我认为这是可用控件所能做到的最好的。
您好,我有一个 wxWindow,它有两个箭头(左箭头和右箭头),中间有一个 wxPanel(附有屏幕截图)。现在,当用户点击向右箭头按钮时,当前显示在屏幕上的面板应该向左滑动,一个新的 wxPanel 应该从右侧出现并向左移动,这样它就会取代第一个 wxPanel .我附上了 4 个屏幕截图,显示了用户单击右箭头按钮后的中间阶段。类似地,当用户单击左箭头按钮时,但这次是在相反的方向上。我知道如何创建箭头并赋予它点击功能,但我不知道如何在 wxWidgets 中制作它的动画,或者这种动画在 wxWidgets 中是否可行。
屏幕上最初显示的是:
下一步当用户点击右箭头按钮时:
接下来 page1 仍然向左移动并离开屏幕,而 page2 从右侧进入屏幕但仍未占据全空间。这是一个中间阶段:
最后第2页取代了第1页。这是结束阶段。
请注意,当用户单击向右箭头时,滑动动画应该需要一些时间,比如 0.5 秒或 1 秒,以便用户可以看到下一个面板滑入屏幕。
我认为对于 wxWidgets,你能做的最好的事情就是用一个 simplebook 来模拟它。这是一个例子:
#include "wx/wx.h"
#include <wx/simplebook.h>
#include <wx/spinctrl.h>
class MyFrame: public wxFrame
{
public:
MyFrame();
private:
void ChangePage(wxShowEffect);
void SetLabel();
wxSimplebook* m_simplebook;
wxStaticText* m_pageIndicator;
};
MyFrame::MyFrame():wxFrame(NULL, wxID_ANY, "Sliding Demo", wxDefaultPosition,
wxSize(400, 300))
{
const int initialEffectTimout = 200;
wxPanel* bg = new wxPanel(this,wxID_ANY);
// Create the simple booka and add 3 dummy pages.
m_simplebook = new wxSimplebook(bg,wxID_ANY);
m_simplebook->SetEffectTimeout(initialEffectTimout);
wxPanel* page1 = new wxPanel(m_simplebook,wxID_ANY);
wxPanel* page2 = new wxPanel(m_simplebook,wxID_ANY);
wxPanel* page3 = new wxPanel(m_simplebook,wxID_ANY);
page1->SetBackgroundColour(*wxRED);
page2->SetBackgroundColour(*wxGREEN);
page3->SetBackgroundColour(*wxBLUE);
m_simplebook->AddPage(page1,wxString());
m_simplebook->AddPage(page2,wxString());
m_simplebook->AddPage(page3,wxString());
// create left and right arrows.
wxButton* leftArrow = new wxButton(bg, wxID_ANY, wxUniChar(0x276E),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
wxButton* rightArrow = new wxButton(bg, wxID_ANY, wxUniChar(0x276F),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
// create the label for the page indicator.
m_pageIndicator = new wxStaticText(bg,wxID_ANY,wxString());
SetLabel();
// add a spin control to change the duration of the slide animation.
wxStaticText* spinLabel = new wxStaticText(bg,wxID_ANY,"Transition time:");
wxSpinCtrl* spin = new wxSpinCtrl(bg,wxID_ANY);
spin->SetRange(0,1000);
spin->SetValue(initialEffectTimout);
// Layout the controls
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* bookSizer = new wxBoxSizer(wxHORIZONTAL);
bookSizer->Add(leftArrow,wxSizerFlags(0).Border(wxALL).CenterVertical());
bookSizer->Add(m_simplebook,wxSizerFlags(1).Expand().Border(wxTOP|wxBOTTOM));
bookSizer->Add(rightArrow,wxSizerFlags(0).Border(wxALL).Center());
mainSizer->Add(bookSizer,wxSizerFlags(1).Expand());
mainSizer->Add(m_pageIndicator,wxSizerFlags().Border(wxBOTTOM).Center());
wxSizer* spinSizer = new wxBoxSizer(wxHORIZONTAL);
spinSizer->Add(spinLabel,wxSizerFlags().Center());
spinSizer->Add(spin,wxSizerFlags());
mainSizer->Add(spinSizer, wxSizerFlags().Center().Border(wxBOTTOM));
bg->SetSizer(mainSizer);
Layout();
// Event handlers for the left arrow, right arrow, and spin control.
leftArrow->Bind(wxEVT_BUTTON,
[this](wxCommandEvent&){ChangePage(wxSHOW_EFFECT_SLIDE_TO_RIGHT);});
rightArrow->Bind(wxEVT_BUTTON,
[this](wxCommandEvent&){ChangePage(wxSHOW_EFFECT_SLIDE_TO_LEFT);});
spin->Bind(wxEVT_SPINCTRL,
[this](wxSpinEvent& event)
{m_simplebook->SetEffectTimeout(event.GetPosition());});
}
void MyFrame::SetLabel()
{
int curPage = m_simplebook->GetSelection();
int totalPages = m_simplebook->GetPageCount();
wxString label;
for ( int i = 0 ; i < totalPages ; ++i )
{
// U+2B24 = "Black Large Circle"
// U+2B58 = "Heavy Circle"
label << ((i == curPage) ? wxUniChar(0x2B24) : wxUniChar(0x2B58));
}
m_pageIndicator->SetLabel(label);
}
void MyFrame::ChangePage(wxShowEffect effect)
{
m_simplebook->SetEffect(effect);
m_simplebook->AdvanceSelection(effect == wxSHOW_EFFECT_SLIDE_TO_LEFT);
SetLabel();
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
在 windows 上看起来像这样:
我知道这不是您想要的,因为它会在滑动下一页之前完全滑出 1 页,而不是在滑动时让页面彼此相邻。但我认为这是可用控件所能做到的最好的。