GacUI新Demo:按钮和排版

GacUI新Demo:按钮和排版
    今天为 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( 2 2 );
        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( 10 10 10 10 ));
        
//  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( 0 0 1 2 );

            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( 0 0 0 3 ));
            
//  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( 1 0 1 1 );

            buttonEnable
= g::NewButton();
            buttonEnable
-> SetText(L " Enable " );
            buttonEnable
-> GetBoundsComposition() -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
            buttonEnable
-> GetBoundsComposition() -> SetAlignmentToParent(Margin( 0 3 3 0 ));
            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( 1 1 1 1 );

            buttonDisable
= g::NewButton();
            buttonDisable
-> SetText(L " Disable " );
            buttonDisable
-> GetBoundsComposition() -> SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
            buttonDisable
-> GetBoundsComposition() -> SetAlignmentToParent(Margin( 3 3 0 0 ));
            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下面找到。

你可能感兴趣的:(GacUI新Demo:按钮和排版)