随笔-341  评论-2670  文章-0  trackbacks-0
    今天为GacUI写了一个新的Demo,展示了一些可以自动排版的按钮。主要的设想就是在窗口上放一个表格,分成两行两列。上面的按钮占满一整行,下面两个单元格放两个按钮。然后就可以设置每个行和列占整个表格的比例,在这个Demo里面都设置成50%。这样每当窗口缩放的时候,按钮的位置也会随之重新排版。然后设置表格充满整个窗口,这样窗口的最小值就会被表格的内容所限定,这样试图把窗口缩小的时候,就会有一个最小的尺寸限制着,至始至终保证所有的东西都可以显示出来,不会因为窗口太小而只显示一半。按钮也是同样,可以设置它必须显示所有的文字。所有的过程一旦配置好之后,计算尺寸的时候所有的操作都会自动做,程序员不需要为窗口的Resize事件写任何代码。

    下面先放图。

    第一个图是窗口刚刚打开的时候的样子。因为Demo里面没有设置窗口的尺寸,所以一上来就自动变成了最小的尺寸——并且刚好可以显示所有的内容。



    第二个图是窗口放大之后的样子。Disable按钮被按下了,所以上面的按钮就变灰。



    这个Demo使用了Direct2D渲染器,所有的绘制过程都十分高速。而且表格的尺寸计算也是经过优化的,在拖放窗口的时候十分流畅。事实上按钮的渐变啊、边框啊、文字等等也是借助表格排版的。由于尺寸计算过于复杂,除了表格之外整个框架都不保存控件的尺寸,所有的东西都在需要的时候——譬如说渲染的时候,譬如说计算鼠标点中的位置——的那一刻才开始算。因此无论是鼠标滑过,或者是窗口拖放,都拼命地执行很多虚函数。可见C++的虚函数的性能之高,几乎永远都不会成为程序的瓶颈。下面来看代码:

#include "..\..\Public\Source\GacUIIncludes.h"
#include 
<Windows.h>

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
{
    
return SetupWindowsDirect2DRenderer();
}

class EnableDisableWindow : public GuiWindow
{
private:
    GuiButton
*            buttonTarget;
    GuiButton
*            buttonEnable;
    GuiButton
*            buttonDisable;

    
void buttonEnable_OnClick(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
    {
        buttonTarget
->SetEnabled(true);
    }

    
void buttonDisable_OnClick(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
    {
        buttonTarget
->SetEnabled(false);
    }
public:
    EnableDisableWindow()
        :GuiWindow(GetCurrentTheme()
->CreateWindowStyle())
    {
        
this->SetText(L"Controls.Button.EnableDisable");
        
// limit the size that the window should always show the whole content without cliping it
        this->GetContainerComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);

        
// create a table to layout the 3 buttons
        GuiTableComposition* table=new GuiTableComposition;
        
// make the table to have 2 rows
        table->SetRowsAndColumns(22);
        table
->SetRowOption(0, GuiCellOption::PercentageOption(0.5));
        table
->SetRowOption(1, GuiCellOption::PercentageOption(0.5));
        table
->SetColumnOption(0, GuiCellOption::PercentageOption(0.5));
        table
->SetColumnOption(1, GuiCellOption::PercentageOption(0.5));
        
// dock the table to fill the window
        table->SetAlignmentToParent(Margin(10101010));
        
// add the table to the window;
        this->GetContainerComposition()->AddChild(table);

        
// add the target button
        {
            GuiCellComposition
* cell=new GuiCellComposition;
            table
->AddChild(cell);
            
// this cell is the top cell
            cell->SetSite(0012);

            buttonTarget
=g::NewButton();
            buttonTarget
->SetText(L"Enable or disable me using the buttons below!");
            
// ensure that the buttonTarget display the whole text
            buttonTarget->GetBoundsComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
            
// dock the button to fill the cell
            buttonTarget->GetBoundsComposition()->SetAlignmentToParent(Margin(0003));
            
// add the button to the cell
            cell->AddChild(buttonTarget->GetBoundsComposition());
        }

        
// add the enable button
        {
            GuiCellComposition
* cell=new GuiCellComposition;
            table
->AddChild(cell);
            
// this cell is the bottom left cell
            cell->SetSite(1011);

            buttonEnable
=g::NewButton();
            buttonEnable
->SetText(L"Enable");
            buttonEnable
->GetBoundsComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
            buttonEnable
->GetBoundsComposition()->SetAlignmentToParent(Margin(0330));
            buttonEnable
->Clicked.AttachMethod(this&EnableDisableWindow::buttonEnable_OnClick);
            cell
->AddChild(buttonEnable->GetBoundsComposition());
        }

        
// add the disable button
        {
            GuiCellComposition
* cell=new GuiCellComposition;
            table
->AddChild(cell);
            
// this cell is the bottom right cell
            cell->SetSite(1111);

            buttonDisable
=g::NewButton();
            buttonDisable
->SetText(L"Disable");
            buttonDisable
->GetBoundsComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
            buttonDisable
->GetBoundsComposition()->SetAlignmentToParent(Margin(3300));
            buttonDisable
->Clicked.AttachMethod(this&EnableDisableWindow::buttonDisable_OnClick);
            cell
->AddChild(buttonDisable->GetBoundsComposition());
        }

        
// change the button font
        {
            FontProperties font;

            font
=buttonTarget->GetFont();
            font.size
=20;
            buttonTarget
->SetFont(font);
            buttonEnable
->SetFont(font);
            buttonDisable
->SetFont(font);
        }

        
// call this to calculate the size immediately if any indirect content in the table changes
        
// so that the window can calcaulte its correct size before calling the MoveToScreenCenter()
        table->UpdateCellBounds();
        
// update the size
        this->SetBounds(Rect());
        
// move to the screen center
        this->MoveToScreenCenter();
    }

    
~EnableDisableWindow()
    {
    }
};

void GuiMain()
{
    GuiWindow
* window=new EnableDisableWindow();
    GetApplication()
->Run(window);
    delete window;
}

    代码里面充满了注释,而且主要的内容也在上面介绍了,在这里我就不罗嗦了。所有的代码都可以在http://gac.codeplex.com中,下载最新的代码,然后在Libraries\GacUI\GacUIDemo\GacUIDemo.sln下面找到。
posted on 2012-04-25 02:46 陈梓瀚(vczh) 阅读(2301) 评论(5)  编辑 收藏 引用 所属分类: GacUI

评论:
# re: GacUI新Demo:按钮和排版[未登录] 2012-04-25 04:02 | me
superstar!  回复  更多评论
  
# re: GacUI新Demo:按钮和排版[未登录] 2012-04-25 18:20 | diryboy
好厉害!  回复  更多评论
  
# re: GacUI新Demo:按钮和排版[未登录] 2012-04-27 05:53 | koobin
是不是用Win7的API写的?在XP下还运行不了?koobin@126.com  回复  更多评论
  
# re: GacUI新Demo:按钮和排版 2012-04-27 06:09 | 陈梓瀚(vczh)
@koobin
应该只有剪贴板用到了win7的一个api,只要在xp的时候禁用即可。如果放在XP,最大的牺牲是没有显卡加速,要采用GDI来绘制,让本来就慢的XP变得更慢了。  回复  更多评论
  
# re: GacUI新Demo:按钮和排版 2013-05-15 23:28 | tb
厉害啊   回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理