LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

User switch between tab and independant panel

Solved!
Go to solution

Hello all,

sometimes a panel is better in it own window, sometimes it's better as part of a tab... and sometimes the user can't make up his mind and it would be nice to have the possibility to switch between one and the other at will. I know there are a few differences between using a tabbed panel and a separate one, so before I spend some time on this, are there any examples of .UIR where the user can separate at will ?

For instance I don't think you can drop a panel onto a tab and hope to catch a DROP even. So some kind of button would be required. Any other issues to consider ?

Thanks.

0 Kudos
Message 1 of 3
(2,975 Views)

I don't expect the drop command to work either!

What you can think of is to let the user select the desired aspect and then use InsertPanelAsTabPage to transform from independent panels to a tab control, and DuplicatePanel to move the opposite direction. Provided you save the panel handle (whichever it is) to a variable that you use in every UI call, you should notice no major difference in program behaviour. When changing the way the application is run you will need to update the variable with the new handle and discard the old panel afterwards.

(It's more or less what View >> Workspace View Selection option in CVI IDE environment does)



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 3
(2,961 Views)
Solution
Accepted by topic author gdargaud

Yup, I got it to work. Here's the heart of the code. I've tested it starting from a bunch of filled tabs and top-level panels.

 

/* The following 2 functions switch between SDI and MDI
   SDI: Single Document Interface - The panel is top-level
   MDI: Multiple Document Interface - The panel is in a Tab
   Have a panel with a tab ready
   Place a picture ring (without inc/dec arrows) in the panel you wish to (un)tab
   and use the following callback function on it:
int  CVICALLBACK cb_TabToPanel(int panel, int control, int event, 
							   void *callbackData, int eventData1, int eventData2) {
	BOOL ToTab;
	switch (event) {
		case EVENT_LEFT_CLICK:
			GetCtrlVal(panel, control, &ToTab);
			SetCtrlVal(panel, control, ToTab=!ToTab);
			if (ToTab) MovePanelToTab(pTab, PTAB_TAB, &PnlHandle); // And not 'panel' as the value will change
			else PnlHandle=MovePanelFromTab(pTab, PTAB_TAB, 
						PnlHandle==0 ? -1 : GetTabIndexFromPanel(pTab, PTAB_TAB, PnlHandle));
			break;
	}
	return 0;
}
*/

///////////////////////////////////////////////////////////////////////////////
/// HIFN	Take an existing top-level panel and pushes it inside a tab (at the last position)
/// OUT		Panel
/// HIPAR	Panel/Panel to put inside a tab. 
/// HIPAR	Panel/THE HANDLE WILL CHANGE, so use a variable, not a callback function parameter
/// HIPAR	pTab/Panel containing the tab
/// HIPAR	TabCtrl/Handle of the tab control
/// HIRET	Index of the newly created tab
///////////////////////////////////////////////////////////////////////////////
int MovePanelToTab(int pTab, int TabCtrl, int *Panel) {
	if (*Panel<0) return -1;
	int NewTabIndex = InsertPanelAsTabPage (pTab, TabCtrl, -1, *Panel);
	DiscardPanel(*Panel);
	GetPanelHandleFromTabPage (pTab, TabCtrl, NewTabIndex, Panel);
	SetCtrlAttribute (pTab, TabCtrl, ATTR_CTRL_INDEX, NewTabIndex);
	return NewTabIndex;
}

///////////////////////////////////////////////////////////////////////////////
/// HIFN	Takes a tab and turn it into an independant panel
/// HIFN	Note that it removes it from the tab, so the index of the next tabs will change
/// HIPAR	pTab/Panel containing the tab
/// HIPAR	TabCtrl/Handle of the tab control
/// HIPAR	index/index of the tab to turn into a panel (will be deleted) or -1 to use active one
/// HIRET	Panel handle of newly independant tab
/// HIRET	- note that it is different from the handle obtained from the tab
///////////////////////////////////////////////////////////////////////////////
int MovePanelFromTab(int pTab, int TabCtrl, int index) {
	int Pnl, Len;
	if (index<0) GetActiveTabPage (pTab, TabCtrl, &index);
	GetPanelHandleFromTabPage (pTab, TabCtrl, index, &Pnl);
	int NewPnl = DuplicatePanel (0, Pnl, 0, VAL_KEEP_SAME_POSITION, VAL_KEEP_SAME_POSITION);
	SetPanelAttribute(NewPnl, ATTR_TITLEBAR_VISIBLE, 1);
	// Optional
	GetPanelAttribute (NewPnl, ATTR_TITLE_LENGTH, &Len);
	if (Len==0) {
		char Str[256];
		GetTabPageAttribute (pTab, TabCtrl, index, ATTR_LABEL_TEXT, Str);
		SetPanelAttribute (NewPnl, ATTR_TITLE, Str);
	}
	
	DeleteTabPage (pTab, TabCtrl, index, 1);
	DisplayPanel     (NewPnl);
	SetActivePanel   (NewPnl);
	return NewPnl;
}

///////////////////////////////////////////////////////////////////////////////
/// HIFN	Get the index of a panel that's inside a tab
/// HIPAR	pTab/Panel containing the tab
/// HIPAR	TabCtrl/Handle of the tab control
/// HIPAR	Panel/Handle of the panel to look for within that tab
/// HIRET	The tab index of the panel, or -1 if not found
///////////////////////////////////////////////////////////////////////////////
int GetTabIndexFromPanel(int pTab, int TabCtrl, int Panel) {
	int Count, i, Pnl;
	GetNumTabPages (pTab, TabCtrl, &Count);
	for (i=0; i<Count; i++) {
		GetPanelHandleFromTabPage (pTab, TabCtrl, i, &Pnl);
		if (Pnl==Panel) return i;
	}
	return -1;
}

0 Kudos
Message 3 of 3
(2,933 Views)