/*!
    \class QskItem QskItem.h

    \ingroup Framework

    QskItem completes the C++ API of QQuickItem and re-establishs basic
    concepts like events. It also offers better control over the operations
    happening in the update cycle.
 */

/*!
    \enum QskItem::UpdateFlag

    Qt/Quick classes have a tendency to update items too early
    and too often. To avoid processing of unwanted operations
    QskItem implements a couple of modifications, that
    can be en/disabled individually.

    \sa updateFlags(), resetUpdateFlags()
        testUpdateFlag(), setUpdateFlag(), resetUpdateFlag()

    \var QskItem::UpdateFlag QskItem::DeferredUpdate

        Creating of scene graph nodes is blocked when being invisible.

        The default implementation of Qt/Quick creates scene graph nodes for all items
        in the scene what might become a significant factor for the startup performance
        ( and memory footprint ) of large user interfaces.

        Instead of trying to work around these problems by asynchrounous instantiation
        strategies ( QQmlIncubator ) the DeferredUpdate flag offers a much simpler
        and obvious solution: don't instantiate before really needed.

    \saqt QQuickItem::isVisible()

    \note Some more advanced algorithms have not yet been implemented,
          such as viewport frustrum culling (i.e. hiding items outside of the
          window geometry).

    \var QskItem::UpdateFlag QskItem::DeferredPolish

        Polishing an item is blocked when being invisible.
        F.e for all items being derived from QskControl the layout calculations
        happen during polishing.

    \saqt QQuickItem::updatePolish(), QQuickItem::polish()

    \var QskItem::UpdateFlag QskItem::DeferredLayout

        Recalculations of the implicitSize are blocked until being explicitly requested. 

        When being enabled the item indicates layout relevant changes by
        sending a QEvent::LayoutRequest ( similar to QWidget ) to its parent item
        without recalculating the actual size hints ( f.e the implicitSize ).

        When having layout code that relies on binding the implicit width/height
        the QskItem::DeferredLayout flag needs to be disabled.

    \note All layout classes offered by the Qt/Quick modules of the Qt Company
          ( f.e anchors ) do require immediate updates of the implicit size. 

    \sa QskItem::resetImplicitSize()
    \saqt QQuickItem::implicitSize()

    \var QskItem::UpdateFlag QskItem::CleanupOnVisibility

        Delete scene graph nodes, when the item becomes hidden.
        Enabling this mode will reduce the memory footprint, but comes at the cost
        of having to recreate nodes once the item gets shown again.

    \saqt QQuickItem::isVisible()

    \var QskItem::UpdateFlag QskItem::PreferRasterForTextures

        When creating textures from QskGraphic, prefer the raster paint
        engine over the OpenGL paint engine.

    \var QskItem::UpdateFlag QskItem::DebugForceBackground

        Always fill the background of the item with a random color.

    \note This flag is useful when analyzing layouts.

*/

/*!
    \property QskItem::geometry

    This property holds the geometry of the item relative to its parent item.
    When changing the geometry, the item receives a QskEvent::GeometryChange event.

    \sa geometryChangeEvent(), geometryChange(), rect
*/

/*!
    \property QskItem::rect

    This property returns the internal geometry of the item.
    It equals QRect(0, 0, width(), height() ).

    \sa geometryChangeEvent(), geometryChange(), geometry
*/

/*!
    \var QskItem::transparentForPositioners

    When transparentForPositioners is set the item indicates, that it should be excluded
    from any layout calculations. This flag is actually a concept of QQuickItem, that
    has not been exposed to its public API.

    \sa isTransparentForPositioner()
*/

/*!
    \property QskItem::tabFence

    The tabFence flag can be used to create local tab focus chains. It is usually
    used in combination with QQuickItem::ItemIsFocusScope.

    QskPopup is an example where the focus tab chain is expected to continue
    with the first child instead of leaving the popup, when reaching its end.

    \sa isTabFence(), QQuickItem::ItemIsFocusScope
    \saqt QQuickItem::ItemIsFocusScope
*/

