Monday, May 14, 2012

How to Use Multiple Panels

    Written by Erez Wenger - May 2012

In this post we show, in screenshots and code-lines, how to create and handle multiple panels in CVI.

Using multiple panels (windows) is very useful for handling large amount of controls or data, adding more panels allows you to add more content while keeping the use interface ordered and neat (every panel has its own function and is dedicated to a different task).

UIR Operations

To add another panel right click outside the first panel and select "Panel":





The second panel will appear in the UIR, next edit the panel properties:





There are two main parametes:
  • the Constant Name which has to be a unique name and acts like the panel's ID.
  • the Callback Function of the panel, the function can be the same function used for the first panel (in this case you need to address both panels inside the function) or it can be a unique function (like in the example).
The next step is to generate the second panel's function by highlighting the panel and clicking Code->Generate->Panel Callback.



This action will generate the code for the panel function which we will address later.

Code Operations

 There are 3 steps for dealing with multiple panels in the code:

1. Handling with memory representation - when you generate code for a new CVI program, CVI adds automatically the memory representation of the panel, when adding a new panel you need to do it manually for the second panel:

  • Add a new global static int variable (panelHandle_2). 
  • Duplicate the LoadPanel function code from the first panel and change the panel handle and panel Constant name accordingly (panelHandle_2, PANEL_2)
  • Duplicate the DiscardPanel function code of the first panel and change the panel handle accordingly (panelHandle_2).

static int panelHandle, panelHandle_2;

int main (int argc, char *argv[])
{
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;    /* out of memory */
    if ((panelHandle = LoadPanel (0, "pt.uir", PANEL)) < 0)
        return -1;
    if ((panelHandle_2 = LoadPanel (0, "pt.uir", PANEL_2)) < 0)
        return -1;
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
    DiscardPanel (panelHandle_2);
    return 0;
}

The LoadPanel function loads the panel to the memory and represent it by the panel handle variable.
The DiscardPanel function unloads the panel from the memory.

2. Handling with the panel's appearance - when you use multiple panels they won't be displayed automatically, you need to manually specify in the code where and when you want the panels to be displayed or to be hidden, in our example we will define that the second panel will be displayed when we commit a command button and will be hidden when the user commit the X button on the top-right corner:

  • Add the DisplayPanel function to the code with the appropriate panel handle (panelHandle_2).
  • Add the HidePanel function to the code with the appropriate panel handle (panelHandle_2).

int CVICALLBACK open_2p (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:

            DisplayPanel (panelHandle_2);
           
            break;
    }
    return 0;
}

int CVICALLBACK panelFunc_2 (int panel, int event, void *callbackData,
        int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_GOT_FOCUS:

            break;
        case EVENT_LOST_FOCUS:

            break;
        case EVENT_CLOSE:

            HidePanel (panelHandle_2);
           
            break;
    }
    return 0;
}

3. Handling with the panel's controls in the code - in order to deal with the panel's control in the code, you need to specify the correct panel handle (panelHandle or panelHandle_2) and constant name (that starts with the panel constant name PANEL or PANEL_2) of the control you deal with. In this example there two controls from each panel which we take their value, add them up and display the result in a control on the second panel:

int CVICALLBACK calc (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    int x, y;
   
    switch (event)
    {
        case EVENT_COMMIT:

            GetCtrlVal (panelHandle, PANEL_NUMERIC_X, &x);
            GetCtrlVal (panelHandle_2, PANEL_2_NUMERIC_Y, &y);
            SetCtrlVal (panelHandle_2, PANEL_2_NUMERIC_XY, x+y);
           
            break;
    }
    return 0;
}


4 comments: