Dxutgui control Customization

Source: Internet
Author: User
Tags bmp image
Customization includes two aspects: customization of the entire control library style and customization of specific control instances.

Let's talk about the overall UI style customization.

SDK customui to learn about dxut.
This example declares a global dialog box resource management object cdxutdialogresourcemanager g_dialogresourcemanager, and then uses it to initialize three dialogs respectively. Take the sampleui dialog box as an example. The initialization statement is in the initapp function: g_samleui.init (& g_dialogresourcemanager ). There is only one parameter for calling the init function, and the other is the default bregisterdialog = true.

Dxut implements buttons, lists, optional buttons, and edit boxes. At first I thought the control was directly drawn (this feeling is too stupid), and later I thought it should be a texture map. However, it seems that you must read the source code of dxutgui.

It is a good choice to study the Resource Management of dxutgui starting with the init function. I followed in and found that the "skin" texture will be loaded from the memory when the dialog box is initialized as in the example program. The memory texture resources used by dxutgui are in the DDS format and stored in the g_dxutguitexturesrcdata array of dxutres. cpp. This is where its mysteries are.

Save the texture as a BMP image (256x256) to view the resources of the dxutgui control.

With this discovery, we can implement our own style. Only two steps are required:

(1) Create your own image based on the skin texture inherent in dxutgui
(2) In the initialization dialog box, select the init function of the three parameters to specify the path of the texture image.

Note that the image we make must be the same as the image type used by dxutgui, including the texture areas corresponding to various elements. Otherwise, the image may be messy. Of course, there is another way not to be consistent with the dxutgui image specifications: Modify the cdxutdialog: initdefaultelements function.

Studying the initdefaultelements function can help us to understand how dxutgui uses texture skins and implement our own skins.

The default control provided by dxutgui has achieved transparent effects and effects similar to color keys. There is no direct Color Key (in Direct Draw) function in d3d. However, the alpha channel can be used to achieve similar effects, but the image must have an alpha channel.

The texture of the dxutgui control is implemented in this way. You can use Photoshop to open the saved texture image and see the image of its alpha channel.

To implement the transparent and Color Filtering Function in d3d9, two steps are required.

(1) define the fvf struct, including the vertex color field. Define the fvf tag to include d3dfvf_diffuse.

Struct customvertext {
Float X, Y, Z, h;
DWORD color;
};

# Define customfvf d3dfvf_xyzrhw | d3dfvf_diffuse

(2) set the rendering status:

Pd3ddevice-> setrenderstate (d3drs_alphablendenable, true );
Pd3ddevice-> setrenderstate (d3drs_srcblend, d3dblend_srcalpha );
Pd3ddevice-> setrenderstate (d3drs_destblend, d3dblend_invsrcalpha );
Pd3ddevice-> settexturestagestate (0, d3dtss_alphaop, d3dtop_modulate );
Pd3ddevice-> settexturestagestate (0, d3dtss_alph1_g1, d3dta_texture );
Pd3ddevice-> settexturestagestate (0, d3dtss_alph1_g2, d3dta_diffuse );

The transparency effect is achieved through the Alpha value of the vertex color (0 completely transparent, 255 transparent), and the color filtering is achieved through the alpha channel of the texture, the product of the two can achieve "Transparency + filtering. In this way, you can implement irregular and transparent controls.

In dxutgui, if you want to set the transparency of a control, you can call the getelement function of the control to obtain the pointer of the cdxutelement type and call its settexture function.

To set the transparency of a certain type of control, call cdxutdialog: getdefaultelement to obtain the pointer of the molecular object of the control, and modify the alpha channel of its texturecolor member (or call the settexture function ).

After knowing how dxutgui achieves the above results, we have the basis for customizing the UI. By providing images with Alpha channels for dxutgui, You can implement various effects as you like. However, how to make dxutgui use our own images for a widget (such as a button) requires further mining and implementation.

Custom Controls

By default, the dxutgui control library uses built-in texture resources. This texture resource can be specified as our own texture Resources in the init function of cdxutdialog (it can be replaced by an image file ).

Studying the initdefaultelements function of cdxutdialog, we can find that dxutgui defines several elements for each control, which are stored in the m_defaultelements array. When a new control is added, compare the control type. Extract the Element Set of this type from defaultelements and pass it to the control. The control generates its own element instance and saves it.

We found that the texture resources are stored in the member variable m_texturecache of cdxutdialogresourcemanager. M_texturecache is a dynamic array that stores any texture resources, such as the image texture of a button and the background texture of a list box. You only need to call the cdxutdialg: settexture function and specify an ID and texture file name.

The texture is saved. Next we only need to let the control use our own texture for customization. Controls can be customized into three types: single control customization, one type of control customization, and new control generation. The following describes how to implement it.

I. Single control Customization

The customization of a single control is relatively simple. Taking buttons as an example, three steps are required:

