LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Disable Table Cell Selection

Solved!
Go to solution

Probably best to describe what I'm trying to do.

 

I want to allow the user to select a row using the row label button which highlights all the cells in that row. That works.

I ONLY want the user to be able to select a row using the row label button. No cell selection of any kind allowed.

 

I've tried making the cells VAL_INDICATOR and NO_EDIT_TEXT, but you can still mouse click on a single cell, select text (but can't edit it). 

Any way to completely disallow cell selection? The idea is:

 

The user selects a row (which represents a DAQ channel), then mouses over to select an item from a tree containing information regarding the data that will be captured using that channel, That information then populates the two columns in the table. The next row is then automatically highlighted and the user picks another item from the tree.

 

If they make a mistake, then can select the row label, thereby highlighting the row, but clicking on a cell should do nothing.

 

Any ideas how to implement? Graphic jpg clip of the uir panel under work attached for clarification.

0 Kudos
Message 1 of 6
(5,797 Views)

Here is a small code abstract taken from an application of mine that can offer you some suggestions. the code reacts to either a double-click on a cell or to a column selection, but you can easily change it to a row selection.

 

int CVICALLBACK TableCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
int	row = eventData2 - 1;	// index of clicked column

if (event == EVENT_LEFT_DOUBLE_CLICK) {
	// Double-click: do something
	GetTableCellFromPoint (panel, control, MakePoint (eventData2, eventData1), &cell);
	if (!cell.x || !cell.y) return 0;	// Clicked on scrollbar: do nothing
	GetActiveTableCell (panel, control, &cell);
	// Do something based on the table cell clicked
	return 0;
}
else if (event == EVENT_EDIT_MODE_STATE_CHANGE && eventData1) {
	// Exclude that the clicked cell changes to edit state
	SetCtrlAttribute (panel, control, ATTR_TABLE_RUN_STATE, VAL_SELECT_STATE);
	return 0;
}
else if (event != EVENT_TABLE_ROW_COL_LABEL_CLICK || row <= 0)
	// Exit if not clicked a column label
	return 0;

// Rest of the function

return 0;
}

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 6
(5,784 Views)

Thank you Robert, helpful as always! I implemented part of what is shown and it helps, however the user can still select a range within the table. I want to restrict that functionality to only allowing a single row to be selected, never a range of cells.

Any ideas?

0 Kudos
Message 3 of 6
(5,720 Views)
Solution
Accepted by topic author scottrod

You can do this by swallowing any unwanted mouse click events.  This would include:

  • Any left-click when the mouse is clicked on any part of the table other than a row label.
  • Any left-double-click or right-click.

 

#include <userint.h>
#include "test.h"

#define ROW_HEIGHT 21

int top;
int left;
int colLabelsHeight;
int rowLabelsWidth;
int height;

int tableRowSelected = 0;

int main(void)
{
    // Load the panel
    int panel = LoadPanel(0, "test.uir", PANEL);
    DisplayPanel(panel);
    
    // Read the table dimensions
    GetCtrlAttribute(panel, PANEL_TABLE, ATTR_TOP, &top);
    GetCtrlAttribute(panel, PANEL_TABLE, ATTR_LEFT, &left);
    GetCtrlAttribute(panel, PANEL_TABLE, ATTR_COLUMN_LABELS_HEIGHT, &colLabelsHeight);
    GetCtrlAttribute(panel, PANEL_TABLE, ATTR_ROW_LABELS_WIDTH, &rowLabelsWidth);
    GetCtrlAttribute(panel, PANEL_TABLE, ATTR_HEIGHT, &height);
    
    RunUserInterface();
    
    return 0;
}

int CVICALLBACK TableClickedCb (int panel, int control, int event,
                           void *callbackData, int eventData1, int eventData2)
{
    if (event == EVENT_LEFT_CLICK)
    {
        // Only process the left-click if a row label was clicked
        if ((eventData1 >= top + colLabelsHeight) &&
            (eventData1 <= top + height) &&
            (eventData2 >= left) &&
            (eventData2 <= left + rowLabelsWidth))
        {
            // Which row was selected?
            tableRowSelected = (eventData1 - top - colLabelsHeight) / ROW_HEIGHT + 1;
        
            //
            // ... process this row click ...
            //
        }
        else
        {
            return 1;
        }
    }
    if ((event == EVENT_LEFT_DOUBLE_CLICK) || (event == EVENT_RIGHT_CLICK))
    {
        return 1;
    }
    return 0;
}

Use the tableRowSelected variable rather than GetActiveTableCell or GetTableSelection to keep track of which row is active.

 

 

 

0 Kudos
Message 4 of 6
(5,699 Views)

Note: my sample code above assumes that the entire table is visible.  If there are scroll bars involved, things get more complicated.

0 Kudos
Message 5 of 6
(5,692 Views)

An interesting approach Rich, thanks. I did set up a method that works but yours is more elegant.

 

Still learning how to properly use Callbacks. It's coming, but it takes a different thought process and approach to break away from my long-engrained, top-down background.

 

Thanks,

Scott

0 Kudos
Message 6 of 6
(5,661 Views)