随笔-341  评论-2670  文章-0  trackbacks-0
    GacUI发布了一个新的Demo。这个Demo是关于多选框和单选框的。跟Windows一样,直接创建出来的单选框其实是不会互斥的,除非你把他们放进同一个group里面。界面是左右各一个group box,使用table来保证两边的尺寸都一样大。每一个group box里面放三个按钮,而且每一个group box的最小尺寸都取决于两边所有6按钮中最长的那个按钮。每一边的三个按钮使用stack来排列成像一个列表一样。左边是多选框,右边是单选框。现在先上图:

    第一张是刚打开的时候,窗口的尺寸自动变化到能显示所有内容的最小的尺寸。尽管因为文字的关系,左边的按钮比右边的短,但是table可以控制两个group box一样大,并且共享最小尺寸。



    然后改变窗口的尺寸,按钮始终靠左上角,两个group box则保持一样大。



    大家已经看了前面的三个demo,所以有些东西其实已经不需要重复解释了。先上代码:

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

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

class CheckAndRadioWindow : public GuiWindow
{
private:

    GuiCellComposition
* CreateButtons(const WString& groupName, const WString& buttonName, bool checkBox, GuiSelectableButton::GroupController* groupController)
    {
        GuiCellComposition
* cell=new GuiCellComposition;

        GuiControl
* groupBox=g::NewGroupBox();
        groupBox
->GetBoundsComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
        groupBox
->GetContainerComposition()->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
        
// all child controls should at least 10 pixels away from the group box
        groupBox->GetContainerComposition()->SetInternalMargin(Margin(10101010));
        
// dock the group box to fill the cell
        groupBox->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
        groupBox
->SetText(groupName);
        
// add the button to the cell
        cell->AddChild(groupBox->GetBoundsComposition());

        
// create a stack to layout the 3 buttons from top to bottom shown like a list
        GuiStackComposition* stack=new GuiStackComposition;
        stack
->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren);
        stack
->SetDirection(GuiStackComposition::Vertical);
        stack
->SetAlignmentToParent(Margin(0000));
        stack
->SetPadding(6);
        groupBox
->GetContainerComposition()->AddChild(stack);

        
// create buttons
        for(int i=0;i<3;i++)
        {
            GuiSelectableButton
* button=checkBox?g::NewCheckBox():g::NewRadioButton();
            button
->SetText(buttonName+itow(i+1));
            button
->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
            
if(groupController)
            {
                button
->SetGroupController(groupController);
            }

            GuiStackItemComposition
* stackItem=new GuiStackItemComposition;
            stack
->AddChild(stackItem);
            stackItem
->AddChild(button->GetBoundsComposition());
        }

        
return cell;
    }
public:
    CheckAndRadioWindow()
        :GuiWindow(GetCurrentTheme()
->CreateWindowStyle())
    {
        
this->SetText(L"Controls.Button.CheckAndRadio");
        
// 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 2 group boxes
        GuiTableComposition* table=new GuiTableComposition;
        
// make the table to have 2 rows
        table->SetRowsAndColumns(12);
        table
->SetRowOption(0, GuiCellOption::MinSizeOption());
        table
->SetColumnOption(0, GuiCellOption::PercentageOption(0.5));
        table
->SetColumnOption(1, GuiCellOption::PercentageOption(0.5));
        
// dock the table to fill the window
        table->SetAlignmentToParent(Margin(4444));
        table
->SetCellPadding(6);
        
// add the table to the window;
        this->GetContainerComposition()->AddChild(table);

        
// add group box for check boxes
        {
            GuiCellComposition
* cell=CreateButtons(L"Check Boxes", L"This is a check box "true0);
            table
->AddChild(cell);
            
// this cell is the left cell
            cell->SetSite(0011);
        }

        
// add group box for radio buttons
        {
            
// create a group controller to group those radio buttons together
            
// so that select a radio button will unselect the previous one automatically
            GuiSelectableButton::GroupController* groupController=new GuiSelectableButton::MutexGroupController;
            
this->AddComponent(groupController);

            GuiCellComposition
* cell=CreateButtons(L"Radio buttons", L"This is a radio button "false, groupController);
            table
->AddChild(cell);
            
// this cell is the right cell
            cell->SetSite(0111);
        }

        
// 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()
        this->ForceCalculateSizeImmediately();
        
// move to the screen center
        this->MoveToScreenCenter();
    }

    
