Developer forum
cancel
Showing results for 
Search instead for 
Did you mean: 

C++ TabControl multi tab issue

ggiloyan
Newcomer
I have a TabControl (NormalTab) which has two tab

I have five classes to implement my TabControl
There is one main dialog class and two class for each tab.

My dialog opens without any problem. First tab events fires without any problem. The only problem is that second tab events (ButtonClicked) do not fire and I can not change any control text in second tab.

Here is my whole code.

resource file


'GDLG'	32511	Modal 	0	0	 444  174  "Upload IFC" {
/* [  1] */ NormalTab			  0   0  428 148
								  32512 NoIcon "New" 
								  32513 NoIcon "Existing"

}

'DLGH'  32511  DLG_32511_Upload_IFC {
1	""							uploadTabControl
}

'GDLG'  32512    TabPage  0    0 428 134  "" {
/* [  1] */  LeftText           13   23   84   13  LargePlain		"Model file name:"
/* [  2] */  TextEdit			104  18   293  20  LargePlain		256
/* [  3] */  Separator		    13   53   385  1
/* [  4] */  Button				241  68	  75   23  LargePlain		"Cancel"
/* [  5] */  Button				322  68	  75   23  LargePlain		"Upload" 
}

'DLGH'  32512  TabPage_32512 {
1	""							lblModelName_New
2	""							txtModelName
3	""							seperator_0
4	""							btnCancel
5	""							btnUpload
}

'GDLG'  32513    TabPage  0    0 428 134  "" {
/* [  1] */  LeftText           13   23   84   13  LargePlain		"Model file name:"
/* [  2] */  PopupControl		104  18   293  20  144 0
/* [  3] */  Separator		    13   53   385  1
/* [  4] */  Button				241  68	  75   23  LargePlain		"Cancel"
/* [  5] */  Button				322  68	  75   23  LargePlain		"Upload" 
}

'DLGH'  32513  TabPage_32513 {
1	""							lblModelName_Existing
2	""							comboModelName
3   ""							seperator_2
4	""							btnCancel
5	""							btnUpload
}

.h file

class ExportDialog : public DG::ModalDialog
{

	friend class NewTabControl;
	friend class NewTabControlObserver;

	friend class EditTabControl;
	friend class EditTabControlObserver;

private:

	enum ui  {
	
		id = 32511,
		normalTabID = 1
	};

	DG::NormalTab   m_normalTab;
	
	NewTabControl		*m_newTabControl;	
	NewTabControlObserver  *m_newTabObserver;
	
	EditTabControl		*m_editTabControl;
	EditTabControlObserver	*m_editTabObserver;

public:
	ExportDialog();
	~ExportDialog();

private:
	ExportDialog(const ExportDialog&);
	const	ExportDialog& operator=(const ExportDialog&); //Disabled

};

// ----------------------------------------------- New tabe class---------------------------------------------------- 

class NewTabControl : public DG::TabPage 
{
	friend class NewTabControlObserver;

private:
	
	enum ui {
		
		TabID = 32512,
		lblModelNameID = 1,
		txtModelNameID = 2,
		seperator0ID = 3,
		btnCancelID = 4,
		btnUploadID = 5
	};

	DG::TextEdit	m_txtModelName;
	DG::Button		m_btnCancel;
	DG::Button		m_btnSave;

public:
	NewTabControl( const DG::TabControl& tabControl, short tabItem );
	~NewTabControl( void );
};

class EditTabControl : public DG::TabPage 
{
	friend class EditTabControlObserver;

private:
	
	enum ui {
		
		TabID = 32513,
		comboModel = 2,
		btnCancelID = 4,
		btnUploadID = 5
	};

	DG::PopUp		m_comboModel;
	DG::Button		m_btnCancel;
	DG::Button		m_btnSave;

public:
	EditTabControl( const DG::TabControl& tabControl, short tabItem );
	~EditTabControl( void );
};


// ----------------------------------------------- TabControlObserver ----------------------------------------------- 

class NewTabControlObserver :  public DG::PanelObserver, 
               public DG::NormalTabObserver, 
               public DG::ButtonItemObserver, 
               public DG::CompoundItemObserver 
{ 
private: 
	NewTabControl		*m_newTabControl; 
	ExportDialog		&mainDialog;

protected: 
   // DG::PanelObserver 
   virtual void   PanelOpened (const DG::PanelOpenEvent& ev) override;
   // DG::ButtonItemObserver 
   virtual void   ButtonClicked (const DG::ButtonClickEvent& ev) override; 

public: 
   explicit      NewTabControlObserver (NewTabControl* newTabControl, ExportDialog &exportDialog); 
   ~NewTabControlObserver (); 
}; 

// ----------------------------------------------- EditControlObserver -----------------------------------------------

class EditTabControlObserver : public DG::PanelObserver, 
               public DG::NormalTabObserver, 
               public DG::ButtonItemObserver, 
               public DG::CompoundItemObserver 
{ 
private: 
	EditTabControl		*m_EditTabControl; 
	ExportDialog		&mainDialog;

protected: 
   // DG::PanelObserver 
   virtual void   PanelOpened (const DG::PanelOpenEvent& ev) override;

   // DG::ButtonItemObserver 
   virtual void   ButtonClicked (const DG::ButtonClickEvent& ev) override; 

public: 
   explicit      EditTabControlObserver (EditTabControl* editTabControl, ExportDialog &exportDialog); 
   ~EditTabControlObserver (); 
}; 
.cpp


ExportDialog::ExportDialog() : 
ModalDialog (ACAPI_GetOwnResModule (), ui::id, InvalidResModule),
	m_normalTab(GetReference (), ui::normalTabID),

	m_newTabControl(new NewTabControl(m_normalTab, ui::normalTabID)),
	m_newTabObserver(new NewTabControlObserver(m_newTabControl, *this)),

	m_editTabControl(new EditTabControl(m_normalTab, ui::normalTabID)),
	m_editTabObserver(new EditTabControlObserver(m_editTabControl, *this))
{

}

ExportDialog::~ExportDialog()
{
	delete m_newTabObserver;
	delete m_newTabControl;
}

//------------------------------ NewTabClass -------------------------------- 

NewTabControl::NewTabControl (const DG::TabControl& tabControl, short tabItem): 
		DG::TabPage         (tabControl, tabItem, ACAPI_GetOwnResModule(), ui::TabID, ACAPI_GetOwnResModule ()), 
		m_txtModelName      (GetReference (), ui::txtModelNameID),
		m_btnCancel(GetReference (), ui::btnCancelID),
		m_btnSave(GetReference (), ui::btnUploadID)
{ 
 
}
  
NewTabControl::~NewTabControl () 
{ 
	
} 


//-----------------------------------------------------------------EditTabClass----------------------------------------------------------
 
EditTabControl::EditTabControl (const DG::TabControl& tabControl, short tabItem): 
DG::TabPage         (tabControl, tabItem, ACAPI_GetOwnResModule(), ui::TabID, ACAPI_GetOwnResModule ()), 
		m_comboModel      (GetReference (), ui::comboModel),
		m_btnCancel(GetReference (), ui::btnCancelID),
		m_btnSave(GetReference (), ui::btnUploadID)
{ 
 
	this->m_btnCancel.SetText("ascaca");
}
  
EditTabControl::~EditTabControl () 
{ 
} 


//-------------------------- Class TabControlObserver ----------------------- 

NewTabControlObserver::NewTabControlObserver (NewTabControl* newTabControl, ExportDialog &exportDialog): 
   m_newTabControl (newTabControl),
   mainDialog(exportDialog)
{ 
   m_newTabControl->Attach (*this); 
   AttachToAllItems (*m_newTabControl); 
} 


NewTabControlObserver::~NewTabControlObserver () 
{ 
   m_newTabControl->Detach (*this); 
   DetachFromAllItems (*m_newTabControl); 
} 


void NewTabControlObserver::PanelOpened (const DG::PanelOpenEvent& ev) 
{ 
  
} 
 
void NewTabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) 
{ 
   // Close dialog with acceptance 
	
	if (ev.GetSource () == &m_newTabControl->m_btnCancel) { 
	  
		mainDialog.PostCloseRequest(DG::ModalDialog::Accept);

    }  
	else if ( ev.GetSource() == &m_newTabControl->m_btnSave ) 
	{
		
		
	}
} 

//---------------------------------------------------------------------------------------------------------------------------------------------------------

//-------------------------- Class TabControlObserver ----------------------- 

EditTabControlObserver::EditTabControlObserver (EditTabControl* editTabControl, ExportDialog &exportDialog): 
   m_EditTabControl (editTabControl),
   mainDialog(exportDialog)
{ 
   m_EditTabControl->Attach (*this); 
   AttachToAllItems (*m_EditTabControl); 
} 


EditTabControlObserver::~EditTabControlObserver () 
{ 
   m_EditTabControl->Detach (*this); 
   DetachFromAllItems (*m_EditTabControl); 
} 


