游览 Nana 1.0

来源:互联网 发布:数据库建立流程图 编辑:程序博客网 时间:2024/05/05 22:41

Nana 1.0是Beta阶段的第一个版本。


接口变更

1, 移除 nana::color_t 类型,加入新的 nana::color 类

color_t 的主要问题是无法表示无效的颜色值,因为 color_t 就是unsigned类型的别名。color 类还提供了一些有用的接口,from_rgb()/from_hsl()用来赋值颜色,blend()混合两个颜色,还定义了一些用于初始化颜色的辅助类型。

using namespace nana;//nana::colors 定义了一些颜色的名称.//参考 http://www.w3.org/TR/2011/REC-css3-color-20110607///4.3. Extended color keywords参看具体的名称 .color col0{colors::silver};//nana::color_rgb将整数解释为颜色color col1{static_cast<color_rgb>(0x112233)}; //red=0x11,green=0x22,blue=0x33//nana::color_argb/nana::color_rgba 将整数解释为带透明通道的颜色.color col2{static_cast<color_argb>(0xff112233)}; //alpha=0xff,red=0x11,green=0x22,blue=0x33color col3{static_cast<color_rgba>(0x112233ff)}; //red=0x11,green=0x22,blue=0x33,alpha=0xff

这些助手类型都表示32位整数,这将有助于将一组颜色数据初始化为color对象。


2,接口变更

一些接口命名的变更。

API::background/foreground变更为API:;bgcolor/fgcolor

widget::background/foreground变更为widget::bgcolor/fgcolor


一些graphics类的成员函数变更。

函数名(int x, int y)变更为 函数名(const nana::point& pos);

函数名(int x, int y, unsigned width, unsigned height) 变更为 函数名(const nana::rectangle& r);


新特性

1,widget的颜色方案

颜色方案是一个用于个性化显示widget的子系统。Nana库基本上提供了用于修改widget背景色和前景色的接口,但是这对一个复杂复合型的widget来说,例如listbox,这两个接口是不够的。通过颜色方案,就可以实现修改listbox的顶栏颜色。

//nana::listbox lsbox;lsbox.scheme().header_bgcolor = nana::colors::yellow;lsbox.scheme().header_grabbed = nana::colors::chocolate;nana::API::refresh_window(lsbox); //应用这些修改

感谢网友qPCR4vir提出该功能的建议。


2,多显示器的支持

类screen用于查询显示器的信息,以确定将widget放置到合适的显示器中。老的API::screen_size()被移除。

感谢beru提出该功能的需求,并提供了Nana项目的第一笔捐款。


3,Textbox高亮化

Textbox添加了一组新的接口,用于定义一组高亮化显示。简单易用。

using namespace nana;//textbox tb;tb.set_highlight("sqlrev", colors::dark_blue, colors::yellow);tb.set_keywords("sqlrev", false, true, { "select", "from", "where"});tb.set_highlight("table-name", colors::red, {});tb.set_keywords("table-name", false, true, { "studentbase" });tb.set_highlight("field", colors::deep_sky_blue, {});tb.set_keywords("field", false, true, { "score" });

set_highlight() 定义一个高亮化方案。

set_keywords()将一组字符串以指定方案高亮化显示,这里2个bool类型的参数分别表示“大小写敏感”和“全字匹配”。


4,窗口Draw-through

Draw-through表示直接在系统窗口上进行绘制。利用该功能,可以实现通过OpenGL/DX来绘制窗口表面。

#include <windows.h>#include <gl/gl.h>#include <nana/gui.hpp>#include <nana/gui/widgets/button.hpp>#include <nana/gui/timer.hpp>void EnableOpenGL(HDC hDC, HGLRC* hRC){    PIXELFORMATDESCRIPTOR pfd;    memset(&pfd, 0, sizeof pfd);    pfd.nSize = sizeof(pfd);    pfd.nVersion = 1;    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;    pfd.iPixelType = PFD_TYPE_RGBA;    pfd.cColorBits = 24;    pfd.cDepthBits = 16;    pfd.iLayerType = PFD_MAIN_PLANE;    auto iFormat = ChoosePixelFormat(hDC, &pfd);    SetPixelFormat(hDC, iFormat, &pfd);    *hRC = wglCreateContext(hDC);    wglMakeCurrent(hDC, *hRC);}int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){    using namespace nana;    form fm;    nested_form nfm(fm, rectangle{ 10, 10, 100, 20 }, form::appear::bald<>());    nfm.show();    button btn(nfm, rectangle{ 0, 0, 100, 20 });    btn.caption(L"Exit");    btn.events().click([&fm]{        fm.close();    });    HGLRC hRC;    auto hwnd = reinterpret_cast<HWND>(fm.native_handle());    HDC hDC = ::GetDC(hwnd);    EnableOpenGL(hDC, &hRC);    float theta = 0.0f;    //Define a opengl rendering function    fm.draw_through([hDC, theta]() mutable    {        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);        glClear(GL_COLOR_BUFFER_BIT);        glPushMatrix();        glRotatef(theta, 0.0f, 0.0f, 1.0f);        glBegin(GL_TRIANGLES);        glColor3f(1.0f, 0.0f, 0.0f);   glVertex2f(0.0f, 1.0f);        glColor3f(0.0f, 1.0f, 0.0f);   glVertex2f(0.87f, -0.5f);        glColor3f(0.0f, 0.0f, 1.0f);   glVertex2f(-0.87f, -0.5f);        glEnd();        glPopMatrix();        SwapBuffers(hDC);        glFinish();        theta += 1.0f;    });    fm.events().destroy([hwnd, hDC, hRC]    {        wglMakeCurrent(nullptr, nullptr);        wglDeleteContext(hRC);        ReleaseDC(hwnd, hDC);    });    timer tmr;    tmr.elapse([hwnd]{        RECT r;        ::GetClientRect(hwnd, &r);        ::InvalidateRect(hwnd, &r, FALSE);    });    tmr.interval(20);    tmr.start();    fm.show();    exec();    return 0;}