~CheckAndRadioWindow()
    {
    }
};

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

    需要关心的就是第二次调用CreateButtons函数,用来构造单选按钮的时候,穿进去的最后一个参数。GuiSelectableButton::GroupController类是一个虚类,用来控制选中状况。而预定义的MutexGroupController则可以控制连接到的所有GuiSelectionButton并保证他们互斥。如果需要更加复杂的情况,譬如说“最多只能选中N个按钮”这样的,则自己集成一个group controller就可以了。在创建了一个group controller,要调用GuiWindow::AddComponent保持他的生命周期,然后使用GuiSelectableButton::SetGroupController来帮顶一个按钮和一个group controller。

    这个demo就介绍到这里了,下一个将是关于tab控件和文本框的demo。
posted on 2012-04-27 06:02 陈梓瀚(vczh) 阅读(2244) 评论(25)  编辑 收藏 引用 所属分类: GacUI

评论:
# re: GacUI Demo:多选框和单选框 2012-04-27 06:39 | ccsdu2009
最好通过类似xml配置文件的形式生成窗体,这样看上去很复杂  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-27 07:06 | 陈梓瀚(vczh)
@ccsdu2009
我已经有计划了,等到demo写完网站做好了我就开始做那个。我暂时觉得比xml要好多了,啊哈哈哈  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-27 16:24 | Pear
什么时候能支持样式表涅?其实我只是想做效果的时候偷懒一点。。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框[未登录] 2012-04-27 19:43 | me
Excellent !

  回复  更多评论
  
# re: GacUI Demo:多选框和单选框[未登录] 2012-04-27 20:41 | Koobin
不知道有没有开发ui的ide呀?  回复  更多评论
  
# re: GacUI Demo:多选框和单选框[未登录] 2012-04-28 00:15 | fox
天生不支持xp,这是基于什么考虑呢  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-28 04:47 | qqdy
@陈梓瀚(vczh) 或者考虑采用类似 lua 那种 table 结构如何?
  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-28 05:21 | 陈梓瀚(vczh)
@fox
我有GDI啊,怎么能说天生不支持xp呢,只是xp没有显卡加速而已。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-28 05:22 | 陈梓瀚(vczh)
@qqdy
lua的table做GUI不好用。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-28 05:48 | 陈梓瀚(vczh)
@Pear
我应该会做出blend那种样子,而不是CSS那种样子的。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 04:24 | qqdy
@陈梓瀚(vczh) table 支持 key-value ,而且 value 也可以是任意类型,可以很轻松滴构建出像树这种结构。个人感觉 xml 能够包含的信息,table 也能包含,而且类似 table / json 这种结构视觉上看起来可读性高点哇?  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 05:39 | 陈梓瀚(vczh)
@qqdy
这是C++啊!模拟一个“value”出来你知道有多困难吗= =虽然要做当然是可以做,不划算啊,C++就要有C++的样子。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 08:19 | qqdy
@陈梓瀚(vczh)
value 类型为 void* 如何。。。哎,我只是随便说说。。。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 08:57 | qqdy
@陈梓瀚(vczh)
我的意思是“采用 table / json 这种形式的配置组织格式”,并不是说要用C++硬整一个万能类型的 value 出来哈。提这个纯粹是因为个人感觉这种配置格式看起来比XML更清爽。。。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 09:19 | Scan
@qqdy
可以用boost::any。以std::map<std::string, boost::any>部分模拟lua的table(key还不是动态类型的)。
C++中什么都可以办到,问题是,一旦语法糖裹厚了,那个编译时间不是可以忍受的。
我个人以为,陈子涵老大个人的C++库倾向于.Net风格,虽然它不同于stl和boost,但它很实用。
往C++中移植其他语言的特性,往往会付出编译时间等代价。用C++就因为它的快,没有必要过度追求语法上的便利性。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-04-29 17:46 | ooseven
@陈梓瀚(vczh)
为啥说xp下无法支持显卡硬加速?  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-05-01 03:59 | qqdy
@Scan
哎,C++的编译速度向来被人所诟病啊,加了模板后更是变本加厉的慢。。。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-05-01 05:04 | 陈梓瀚(vczh)
@qqdy
这个时候就要看程序员的功力了,boost的spirit编译一次一个多小时,我的parser combinator,一样是模板,编译一次就5秒钟。完成的功能几乎是一样的,性能也没差多少。  回复  更多评论
  
# re: GacUI Demo:多选框和单选框 2012-05-03 05:58 | 装配脑袋
复选框和单选钮的样子怪怪的。。  回复  更多评论
  

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