/*!
    \property QskItem::visibleToParent

    Flag indicating if an item would become visible if its parentItem() is shown.
    The implementation relies on the internal explicitVisible flag, that has not
    been exposed by the public API of QQuickItem.

    In many situations it is important to know if an item has been explicitly hidden
    because of a setVisible( false ) or it is a child of an item, that is in
    an invisible state. F,e for calculating the size hint for a hidden container
    it is necessary to know which children would stay hidden when the container
    becomes visible.

    \sa setHidden(), show(), hide(), isVisibleToParent(), qskIsVisibleToParent()
    \saqt QQuickItem::setVisible()
*/

/*!
    \property QskItem::polishOnResize

    When polishOnResize is set QQuickItem::polish() will be called automatically
    whenever the size of the item has been changed. This is usually necessary
    when the item is a container and the layout of its children depends on the
    size of the container.

    \sa QskControl::updateLayout(), QskControl::autoLayoutChildren
*/

/*!
    \property QskItem::initiallyPainted

    Status flag indicating that there has already been a call
    of QQuickItem::updatePaintNode() since the item has become visible.

    Before each initial call of updatePaintNode() the specific
    hook aboutToShow() is called, that is intended to be overloaded.

    \sa isInitiallyPainted(), aboutToShow()
*/

/*!
    \property QskItem::hasChildItems

    A property indicating if the item has child items.

    \saqt QQuickItem::childItems(), QQuickItem::parentItem()
*/

/*!
    \property QskItem::updateFlags

    QskItem offers several tweaks to the Qt/Quick update cycle,
    that can be en/disabled individually.

    The flags are a combination from bits that have been explicitly set
    by setUpdateFlag() and those being derived from the aapplication
    wide default settings, that can be set with QskSetup.
    
    \sa QskItem::UpdateFlag, QskItem::updateFlags(), QskSetup::itemUpdateFlags()
*/

/*!
    \fn QskItem::QskItem

    Sets the QQuickItem::ItemHasContents flag to true.
*/

*!
    \fn QskItem::~QskItem

    Sets the componentComplete to false, so that its about-to-delete state is known
    when detaching it from parent/window.
*/

/*!
    \fn QskItem::className

    A convenience wrapper for metaObject()->className()
    \return Class name
*/

/*!
    \fn QskItem::isVisibleTo

    The true case occurs if neither the item itself nor any parent up to but excluding
    ancestor has been explicitly hidden.

    \param ancestor Ancestor is the parentItem() hierarchy
    \return true if this item would become visible if ancestor is shown; otherwise returns false.

    \sa visibleToParent
*/

/*!
    \fn QskItem::isVisibleToParent

    An item might be invisible because it has been explicitly hidden or
    one of its ancestors has been hidden. isVisibleToParent() indicates
    the first situation.
    
    \return true once setVisible( false ) has been called

    \sa visibleToParent(), qskIsVisibleToParent()
    \saqt QQuickItem::setVisible()
*/

/*!
    \fn QskItem::hasChildItems() const

    \return true, if the item has child items
    \sa hasChildItems
*/

/*!
    \fn QskItem::setGeometry( qreal, qreal, qreal, qreal )

    Set the position and the size of an item

    \param x X ( = left ) coordinate relative to the parent item 
    \param y Y ( = top ) coordinate relative to the parent item 
    \param width Width
    \param height Height

    \sa geometry(), geometryChange()
    \saqt QQuickItem::size(), QQuickItem::position()
*/

/*!
    \fn QskItem::setGeometry( const QPointF &, const QSizeF & )

    Set the position and the size of an item

    \param pos Position relative to the parent item
    \param size Size of the item
*/

/*!
    \fn QskItem::setGeometry( const QRectF& )

    Set the position and the size of an item

    \param rect Geometry relative to the parent item

    \sa geometry(), geometryChange()
    \saqt QQuickItem::size(), QQuickItem::position()
*/