(1) cdxutdialog: addbutton generate button pbtn
(2) cdxutdialog: settexture: generate the texture of the button and record the texture number ntexture
(3) pbtn-> getelement gets the cdxutelement pointer pelem, pelem-> settexture, and modifies the texture used by the control to ntexture.

The above customization is restricted by dxutgui. You need to generate your own texture resources based on the rendering method of the implemented controls, and check initdefaultelements to determine how to call cdxutelement: settexture and cdxutelement :: setfont.

Ii. customization of single-class controls

To customize a type of control, you need to change the default elements of the Control. This can be achieved through cdxutdialog: setdefaultelement. Two steps are required:

(1) cdxutdialog: settexture: generate the texture of the control class and record the texture number ntexture
(2) cdxutdialog: getdefaultelement or the pointer pelem of the default element object, and then modify pelem-> settexture.

STEP (2) also has another implementation method. Declare the cdxutelement object, set its members, and then call cdxutdialog: setdefaultelement to rewrite the default Element Set generated during initialization. In any case, you need to understand what is done in the initdefaultelements function.

3. generate new control types

To generate a new control and use a custom texture, take the following steps:

(1) Implement controls
(2) Load Resources
(3) generate a default element set for a new control
(4) generate a control instance and add it to the dialog box

We do not change dxut's own files. Everything is implemented in our own files.

(1) The control provided by dxutgui may not be able to meet our needs. Sometimes we need to implement new controls and tablet buttons on our own. We can derive from cdxutcontrol or a specific control class. Next we will take the implementation of the image button as an example to illustrate, first look at the code.

class CDXUTImageButton : public CDXUTButton
{
public:
    CDXUTImageButton(CDXUTDialog *pDialog = NULL ):CDXUTButton(pDialog)
    {
        m_Type = (DXUT_CONTROL_TYPE)(DXUT_CONTROL_SCROLLBAR + 1);
    };
    ~CDXUTImageButton(void)...{};
    virtual void Render( float fElapsedTime )
    {    
int nOffsetX = 0;
    int nOffsetY = 0;
    DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
    int iIndex = 0;
    if( m_bVisible == false )
    {
        iState = DXUT_STATE_HIDDEN;
    }
    else if( m_bEnabled == false )
    {
        iState = DXUT_STATE_DISABLED;
        iIndex = 2;
    }
    else if( m_bPressed )
    {
        iState = DXUT_STATE_PRESSED;
        iIndex = 1;
    }
    else if( m_bMouseOver )
    {
        iState = DXUT_STATE_MOUSEOVER;
        iIndex = 3;
    }
    else if( m_bHasFocus )
    {
        iState = DXUT_STATE_FOCUS;
        iIndex = 3;
    }
    // Main button
    CDXUTElement *pElement = m_Elements.GetAt( iIndex );
    float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
    // Blend current color
    pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
    m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, 0.8f );
};

We need to specify a control type for cdxutimagebutton and choose dxut_control_scrollbar + 1. At the same time, rewrite the render function of cdxutbutton and draw different texture elements based on the button status. The image we provide has four States (sequence): normal state, under-pressure state, prohibited state, and hover state, corresponding to the four states of the button.

(2) With the image button class, we need to load the button resources. You can use cdxutdialog: settexture.
(3) Call cdxutdialog: setdefaultelement four times to set four elements for the image button.
(4) assign a cdxutimagebutton object, call cdxutdialog: addcontrol, and set the ID, text, position, size, and other elements of the button.
Sample Code in steps (2), (3), and (4:

    //init custom button, normal way
    int iTexture = g_SampleUI.SetTexture(IDC_BUTTON_CUSTOM_1, L"play.tga");
    CDXUTElement elem;
    elem.iTexture = IDC_BUTTON_CUSTOM_1;
    elem.iFont = 0;
    RECT rc = {0};
    for(int i=0; i<4; i++)
    {
        SetRect(&rc, i*64, 0, (i+1)*64, 28);
        elem.SetTexture(IDC_BUTTON_CUSTOM_1, &rc, D3DCOLOR_ARGB(128, 255, 255, 255));
        g_SampleUI.SetDefaultElement(DXUT_CONTROL_SCROLLBAR+1, i, &elem);
    }
    CDXUTImageButton *imgbtn = new CDXUTImageButton(&g_SampleUI);
    g_SampleUI.AddControl(imgbtn);
    imgbtn->SetID(IDC_BUTTON_CUSTOM_1);
    imgbtn->SetText(L"CustomStyle");
    imgbtn->SetSize(64, 27);
    imgbtn->SetLocation(5, 5);


If you change the source code of dxutgui, you can add the marker item to the enumeration type dxut_control_type, add the default Element Set of the For Loop settings to the initdefaultelements function, and add the addimagebutton function to the cdxutdialog. The code for generating the button looks relatively concise, which may look like this:

G_sampleui.addimagebutton (idc_button_custom_1, l "customstyle", 5, 5, 64, 27 );

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.