void EditTabControlObserver::PanelOpened (const DG::PanelOpenEvent& ev) 
{ 
 
} 
 
 
void EditTabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) 
{ 
   // Close dialog with acceptance 
	
	if (ev.GetSource () == &m_EditTabControl->m_btnCancel) { 
	  
		mainDialog.PostCloseRequest(DG::ModalDialog::Accept);

    }  
	else if ( ev.GetSource() == &m_EditTabControl->m_btnSave ) 
	{
		
		
	}
} 

7 REPLIES 7

Tibor Lorantfy
Graphisoft
Graphisoft
Hi,

There could be more bugs in your code, but the first I noticed is the following:
You should have an observer class for your modaldialog also (ExportDialogObserver), so 2 class for each.
And the modaldialog's observer should be inherited from DG::PanelObserver, DG::NormalTabObserver and DG::CompoundItemObserver.

It's a mistake in your code that your tabpages' observers inherited from DG::NormalTabObserver, however they don't have any NormalTab, so please delete that inheritance.

Regards,
Tibor

ggiloyan
Newcomer
Tibor wrote:
Hi,

There could be more bugs in your code, but the first I noticed is the following:
You should have an observer class for your modaldialog also (ExportDialogObserver), so 2 class for each.
And the modaldialog's observer should be inherited from DG::PanelObserver, DG::NormalTabObserver and DG::CompoundItemObserver.

It's a mistake in your code that your tabpages' observers inherited from DG::NormalTabObserver, however they don't have any NormalTab, so please delete that inheritance.

Regards,
Tibor

Than you for the response.

What concern to tabpage's observers I removed the DG::NormalTabObserver.

The strange thing is that first tab functionality working fine. The only problem is second tab.

What concern ModelDialog why I should have an observer class ?

Some times age you gave me this example where the main dialog has no observer

http://archicad-talk.graphisoft.com/viewtopic.php?t=48241

Tibor Lorantfy
Graphisoft
Graphisoft
ggiloyan wrote:
Some times age you gave me this example where the main dialog has no observer

http://archicad-talk.graphisoft.com/viewtopic.php?t=48241
That is not true.
In that code TabControlDialog has an observer class named TabControlObserver.

ggiloyan
Newcomer
I'm confused.

So please explain me why my code works only for first tab ?
And why I need Observer also for Dialog ?

Tibor Lorantfy
Graphisoft
Graphisoft
ggiloyan wrote:
So please explain me why my code works only for first tab ?
And why I need Observer also for Dialog ?
Observers handle the user interface changes. So if the user selects an another tab, then the observer must handle it and run the required updates.
In your case I think one of the required updated didn't run and that's why you should implement an observer for your dialog class, and attach the observer to the dialog.

ggiloyan
Newcomer
I added also Dialog's observer but the result is the same

The strange thing is that my second tab constructor working and in constructor I wrote this this->m_btnCancel.SetText("ascaca"); which does not change the button name.

Here is the new dialog's observer class


class TabControlObserver:   public DG::PanelObserver, 
               public DG::NormalTabObserver, 
               public DG::ButtonItemObserver, 
               public DG::CompoundItemObserver 
{ 
private: 
   ExportDialog*      mDialog; 

protected: 
   // DG::PanelObserver 
   virtual void   PanelOpened (const DG::PanelOpenEvent& ev) override; 

   // DG::ButtonItemObserver 
   virtual void   ButtonClicked (const DG::ButtonClickEvent& ev) override; 

public: 
   explicit      TabControlObserver (ExportDialog* testDialog); 
   ~TabControlObserver (); 
}; 

.cpp
TabControlObserver::TabControlObserver (ExportDialog* testDialog): 
   mDialog (testDialog) 
{ 
   mDialog->Attach (*this); 
   AttachToAllItems (*mDialog); 
} 


TabControlObserver::~TabControlObserver () 
{ 
   mDialog->Detach (*this); 
   DetachFromAllItems (*mDialog); 
} 


void TabControlObserver::PanelOpened (const DG::PanelOpenEvent& /*ev*/) 
{ 
   mDialog->SetClientSize (mDialog->GetOriginalClientWidth (), mDialog->GetOriginalClientHeight ()); 
} 


void TabControlObserver::ButtonClicked (const DG::ButtonClickEvent& ev) 
{ 
   
} 

And I'm calling the dialog by this way
ExportDialog      dialog (ACAPI_GetOwnResModule (), 32511); 
   
	if (DBERROR (dialog.GetId () == 0)) { 
		return; 
	} 
  
	TabControlObserver      observer (&dialog); 
	dialog.Invoke (); 
	return;

DevJeer
Newcomer
Hi.
I have the same problem.
What is the solution to this problem?
Thanks.

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!