/*!
    \fn QskItem::geometry() const

    \return Position and size relative to the parent item
    \sa geometry, setGeometry()
*/

/*!
    \fn QskItem::geometryChange

    This overloaded notifier calls QQuickItem::polish() depending on the
    polishOnResize() flag and forwards the notification to the event queue.

    \sa geometryChangeEvent(), polishOnResize()
*/

/*!
    \fn QskItem::rect() const

    \return Internal geometry of the item, where the position is always at ( 0, 0 )
    \sa geometry
*/

/*!
    \fn QskItem::implicitSize

    Qt/Quick offers an oversimplified layout system that is based on the
    property bindings of implicit width and height. QSkinny restablishs a layout
    system that can compete with what is available in the Qt/Widgets or Qt/Graphics
    technologies.

    In the QSkinny layout system the implicitSize is a synonym for what is also known
    as sizeHint or preferredSize.

    \return Implicit size, 

    \note Layout code that relies on property bindings of the implicit width a height
          needs to disable the QskItem::DeferredLayout flag

    \sa QskControl::preferredSize(), QskControl::sizeHint()
    \saqt QQuickItem::implicitWidth(), QQuickItem::implicitHeight()
*/

/*!
    \fn QskItem::setPolishOnResize

    Set or clear the polishOnResize flag.
    \sa polishOnResize
*/

/*!
    \fn QskItem::polishOnResize() const

    \return Value of the polishOnResize flag
    \sa setPolishOnResize()
*/

/*!
    \fn QskItem::setTransparentForPositioner

    Set or clear the transparentForPositioner flag
    \sa isTransparentForPositioner()
*/

/*!
    \fn QskItem::isTransparentForPositioner

    \return Value of the transparentForPositioner flag
    \sa transparentForPositioner
*/

/*!
    \fn QskItem::setTabFence

    Set or clear the tabFence property
    \sa isTabFence()
*/

/*!
    \fn QskItem::isTabFence

    \return Value of the tabFence property
    \sa setTransparentForPositioner()
*/

/*!
    \fn QskItem::setLayoutMirroring

    Change the direction how the content is laid out horizontally.

    \param on True enables layoutMirroring
    \param childrenInherit If true the mirroring behavior is propagated
                           to all child items as well. 

    Changes of this property will be indicated by a QEvent::LayoutDirectionChange.

    \sa layoutMirroring, resetLayoutMirroring(), changeEvent()
    \note In Qml the parameters are routed through the attached LayoutMirroring property
          to have something declarative
*/

/*!
    \fn QskItem::resetLayoutMirroring

    Clear the layoutMirroring property

    \sa setLayoutMirroring(), layoutMirroring
*/

/*!
    \fn QskItem::layoutMirroring() const

    Direction how the content is layed out horizontally.

    If no value has been explicitly assigned it is inherited
    from the closest ancestor, where the attribute has been
    assigned with the childrenInherit parameter. If such an ancestor
    does not exists layoutMirroring is false.

    \return Inherited or explicitly assigned value

    \sa setLayoutMirroring(), layoutMirroring()
    \todo Several controls do not respect this flag

    \sa setLayoutMirroring(), resetLayoutMirroring()
    \note Several controls do not respect this flag
    \note In Qml the parameters are routed through the attached LayoutMirroring property
          to have something declarative
*/

/*!
    \fn QskItem::resetUpdateFlags

    Reset all flags to the default settings 

    \sa QskSetup::itemUpdateFlags(), updateFlags(), updateFlags
*/

/*!
    \fn QskItem::updateFlags() const

    \return Flags affecting the item update process
    \sa testUpdateFlag(), setUpdateFlag(), updateFlags
*/