感谢Tom分享了这方面的经验。


5,Spinbox

Spinbox是一个新的widget,它可以让用户在一个可选范围内选择一个值。这些值可以是一组整数,浮点数和文本文字。

#include <nana/gui.hpp>#include <nana/gui/widgets/spinbox.hpp>int main(){    using namespace nana;    form fm;    spinbox spbox(fm, rectangle{10, 10, 100, 30});    spbox.range(0, 100, 1); //Set the range of integers    fm.show();    exec();}

spinbox::range()有4个重载版本,每个版本决定了用户输入值的类型。

/// 设置数字值.void range(int begin, int last, int step);void range(double begin, double last, double step);/// 设置文本值.void range(std::initializer_list<std::string> steps_utf8);void range(std::initializer_list<std::wstring> steps);

6,Inputbox

Inputbox提供了一个简单方便,用于用户输入的对话框。它可以让用户输入一个值或者多个值。

using namespace nana;form fm;    fm.events().click([&fm]{    //将这些单词翻译成中文.    internationalization i18n;    i18n.set("OK", L"确定");    i18n.set("Cancel", L"取消");    i18n.set("February", L"二月");    //定义一个inputbox.    inputbox ibox(fm, L"description hello this is a long description.", L"title");    //定义用户输入的内容.    //获取一个整数    inputbox::integer integer{L"标签", 15, -10, 100, 1};    //获取一个浮点数    inputbox::real real{ L"输入一个浮点数", 15, -10, 100, 1.5 };    //获取一个指定范围中的字符串.    inputbox::text text0( L"combox text", { L"Hello", L"Nana", L"C++", L"Library" } );    //获取任意输入的文本.    inputbox::text text1{ L"textbox text" };    //获取一个日期.    inputbox::date date{L"日期"};    //显示inputbox,当用户点击了 确定 按钮,show()将返回true。    if (ibox.show(integer, real, text0, text1, date))    {        auto n = integer.value(); //int        auto r = real.value();    //double        auto t1 = text0.value();  //nana::string(std::wstring)        auto t2 = text1.value();  //nana::string        auto d1 = date.value();   //nana::string        auto year = date.year();  //int        auto month = date.month(); //int        auto day = date.day();     //int    }});

Inputbox提供了两个显示函数:show()和show_modal(),如它们名称那样,show()不会阻止用户与其它窗口的交互;show_modal()会阻止用户与其它窗口的交互,并直到inputbox被关闭,也就是模态对话框。


7,终止事件传播

所有事件参数都包含一个名为stop_propagation()的方法。当该方法被调用之后,之后的可忽略的事件处理函数将不在被调用。

int main(){    using namespace nana;    form fm;    fm.events().click([]{        //该处理函数会被调用,但是这并不是最先被调用的。    });    fm.events().click([](const arg_mouse& arg){        arg.stop_propagation();    });    fm.events().click([]{        //它不会被调用。    });    fm.events().click.connect_unignorable([]{        //会被调用,因为这是一个不可忽略的事件处理函数    });    fm.events().click.connect_front([]{        //这个最先被调用,因为它被放在事件链的最前面。    });    fm.show();    exec();}

8,单选Listbox

用于开启/关闭listbox单选的新方法。

void enable_single(bool for_selection, bool category_limited);void disable_single(bool for_selection);

参数for_selection表示 选择或钩选模式,选择模式表示高亮某一项,钩选模式表示在某项开头的方框中打上钩。

参数category_limited表示是否允许在每个列别中单选。如果该参数传入false,表示整个listbox只有一项可以被选中。


0 0