BGraphWgtBase_c::~BGraphWgtBase_c( void )
{
hide();
DeleteChildren();
}
//virtual
bool BGraphWgtBase_c::Redraw()
{
QRect rectToRefresh
( boundingRect
() );
m_pParent->setChanged( rectToRefresh );
m_pParent->SetDoARedrawPlease();
return RDstatus::success;
}
bool BGraphWgtBase_c::SetMarkForDelete()
{
m_bIsMarkedForDelete = true;
hide();
// Now go through all this widget's child widgets and mark for delete too
ListWgts::iterator it = m_listChildWidgets.begin();
while( it != m_listChildWidgets.end() )
{
BGraphWgtBase_c * pWgt = *it;
if( pWgt == NULL )
{
continue;
}
pWgt->hide();
pWgt->SetMarkForDelete();
// Move to next
++it;
}
return RDstatus::success;
}
// Slot
// Visited every 500ms to do canvas updates
void BGraphCanvas_c::SlotUpdateTimer()
{
if( m_bDoARedrawPlease )
{
m_bDoARedrawPlease = false;
try
{
update();
}
catch( ... )
{
}
}
return;
}
// Set by BGraphWgtBase_c to flag that at least one item on the canvas
// would like to be updated
bool BGraphCanvas_c::SetDoARedrawPlease()
{
m_bDoARedrawPlease = true;
return RDstatus::success;
}
// This function goes through all the widgets ( canvas items ) registered with this canvas
// and deletes the items which have been marked for deletion. Widgets for this canvas class
// operation do not get deleted at source when not needed as they may be still in use, or their
// children still in use. They could be contained in the canvas's various containers at the
// time they are deemed as not needed anymore. This function and the
// BGraphWgtBase_c::SetMarkForDelete function enacts a delayed delete system. At the
// source hide the widget and mark for delete. This function is called sometime later and will delete the
// marked items. BGraphWgtBase_c::SetMarkForDelete function also at the same time informs the BGraphWgtMgr_c
// of the widget's removal so it can update its records.
// Note: Very important when this is called. For example do not call at end of
// mouseReleaseEvent(). QCanvas does behind the scenes work
// on all it canvas items after mouseReleaseEvent() and so deleting any before then
// is not a good and causes a crash.
bool BGraphCanvas_c::DeleteMarkedWgts()
{
BGraphWgtBase_c * pCurrentSelectedWgt = GetView()->GetCurrentSelectedItem();
bool bDeleteWgt = false;
QCanvasItemList listAllItems = allItems();
QCanvasItemList::iterator it = listAllItems.begin();
while( it != listAllItems.end() )
{
BGraphWgtBase_c * pWgt = dynamic_cast< BGraphWgtBase_c * >( *it );
if( (pWgt != NULL) && pWgt->IsMarkForDelete() )
{
if( pWgt == pCurrentSelectedWgt )
{
GetView()->SetCurrentSelectedItem( NULL );
}
delete pWgt;
bDeleteWgt = true;
}
// Next
++it;
}
if( bDeleteWgt )
{
update();
}
return RDstatus::success;
}
QCanvasItemList BGraphCanvas_c
::GetDlgsHitHoverOver( const QPoint & vMousePos
){
QCanvasItemList wgtHoverOverHitList;
QPoint realMousePos
( GetRealX
( vMousePos.
x() ), GetRealY
( vMousePos.
y() ) );
wgtHoverOverHitList = Collisions( realMousePos );
return wgtHoverOverHitList;
}
//virtual
void BGraphCanvas_c::update()
{
// The try catch is here to stop QCanvas crash if it comes
// across an invalid pointer to a QCanvasItem. This is a bug which
// has been difficult to solve as when is the right time to delete
// a QCanvasItem. See DeleteWgts() in this class which is there to
// try to stop this sort of thing happening.
try
{
QCanvas::update();
}
catch( ... )
{
;
}
}
QCanvasItemList BGraphCanvas_c
::Collisions( const QPoint & vMousePos
){
try
{
return collisions( vMousePos );
}
catch( ... )
{
;
}
QCanvasItemList list;
return list;
}
// vpWgtExceptThisOne would normally be the current selected widget
const RDstr BGraphCanvas_c
::GetDlgHitHoverOver( const QPoint & vMousePos, BGraphWgtBase_c
* vpWgtExceptThisOne
) {
RDstr dlgId;
if( !IsOnCanvas( vMousePos ) )
{
return dlgId;
}
QPoint realMousePos
( GetRealX
( vMousePos.
x() ), GetRealY
( vMousePos.
y() ) );
QCanvasItemList listDlgHitByMouse = Collisions( realMousePos );
// User clicked on a widget that recognised itself as hitable/selectable
dlgId = pDlgItem->GetId();
return dlgId;
}
// return: valid id or no id = no hit
const RDstr BGraphCanvas_c
::GetDlgHit( const QPoint & vMousePos, BGraphWgtBase_c
* vpWgtExceptThisOne
) {
return GetDlgHitHoverOver( vMousePos, vpWgtExceptThisOne );
}
bool BGraphCanvas_c
::IsThisWidgetHit( const QPoint & vPosMouse,
const RDstr
& vWidgetId
) {
bool bHaveHitSpecificWidget = false;
QCanvasItemList listHitItems = GetDlgsHitHoverOver( vPosMouse );
return bHaveHitSpecificWidget;
}
void BGraphCanvasView_c
::mousePressEvent( QMouseEvent * vpEvent
) {
// Clean out widgets marked for deletion. Very important this is called here
// and not say on mouseReleaseEvent(). QCanvas does behind the scenes work
// on all it canvas items after mouseReleaseEvent() and so deleting any before then
// is not a good and causes a crash.
m_pGraphAreaCanvas->DeleteMarkedWgts();
// Has user clicked on an canvas area dialog (QCanvasItem )
m_mouseButtonPressCursorPos = viewportToContents( vpEvent->pos() );
m_currentSelectedAreaDlgId = m_pGraphAreaCanvas->GetDlgHit( m_mouseButtonPressCursorPos, NULL );
m_pCurrentSelectedWgt = m_pGraphAreaCanvas->GetDlgObj( m_currentSelectedAreaDlgId );
if( NULL == m_pCurrentSelectedWgt )
{
// Reset all widget depths accept the current selected widget
m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( NULL );
return;
}
// Create store for event into to be passed onto all hit widgets (canvas items)
BGraphWgtEventInfo_s sEventInfo;
// Pass event onto selected widget (canvas item)
if( m_pCurrentSelectedWgt->MousePressEvent( sEventInfo ) )
{
// Inform the client using BPkgGraph that possible item valid for selection is selected
m_pAGraph->SetCurrentlySelectedWidgetId( m_pCurrentSelectedWgt->GetId() );
}
// Pass event onto rest of hit widgets. These are not the most forward Z pos
// widgets.
m_pGraphAreaCanvas->MousePressEvent( sEventInfo );
// Reset all widget depths accept the current selected widget
m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( m_pCurrentSelectedWgt );
}
void BGraphCanvasView_c
::mouseReleaseEvent( QMouseEvent * vpEvent
) {
// Create store for event into to be passed onto all hit widgets (canvas items)
if( NULL != m_pCurrentSelectedWgt )
{
// Pass event onto selected widget (canvas item)
m_pCurrentSelectedWgt->MouseReleaseEvent( sEventInfo );
}
// Pass event onto rest of hit widgets. These are not the most forward Z pos
// widgets.
m_pGraphAreaCanvas->MouseReleaseEvent( sEventInfo );
// Reset all widget depths accept the last selected widget
m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( m_pCurrentSelectedWgt );
}
void BGraphCanvasView_c
::contentsMouseMoveEvent( QMouseEvent * vpEvent
) {
// Create store for event into to be passed onto all hit widgets (canvas items)
// User clicked on an canvas area dialog (QCanvasItem )
if( m_bMouseLeftButtonHitAreaDlg && m_bMouseLeftButtonDown )
{
// to use this m_currentSelectedAreaDlgId
if( NULL != m_pCurrentSelectedWgt )
{
// Pass event onto selected widget (canvas item)
m_pCurrentSelectedWgt->MouseContentMoveEvent( sEventInfo );
}
}
// Pass event onto rest of hit widgets. These are not the most forward Z pos
// widgets.
m_pGraphAreaCanvas->MouseContentMoveEvent( sEventInfo );
// User just moving the mouse over the canvas. Highlight most forward hit widget if any.
// Unhighlight previous widget if it still exists
// Turn off all/any highlighted hit widget areas
QPoint mousePos
( vpEvent
->pos
() );
const RDstr wgtId = m_pGraphAreaCanvas->GetDlgHitHoverOver( mousePos, pWgtExceptThisOne );
// Crash in collisions in GetDlgHitHoverOver()
// snip
}
}
// Update the view
m_pGraphAreaCanvas->update();
}
Bookmarks