/*!
    \fn QskItem::setUpdateFlag

    QskItem offers several tweaks to the Qt/Quick update cycle,
    that can be en/disables individually.

    The default settings for these flags are taken from QskSetup::itemUpdateFlags()
    When calling setUpdateFlag() the value for the particular flag is decoupled
    from the corresponding default bit - even if both bits have the same value.
    This can be reverted by calling resetUpdateFlag()

    \param flag Flag affecting the item update process
    \param on En/Disable the behaviour related to the flag

    \sa QskSetup::itemUpdateFlags(), testUpdateFlag(). updateFlags
*/

/*!
    \fn QskItem::resetUpdateFlag

    Reset the value for flag to the default settings from QskSetup. Future
    changes of the corresponding bit with QskSetup::setItemUpdateFlag() will affect
    the behaviour of this item.

    \param flag Flag affecting the item update process
    \sa QskSetup::itemUpdateFlags(), updateFlags(), testUpdateFlag(), updateFlags
*/

/*!
    \fn QskItem::testUpdateFlag

    \param Flag affecting the item update process
    \return true, when the corresponding bit is effective

    \sa setUpdateFlag(), QskSetup::itemUpdateFlag(), updateFlags
*/

/*!
    \fn QskItem::updateFlagsChanged

    Signal indicating, that the effective update flags have changed

    \param flags Effective flags, might be derived in parts from QskSetup::itemUpdateFlags()
    \sa updateFlags
*/

/*!
    \fn QskItem::classBegin

    The QML engine initializes an item as being incomplete by
    explicitly calling classBegin(). Once the item
    has been constructed componentComplete() is called. This way
    temporary operations during the construction can be avoided.
    
    In the C++ case the item indicates being complete from
    the beginning and both hooks are never called.

    The overloaded version calls the base class and has no
    purpose beside being an entry point for debugging.
    
    \sa componentComplete()
    \saqt QQuickItem::classBegin, QQuickItem::isComponentComplete()
*/

/*!
    \fn QskItem::componentComplete

    The QML engine initilizes an item as being incomplete by
    explicitly calling QQuickItem::classBegin(). Once the item
    has been constructed componentComplete() is called. This way
    temporary operations during the construction can be avoided.

    In the C++ case the item indicates being complete from
    the beginning and both hooks are never called.

    The overloaded does some sanity checks in debug mode
    and calls the base class.

    \sa classBegin()
    \saqt QQuickItem::isComponentComplete(), QQuickItem::componentComplete
*/

/*!
    \fn QskItem::releaseResources

    This specific hook is called, when the item is about to be removed
    from the window it was previously rendering to. 

    The implementation stores the values needed for the following QskWindowChangeEvent.

    \sa windowChangeEvent()
*/

/*!
    \fn QskItem::isPolishScheduled

    \return True, if the item will be polished in the next
            scene graph update cycle.
    \sa isUpdateNodeScheduled()
    \saqt QQuickItem::polish()
*/

/*!
    \fn QskItem::isUpdateNodeScheduled

    \return True, if the item will update the paint node in
            the next scene graph update cycle
*/

/*!
    \fn QskItem::isInitiallyPainted

    \return Value of the initiallyPainted property
    \sa initiallyPainted
*/

/*!
    \fn QskItem::maybeUnresized

    Flag indicating a potential state, where the item is waiting to be
    sized by the layout system.

    Unfortunately the list of items to-be-polished is not processed
    in top/down order and a container might be requested to calculate
    the geometries for its children before having a proper size itself.

    Some of these situations can be avoided by ignoring these requests
    depending on the maybeUnresized flag. 
*/

/*!
    \fn QskItem::itemFlagsChanged

    Signal indicating that at least one if the following attributes has changed:

    - transparentForPositioners
    - tabFence
    - polishOnResize
*/

/*!
    \fn QskItem::show

    An alternative way to call setVisible( true ).
    Useful for signal/slot connections

    \sa hide(), setHidden()
    \saqt QQuickItem::setVisible()
*/

/*!
    \fn QskItem::hide

    An alternative way to call setVisible( false ).
    Useful for signal/slot connections

    \sa show()
    \saqt QQuickItem::setVisible()
*/

