From 339cf51c0c454fa8b5a65f9ad3f2f5ae07aea4ac Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 20 Aug 2013 15:07:38 +0200 Subject: [PATCH] Added VIEW_GROUP for grouping items to be displayed on a single layer. --- common/CMakeLists.txt | 1 + common/drawpanel_gal.cpp | 5 +- common/view/view.cpp | 223 +++++++++++++++++++++++-------------- common/view/view_group.cpp | 145 ++++++++++++++++++++++++ include/view/view.h | 93 +++++++++++----- include/view/view_group.h | 158 ++++++++++++++++++++++++++ 6 files changed, 513 insertions(+), 112 deletions(-) create mode 100644 common/view/view_group.cpp create mode 100644 include/view/view_group.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 68cceb56df..67b27f893d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -152,6 +152,7 @@ set(COMMON_SRCS ${COMMON_SRCS} view/view.cpp view/view_item.cpp + view/view_group.cpp system/fcontext.s diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index d99f2b0920..a6f11ff8b0 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -88,7 +88,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); /* Generic events for the Tool Dispatcher */ - Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); @@ -127,8 +126,8 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent ) { m_gal->ResizeScreen( aEvent.GetSize().x, aEvent.GetSize().y ); - m_view->SetTargetDirty( KiGfx::TARGET_CACHED ); - m_view->SetTargetDirty( KiGfx::TARGET_NONCACHED ); + m_view->MarkTargetDirty( KiGfx::TARGET_CACHED ); + m_view->MarkTargetDirty( KiGfx::TARGET_NONCACHED ); } diff --git a/common/view/view.cpp b/common/view/view.cpp index 3caed45b8b..83bd16dfac 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -48,7 +49,7 @@ VIEW::VIEW( bool aIsDynamic ) : { // Redraw everything at the beginning for( int i = 0; i < TARGETS_NUMBER; ++i ) - SetTargetDirty( i ); + MarkTargetDirty( i ); } @@ -111,53 +112,6 @@ void VIEW::Remove( VIEW_ITEM* aItem ) } -void VIEW::Draw( VIEW_ITEM* aItem, int aLayer ) const -{ - if( isCached( aLayer ) ) - { - // Draw using cached information or create one - int group = aItem->getGroup( aLayer ); - - if( group >= 0 ) - { - m_gal->DrawGroup( group ); - } - else - { - group = m_gal->BeginGroup(); - aItem->setGroup( aLayer, group ); - if( !m_painter->Draw( aItem, aLayer ) ) - aItem->ViewDraw( aLayer, m_gal, BOX2I() ); // Alternative drawing method - m_gal->EndGroup(); - } - } - else - { - // Immediate mode - if( !m_painter->Draw( aItem, aLayer ) ) - aItem->ViewDraw( aLayer, m_gal, BOX2I() ); // Alternative drawing method - } - - // Draws a bright contour around the item - if( static_cast( aItem )->IsBrightened() ) - { - m_painter->DrawBrightened( aItem ); - } -} - - -void VIEW::Draw( VIEW_ITEM* aItem ) const -{ - int layers[VIEW_MAX_LAYERS], layers_count; - aItem->ViewGetLayers( layers, layers_count ); - - for( int i = 0; i < layers_count; ++i ) - { - Draw( aItem, layers[i] ); - } -} - - void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired ) { wxASSERT( (unsigned) aLayerId < m_layers.size() ); @@ -271,9 +225,9 @@ void VIEW::SetGAL( GAL* aGal ) clearGroupCache(); // every target has to be refreshed - SetTargetDirty( TARGET_CACHED ); - SetTargetDirty( TARGET_NONCACHED ); - SetTargetDirty( TARGET_OVERLAY ); + MarkTargetDirty( TARGET_CACHED ); + MarkTargetDirty( TARGET_NONCACHED ); + MarkTargetDirty( TARGET_OVERLAY ); // force the new GAL to display the current viewport. SetCenter( m_center ); @@ -336,8 +290,8 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor ) m_scale = aScale; // Redraw everything after the viewport has changed - SetTargetDirty( TARGET_CACHED ); - SetTargetDirty( TARGET_NONCACHED ); + MarkTargetDirty( TARGET_CACHED ); + MarkTargetDirty( TARGET_NONCACHED ); } @@ -348,23 +302,8 @@ void VIEW::SetCenter( const VECTOR2D& aCenter ) m_gal->ComputeWorldScreenMatrix(); // Redraw everything after the viewport has changed - SetTargetDirty( TARGET_CACHED ); - SetTargetDirty( TARGET_NONCACHED ); -} - - -void VIEW::sortLayers() -{ - int n = 0; - - m_orderedLayers.resize( m_layers.size() ); - - for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i ) - m_orderedLayers[n++] = &i->second; - - sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder ); - - SetTargetDirty( TARGET_CACHED ); + MarkTargetDirty( TARGET_CACHED ); + MarkTargetDirty( TARGET_NONCACHED ); } @@ -376,6 +315,40 @@ void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder ) } +int VIEW::GetLayerOrder( int aLayer ) const +{ + return m_layers.at(aLayer).renderingOrder; +} + + +void VIEW::SortLayers( int aLayers[], int& aCount ) const +{ + int maxLay, maxOrd, maxIdx; + + for( int i = 0; i < aCount; ++i ) + { + maxLay = aLayers[i]; + maxOrd = GetLayerOrder( maxLay ); + maxIdx = i; + + // Look for the max element in the range (j..aCount) + for( int j = i; j < aCount; ++j ) + { + if( maxOrd < GetLayerOrder( aLayers[j] ) ) + { + maxLay = aLayers[j]; + maxOrd = GetLayerOrder( maxLay ); + maxIdx = j; + } + } + + // Swap elements + aLayers[maxIdx] = aLayers[i]; + aLayers[i] = maxLay; + } +} + + struct VIEW::updateItemsColor { updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) : @@ -559,7 +532,7 @@ struct VIEW::drawItem if( !drawCondition ) return; - view->Draw( aItem, currentLayer->id ); + view->draw( aItem, currentLayer->id ); } const VIEW_LAYER* currentLayer; @@ -585,13 +558,73 @@ void VIEW::redrawRect( const BOX2I& aRect ) } +void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const +{ + if( isCached( aLayer ) && !aImmediate ) + { + // Draw using cached information or create one + int group = aItem->getGroup( aLayer ); + + if( group >= 0 ) + { + m_gal->DrawGroup( group ); + } + else + { + group = m_gal->BeginGroup(); + aItem->setGroup( aLayer, group ); + if( !m_painter->Draw( aItem, aLayer ) ) + aItem->ViewDraw( aLayer, m_gal, BOX2I() ); // Alternative drawing method + m_gal->EndGroup(); + } + } + else + { + // Immediate mode + if( !m_painter->Draw( aItem, aLayer ) ) + aItem->ViewDraw( aLayer, m_gal, BOX2I() ); // Alternative drawing method + } + + // Draws a bright contour around the item + if( static_cast( aItem )->IsBrightened() ) + { + m_painter->DrawBrightened( aItem ); + } +} + + +void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const +{ + int layers[VIEW_MAX_LAYERS], layers_count; + aItem->ViewGetLayers( layers, layers_count ); + SortLayers( layers, layers_count ); + + for( int i = 0; i < layers_count; ++i ) + { + m_gal->SetLayerDepth( m_layers.at( i ).renderingOrder ); + draw( aItem, layers[i], aImmediate ); + } +} + + +void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate ) const +{ + std::set::const_iterator it; + for( it = aGroup->Begin(); it != aGroup->End(); ++it ) + { + draw( *it, aImmediate ); + } +} + + bool VIEW::IsDirty() const { - BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers ) + for( int i = 0; i < TARGETS_NUMBER; ++i ) { - if( l->isDirty ) + if( isTargetDirty( i ) ) return true; - } + } + return false; } @@ -675,18 +708,22 @@ void VIEW::Redraw() m_gal->ClearTarget( TARGET_NONCACHED ); m_gal->ClearTarget( TARGET_CACHED ); - SetTargetDirty( TARGET_NONCACHED ); - SetTargetDirty( TARGET_CACHED ); + MarkTargetDirty( TARGET_NONCACHED ); + MarkTargetDirty( TARGET_CACHED ); m_gal->DrawGrid(); } + + // Always refresh the overlay + MarkTargetDirty( TARGET_OVERLAY ); m_gal->ClearTarget( TARGET_OVERLAY ); redrawRect( rect ); // All targets were redrawn, so nothing is dirty - SetTargetDirty( TARGET_CACHED, false ); - SetTargetDirty( TARGET_NONCACHED, false ); + clearTargetDirty( TARGET_CACHED ); + clearTargetDirty( TARGET_NONCACHED ); + clearTargetDirty( TARGET_OVERLAY ); } @@ -752,10 +789,26 @@ void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) // Mark those layers as dirty, so the VIEW will be refreshed m_layers[layers[i]].isDirty = true; + MarkTargetDirty( m_layers[layers[i]].target ); // TODO remove? } } +void VIEW::sortLayers() +{ + int n = 0; + + m_orderedLayers.resize( m_layers.size() ); + + for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i ) + m_orderedLayers[n++] = &i->second; + + sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder ); + + MarkTargetDirty( TARGET_CACHED ); +} + + void VIEW::updateItemAppearance( VIEW_ITEM* aItem, int aLayer ) { wxASSERT( (unsigned) aLayer < m_layers.size() ); @@ -811,15 +864,13 @@ void VIEW::RecacheAllItems( bool aImmediately ) r.SetMaximum(); #ifdef __WXDEBUG__ - wxLogDebug( wxT( "RecacheAllItems::immediately: %u" ), aImmediately ); - prof_counter totalRealTime; prof_start( &totalRealTime, false ); #endif /* __WXDEBUG__ */ for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i ) { - VIEW_LAYER* l = & ( ( *i ).second ); + VIEW_LAYER* l = &( ( *i ).second ); // Obviously, there is only one cached target that has to be recomputed if( isCached( l->id ) ) @@ -834,7 +885,8 @@ void VIEW::RecacheAllItems( bool aImmediately ) #ifdef __WXDEBUG__ prof_end( &totalRealTime ); - wxLogDebug( wxT( "RecacheAllItems::%.1f ms" ), (double) totalRealTime.value / 1000.0 ); + wxLogDebug( wxT( "RecacheAllItems::immediately: %u %.1f ms" ), + aImmediately, (double) totalRealTime.value / 1000.0 ); #endif /* __WXDEBUG__ */ } @@ -843,6 +895,10 @@ bool VIEW::isTargetDirty( int aTarget ) const { wxASSERT( aTarget < TARGETS_NUMBER ); + // Check the target status + if( m_dirtyTargets[aTarget] ) + return true; + // Check if any of layers belonging to the target is dirty BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers ) { @@ -850,6 +906,5 @@ bool VIEW::isTargetDirty( int aTarget ) const return true; } - // If no layer is dirty, just check the target status itself - return m_dirtyTargets[aTarget]; + return false; } diff --git a/common/view/view_group.cpp b/common/view/view_group.cpp new file mode 100644 index 0000000000..f7ff19da96 --- /dev/null +++ b/common/view/view_group.cpp @@ -0,0 +1,145 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/** + * @file view_group.cpp + * @brief VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object. + * VIEW_GROUP does not take over ownership of the held items. The main purpose of this class is + * to group items and draw them on a single layer (in particular the overlay). + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace KiGfx; + +VIEW_GROUP::VIEW_GROUP( VIEW* aView ) : + m_layer( ITEM_GAL_LAYER( GP_OVERLAY ) ) +{ + m_view = aView; +} + + +VIEW_GROUP::~VIEW_GROUP() +{ +} + + +void VIEW_GROUP::Add( VIEW_ITEM* aItem ) +{ + m_items.insert( aItem ); + updateBbox(); +} + + +void VIEW_GROUP::Remove( VIEW_ITEM* aItem ) +{ + m_items.erase( aItem ); + updateBbox(); +} + + +void VIEW_GROUP::Clear() +{ + m_items.clear(); + updateBbox(); +} + + +unsigned int VIEW_GROUP::GetSize() const +{ + return m_items.size(); +} + + +const BOX2I VIEW_GROUP::ViewBBox() const +{ + BOX2I box; + + // Merge all bounding boxes, so the returned one contains all stored items + BOOST_FOREACH( VIEW_ITEM* item, m_items ) + { + box.Merge( item->ViewBBox() ); + } + + return box; +} + + +void VIEW_GROUP::ViewDraw( int aLayer, GAL* aGal, const BOX2I& aVisibleArea ) const +{ + PAINTER* painter = m_view->GetPainter(); + + // Draw all items immediately (without caching) + BOOST_FOREACH( VIEW_ITEM* item, m_items ) + { + int layers[VIEW::VIEW_MAX_LAYERS], layers_count; + item->ViewGetLayers( layers, layers_count ); + m_view->SortLayers( layers, layers_count ); + + for( int i = 0; i < layers_count; i++ ) + { + aGal->SetLayerDepth( m_view->GetLayerOrder( layers[i] ) ); + + if( !painter->Draw( item, layers[i] ) ) + item->ViewDraw( layers[i], aGal, aVisibleArea ); // Alternative drawing method + } + + /// m_view->Draw( item, true ); + } +} + + +void VIEW_GROUP::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aLayers[0] = m_layer; + aCount = 1; +} + + +void VIEW_GROUP::ViewUpdate( int aUpdateFlags, bool aForceImmediateRedraw ) +{ + BOOST_FOREACH( VIEW_ITEM* item, m_items ) + { + item->ViewUpdate( aUpdateFlags, aForceImmediateRedraw ); + } +} + + +void VIEW_GROUP::updateBbox() +{ + // Save the used VIEW, as it used nulled during Remove() + VIEW* view = m_view; + + // Reinsert the group, so the bounding box can be updated + view->Remove( this ); + view->Add( this ); +} diff --git a/include/view/view.h b/include/view/view.h index f0caf95d02..89155099df 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -37,6 +37,7 @@ namespace KiGfx class PAINTER; class GAL; class VIEW_ITEM; +class VIEW_GROUP; class VIEW_RTREE; /** @@ -95,19 +96,6 @@ public: */ int Query( const BOX2I& aRect, std::vector& aResult ); - /** - * Function Draw() - * Draws an item, but on a specified layers. It has to be marked that some of drawing settings - * are based on the layer on which an item is drawn. - */ - void Draw( VIEW_ITEM* aItem, int aLayer ) const; - - /** - * Function Draw() - * Draws an item on all layers that the item uses. - */ - void Draw( VIEW_ITEM* aItem ) const; - /** * Function SetRequired() * Marks the aRequiredId layer as required for the aLayerId layer. In order to display the @@ -296,13 +284,30 @@ public: /** * Function SetLayerOrder() - * Sets rendering order of a particular layer. + * Sets rendering order of a particular layer. Lower values are rendered first. * @param aLayer: the layer * @param aRenderingOrder: arbitrary number denoting the rendering order. - * Lower values are rendered first. */ void SetLayerOrder( int aLayer, int aRenderingOrder ); + /** + * Function GetLayerOrder() + * Returns rendering order of a particular layer. Lower values are rendered first. + * @param aLayer: the layer + * @return Rendering order of a particular layer. + */ + int GetLayerOrder( int aLayer ) const; + + /** + * Function SortLayers() + * Changes the order of given layer ids, so after sorting the order corresponds to layers + * rendering order (descending, ie. order in which layers should be drawn - from the bottom to + * the top). + * @param aLayers stores id of layers to be sorted. + * @param aCount stores the number of layers. + */ + void SortLayers( int aLayers[], int& aCount ) const; + /** * Function UpdateLayerColor() * Applies the new coloring scheme held by RENDER_SETTINGS in case that it has changed. @@ -390,22 +395,20 @@ public: * Returns true if any of the VIEW layers needs to be refreshened. * @return True in case if any of layers is marked as dirty. */ - bool IsDirty() const; + bool IsDirty() const; /** - * Function SetTargetDirty() + * Function MarkTargetDirty() * Sets or clears target 'dirty' flag. * @param aTarget is the target to set. - * @param aState says if the flag should be set or cleared. */ - inline void SetTargetDirty( int aTarget, bool aState = true ) + inline void MarkTargetDirty( int aTarget ) { wxASSERT( aTarget < TARGETS_NUMBER ); - m_dirtyTargets[aTarget] = aState; + m_dirtyTargets[aTarget] = true; } - static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown private: @@ -438,12 +441,49 @@ private: struct updateItemsColor; struct changeItemsDepth; - ///* Whether to use rendering order modifier or not - bool m_enableOrderModifier; - ///* Redraws contents within rect aRect void redrawRect( const BOX2I& aRect ); + inline void clearTargetDirty( int aTarget ) + { + wxASSERT( aTarget < TARGETS_NUMBER ); + + m_dirtyTargets[aTarget] = false; + } + + /** + * Function draw() + * Draws an item, but on a specified layers. It has to be marked that some of drawing settings + * are based on the layer on which an item is drawn. + * + * @param aItem is the item to be drawn. + * @param aLayer is the layer which should be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ) const; + + /** + * Function draw() + * Draws an item on all layers that the item uses. + * + * @param aItem is the item to be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_ITEM* aItem, bool aImmediate = false ) const; + + /** + * Function draw() + * Draws a group of items on all layers that those items use. + * + * @param aItem is the group to be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const; + + ///* Manages dirty flags & redraw queueing when updating an item. Called internally /// via VIEW_ITEM::ViewUpdate() void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ); @@ -484,10 +524,13 @@ private: */ bool isTargetDirty( int aTarget ) const; + ///* Whether to use rendering order modifier or not + bool m_enableOrderModifier; + /// Contains set of possible displayed layers and its properties LayerMap m_layers; - /// Sorted list of pointers to members of m_layers. + /// Sorted list of pointers to members of m_layers LayerOrder m_orderedLayers; /// Stores set of layers that are displayed on the top diff --git a/include/view/view_group.h b/include/view/view_group.h new file mode 100644 index 0000000000..4439234e0d --- /dev/null +++ b/include/view/view_group.h @@ -0,0 +1,158 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/** + * @file view_group.h + * @brief VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object. + * VIEW_GROUP does not take over ownership of the held items. The main purpose of this class is + * to group items and draw them on a single layer (in particular the overlay). + */ + +#ifndef VIEW_GROUP_H_ +#define VIEW_GROUP_H_ + +#include +#include + +namespace KiGfx +{ + +class VIEW_GROUP : public VIEW_ITEM +{ +public: + VIEW_GROUP( VIEW* aView ); + virtual ~VIEW_GROUP(); + + /** + * Function Add() + * Adds an item to the group. + * + * @param aItem is the item to be added. + */ + virtual void Add( VIEW_ITEM* aItem ); + + /** + * Function Remove() + * Removes an item from the group. + * + * @param aItem is the item to be removed. + */ + virtual void Remove( VIEW_ITEM* aItem ); + + /** + * Function Clear() + * Removes all the stored items from the group. + */ + virtual void Clear(); + + /** + * Function Begin() + * Returns iterator to beginning. + */ + inline std::set::const_iterator Begin() const + { + return m_items.begin(); + } + + /** + * Function End() + * Returns iterator to end. + */ + inline std::set::const_iterator End() const + { + return m_items.end(); + } + + /** + * Function GetSize() + * Returns the number of stored items. + * + * @return Number of stored items. + */ + virtual unsigned int GetSize() const; + + /** + * Function ViewBBox() + * Returns the bounding box for all stored items covering all its layers. + * + * @return The current bounding box + */ + virtual const BOX2I ViewBBox() const; + + /** + * Function ViewDraw() + * Draws all the stored items in the group on the given layer. + * + * @param aLayer is the layer which should be drawn. + * @param aGal is the GAL that should be used for drawing. + * @param aVisibleArea is limiting the drawing area. + */ + virtual void ViewDraw( int aLayer, GAL* aGal, const BOX2I& aVisibleArea ) const; + + /** + * Function ViewGetLayers() + * Returns all the layers used by the stored items. + * + * @param aLayers[] is the output layer index array. + * @param aCount is the number of layer indices in aLayers[]. + */ + virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + + /// @copydoc VIEW_ITEM::ViewUpdate() + virtual void ViewUpdate( int aUpdateFlags, bool aForceImmediateRedraw ); + + /** + * Function SetLayer() + * Sets layer used to draw the group. + * + * @param aLayer is the layer used for drawing. + */ + inline virtual void SetLayer( int aLayer ) + { + m_layer = aLayer; + } + +protected: + /// These functions cannot be used with VIEW_GROUP as they are intended only to work with + /// singular VIEW_ITEMs (there is only one-to-one relation between item/layer combination and + /// its group). + int getGroup( int aLayer ) const { return -1; }; + std::vector getAllGroups() const { return std::vector(); }; + void setGroup( int aLayer, int aGroup ) {}; + void deleteGroups() {}; + bool storesGroups() const { return false; }; + + /// Layer on which the group is drawn + int m_layer; + +private: + void updateBbox(); + + /// Container for storing VIEW_ITEMs + std::set m_items; +}; +} // namespace KiGfx + +#endif // VIEW_GROUP_H_