/*!
    \fn QskItem::setHidden

     Convenience function, equivalent to setVisible( !on ).

     \sa show(), hide()
     \saqt QQuickItem::setVisible()
*/

/*!
    \fn QskItem::setDisabled

    Convenience function, equivalent to setEnabled( !on ).
        \saqt QQuickItem::setEnabled()
*/

/*!
    \fn QskItem::resetImplicitSize

    Notifies the layout system that attributes affecting the layout
    system have changed.

    If the QskItem::DeferredLayout flag is enabled ( = default )
    the cached implicitSize() gets invalidated and a QEvent::LayoutRequest is sent
    to the parent item ( like QWidget::updateGeometry ).

    Otherwise the implicitSize() gets recalculated and layout updates can
    be executed using property bindings.
*/

/*!
    \fn QskItem::event

    QskItem handles the additional type of events.

    For some reason the QQuick classes introduced proprietory notfier hooks
    instead of using the well established and powerful concept of events.
    QskItem tries to revert this decision by mapping notifications
    to events, when possible.

    The following notification events are added by QSkinny - usually with a
    very similar to how they are used known for Qt/Widgets:

    - QEvent::ContentsRectChange
    - QEvent::LocaleChange
    - QEvent::ParentChange
    - QEvent::EnabledChange
    - QEvent::ReadOnlyChange
    - QEvent::LayoutDirectionChange
    - QEvent::LayoutRequest

    Furthermore events derived from QskEvent are used.

    \param event Qt event
*/

/*!
    \fn QskItem::changeEvent

    This event handler can be reimplemented to handle certain state changes:

        - QEvent::StyleChange
        - QEvent::ContentsRectChange
        - QEvent::ReadOnlyChange
        - QEvent::EnabledChange
        - QEvent::LocaleChange
        - QEvent::ParentChange
        - QEvent::LayoutDirectionChange

    \param event Qt event
*/

/*!
    \fn QskItem::geometryChangeEvent

    For no known reason QQuickItem propagates changes of position and size
    by calling QQuickItem::geometryChange(), instead of using events.

    QskItem reestablished the more powerful concept of events by sending/posting
    events, that can be preprocessed by event filtering.

    \param event Event indicating the geometry change

    \sa geometryChange()
    \saqt QObject::installEventFilter()
*/

/*!
    \fn QskItem::windowChangeEvent

    This event handler can be reimplemented to handle situations, where
    an item is added, removed or transferred between windows. It corresponds
    to the QQuickItem::ItemSceneChange notification, but is more convenient:

    - being an event it can be processed by event filtering
    - the previous window is available 

    \param event Event with the old/new windows
*/

/*!
    \fn QskItem::itemChange

    For no obvious reason Qt/Quick has introduced an additional callback
    mechanism beside events and signals.

    \param change Indicator, to identify what has changed
    \param changeData Extra information relating to the change

    \note It is recommended to avoid using this type of notifications where possible.
          Netter rely on overloading the corresponding  event handlers, what allows
          application code to make use of convenient and well established concepts
          like event filtering ( QObject::installEventFilter() ).

    \note If you re-implement this method in a subclass, be sure to call
          the overloaded method of the base class.

    \sa event()
    \saqt QQuickItem::itemChange()
*/

/*!
    \fn QskItem::aboutToShow

    A specific hook that is intended to be overloaded by controls that need
    to do some specific operations, when an item is painted the first time
    after becoming visible.

    The default implementation is a no operation.

    \sa initiallyPainted
    \saqt QQuickItem::setVisible()
*/

/*!
    \fn QskItem::mouseUngrabEvent

    Notification, that is overloaded for debuging purposes, without
    doing anything beside calling the base class.

    \saqt QQuickItem::mouseUngrabEvent
*/

/*!
    \fn QskItem::touchUngrabEvent

    Notification, that is overloaded for debuging purposes, without
    doing anything beside calling the base class.

    \saqt QQuickItem::touchUngrabEvent
*/
