// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/Sizer.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_Sizer_h #define __PCL_Sizer_h /// \file pcl/Sizer.h #ifndef __PCL_BUILDING_PIXINSIGHT_APPLICATION #include #include #endif // __PCL_BUILDING_PIXINSIGHT_APPLICATION namespace pcl { // ---------------------------------------------------------------------------- /*! * \namespace pcl::Align * \brief Control alignment modes. * * * * * * * * * *
Align::Expand The item can be expanded to occupy the available space
Align::Left The item aligns to the left side of the available space
Align::Top The item aligns to the top side of the available space
Align::Right The item aligns to the right side of the available space
Align::Bottom The item aligns to the bottom side of the available space
Align::Center The item aligns centered within the available space
Align::Default Default alignment, equal to Align::Expand
*/ namespace Align { enum value_type { Expand, Left, Top = Left, Right, Bottom = Right, Center, Default = Expand }; } // ---------------------------------------------------------------------------- #ifndef __PCL_BUILDING_PIXINSIGHT_APPLICATION class PCL_CLASS Control; // ---------------------------------------------------------------------------- /*! * \class Sizer * \brief Base class for PixInsight sizer objects. * * %Sizer allows laying out child controls within their parent controls as * simple one-dimensional stacks with precise control over orientations, * margins, distances between items, and item alignments. By distributing * controls in nested %Sizer objects with horizontal and vertical orientations, * complex albeit clean user interfaces can be easily defined. * * \b Automatic \b Scaling * * The %Sizer class provides an automatic scaling feature that simplifies the * adaptation of existing and new PCL-based UI generation code to varying * display resolutions. This functionality can be controlled with a Boolean * \a autoScaling parameter available for the following member functions: * * Sizer::SetMargin( int margin, bool autoScaling = true );\n * Sizer::SetSpacing( int spacing, bool autoScaling = true );\n * Sizer::AddSpacing( int spacing, bool autoScaling = true );\n * Sizer::InsertSpacing( int index, int spacing, bool autoScaling = true );\n * int Margin( bool autoScaling = true );\n * int Spacing( bool autoScaling = true ); * * As you can see, automatic scaling is always enabled by default. On the * PixInsight platform, the reference display density is 109 dpi, corresponding * to a 27 inch monitor at QHD resolution (2560x1440 physical pixels). * * The automatic scaling feature applies the scaling ratio returned by * Sizer::DisplayPixelRatio() to convert horizontal and vertical spaces between * items from device-independent (or \e logical) pixel units to physical device * pixel units. When this feature is enabled through the corresponding * \a autoScaling parameters, scaling is applied to both automatic and manual * spacings between controls, that is, to spacings defined by SetSpacing(), * SetMargin(), AddSpacing(), and InsertSpacing(). The reverse transformation * is applied from physical pixels to logical units when dimensions are * retrieved by Spacing() and Margin(). * * \sa HorizontalSizer, VerticalSizer */ class PCL_CLASS Sizer : public UIObject { public: /*! * Represents the alignment of a %Sizer item. */ typedef Align::value_type item_alignment; /*! * Constructs a %Sizer object. * * \param vertical If true, this sizer will lay out items vertically. If * false, items will be laid out horizontally. */ Sizer( bool vertical ); /*! * Destroys a %Sizer object. */ virtual ~Sizer() { } /*! * Ensures that the server-side object managed by this instance is uniquely * referenced. * * Since sizers are unique objects by definition, calling this member * function has no effect. */ void EnsureUnique() override { // Sizers are unique objects by definition } /*! * Returns a reference to a null %Sizer instance. A null %Sizer does not * correspond to an existing sizer in the PixInsight core application. */ static Sizer& Null(); /*! * Returns a reference to the parent control of this %Sizer object, or * Control::Null() if this sizer has no parent control. */ Control& ParentControl() const; /*! * Returns true iff this %Sizer lays out items vertically. */ bool IsVertical() const; /*! * Returns true iff this %Sizer lays out items horizontally. */ bool IsHorizontal() const { return !IsVertical(); } /*! * Returns the number of items in this %Sizer object. */ int NumberOfItems() const; /*! * Returns the zero-based index of the specified child %Sizer object \a s in * this sizer, or -1 if the \a s sizer does not belong to this %Sizer. */ int IndexOf( const Sizer& s ) const; /*! * Returns the zero-based index of the specified child control \a c in this * sizer, or -1 if the \a c control does not belong to this %Sizer. */ int IndexOf( const Control& c ) const; /*! * Returns true iff the specified child sizer \a s belongs to this %Sizer. */ bool Contains( const Sizer& s ) const { return IndexOf( s ) >= 0; } /*! * Returns true iff the specified child control \a c belongs to this %Sizer. */ bool Contains( const Control& c ) const { return IndexOf( c ) >= 0; } /*! * Adds a sizer to this %Sizer object. * * \param s The %Sizer object to be added. * * \param stretchFactor Indicates how much space the sizer \a s will tend * to occupy within its parent sizer (this sizer), relative to * the rest of sibling sizer items. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description. * * \sa Add( Control&, int, item_alignment ), AddSpacing(), AddStretch(), * Insert() */ void Add( Sizer& s, int stretchFactor = 0 ); /*! * Adds a control to this %Sizer object. * * \param c The control to be added. * * \param stretchFactor Indicates how much space the control \a c will * try to occupy within its parent sizer (this sizer), relative * to the rest of sibling sizer items. A value of zero indicates * that the added control has no particular preference and can * be adapted to the existing space, as necessary/possible. * * \param align Item alignment. * * In the following example: * * \code * PushButton button1; * PushButton button2; * PushButton button3; * // ... * Sizer fooSizer; * fooSizer.Add( button1, 25 ); * fooSizer.Add( button2, 50 ); * fooSizer.Add( button3, 25 ); * \endcode * * The button1 control will occupy one half of the total available space for * fooSizer, and each of button1 and button2 will occupy 1/4 of the space * available in fooSizer. Stretch factors don't have to be expressed as * percentages necessarily, although using percentage values is usually more * readable. The stretch factors 2, 4, 2 would have the same meaning as 25, * 50, 25 in the example above. * * \sa Add( Sizer&, int ), AddSpacing(), AddStretch(), Insert() */ void Add( Control& c, int stretchFactor = 0, item_alignment align = Align::Default ); /*! * Adds a non-stretchable space of \a size pixels to this %Sizer. * * If the \a autoScaling parameter is set to true, the specified \a size * will be converted from logical device-independent pixel units to physical * device pixels automatically. If \a autoScaling is false, the specified * \a size is assumed to be expressed in physical pixel units, and no * automatic scaling will be performed. * * \sa InsertSpacing(), AddStretch(), InsertStretch() */ void AddSpacing( int size, bool autoScaling = true ); /*! * Adds a non-stretchable space of \a size logical pixels to this %Sizer. * This is a convenience member function equivalent to: * * \code AddSpacing( size, true ); \endcode */ void AddScaledSpacing( int size ) { AddSpacing( size, true ); } /*! * Adds a non-stretchable space of \a size physical pixels to this %Sizer. * This is a convenience member function equivalent to: * * \code AddSpacing( size, false ); \endcode */ void AddUnscaledSpacing( int size ) { AddSpacing( size, false ); } /*! * Adds a stretchable space with the specified stretch factor. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description of stretch factors. * * \sa AddSpacing(), InsertSpacing(), InsertStretch() */ void AddStretch( int stretchFactor = 100 ); /*! * Inserts a sizer in this %Sizer object. * * \param index Zero-based index where the sizer \a s will be inserted. * * \param s The %Sizer object to be added. * * \param stretchFactor Indicates how much space the sizer \a s will tend * to occupy within its parent sizer (this sizer), relative to * the rest of sibling sizer items. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description. * * \sa Insert( int, Control&, int, item_alignment ), InsertSpacing(), * InsertStretch(), Add() */ void Insert( int index, Sizer& s, int stretchFactor = 0 ); /*! * Inserts a control in this %Sizer object. * * \param index Zero-based index where the control \a c will be inserted. * * \param c The control to be added. * * \param stretchFactor Indicates how much space the control \a c will * tend to occupy within its parent sizer (this sizer), relative * to the rest of sibling sizer items. * * \param align Item alignment. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description. * * \sa Insert( int, Sizer&, int ), InsertSpacing(), InsertStretch(), Add() */ void Insert( int index, Control& c, int stretchFactor = 0, item_alignment align = Align::Default ); /*! * Inserts a non-stretchable space of \a size pixels in this %Sizer. * * If the \a autoScaling parameter is set to true, the specified \a size * will be converted from logical device-independent pixel units to physical * device pixels automatically. If \a autoScaling is false, the specified * \a size is assumed to be expressed in physical pixel units, and no * automatic scaling will be performed. * * \sa AddSpacing(), InsertStretch(), AddStretch() */ void InsertSpacing( int index, int size, bool autoScaling = true ); /*! * Inserts a non-stretchable space of \a size logical pixels in this %Sizer. * This is a convenience member function equivalent to: * * \code InsertSpacing( index, size, true ); \endcode */ void InsertScaledSpacing( int index, int size ) { InsertSpacing( index, size, true ); } /*! * Inserts a non-stretchable space of \a size physical pixels in this * %Sizer. This is a convenience member function equivalent to: * * \code InsertSpacing( index, size, false ); \endcode */ void InsertUnscaledSpacing( int index, int size ) { InsertSpacing( index, size, false ); } /*! * Inserts a stretchable space with the specified stretch factor. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description of stretch factors. * * \sa InsertSpacing(), AddSpacing(), AddStretch() */ void InsertStretch( int index, int stretchFactor = 100 ); /*! * Removes the specified sizer \a s from this %Sizer object. If \a s doesn't * belong to this sizer, nothing happens. */ void Remove( Sizer& s ); /*! * Removes the specified control \a c from this %Sizer object. If \a c * doesn't belong to this sizer, nothing happens. */ void Remove( Control& c ); /*! * Changes the stretch factor for a child sizer \a s belonging to this * %Sizer object. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description of stretch factors. */ void SetStretchFactor( Sizer& s, int stretch ); /*! * Changes the stretch factor for a child control \a s belonging to this * %Sizer object. * * See the documentation for Add( Control&, int, item_alignment ) for a * detailed description of stretch factors. */ void SetStretchFactor( Control& c, int stretch ); /*! * Changes the alignment of a child sizer \a s belonging to this %Sizer * object. */ void SetAlignment( Sizer& s, item_alignment align ); /*! * Changes the alignment of a child control \a c belonging to this %Sizer * object. */ void SetAlignment( Control& c, item_alignment align ); /*! * Returns the margin in pixels around this sizer. * * The margin is the empty space that is automatically reserved around * this sizer on its parent control's (or parent sizer's) client area. * The default margin is always zero pixels for all sizer types, unless * explicitly changed with this function. * * If the \a autoScaling parameter is set to true, the returned value will * be expressed in logical device-independent pixel units. This means that * the returned value has been converted from physical device pixels * automatically. If \a autoScaling is false, the returned value will be * expressed in physical device pixels, and no automatic scaling is applied. * * \sa SetMargin(), Spacing(), SetSpacing() */ int Margin( bool autoScaling = true ) const; /*! * Sets the margin in pixels around this sizer. * * If the \a autoScaling parameter is set to true, the specified \a margin * will be converted from logical device-independent pixel units to physical * device pixels automatically. If \a autoScaling is false, the specified * \a margin is assumed to be expressed in physical pixel units, and no * automatic scaling will be performed. * * \sa Margin(), Spacing(), SetSpacing() */ void SetMargin( int margin, bool autoScaling = true ); /*! * Returns the spacing in pixels between items in this %Sizer object. * * If the \a autoScaling parameter is set to true, the returned value will * be expressed in logical device-independent pixel units. This means that * the returned value has been converted from physical device pixels * automatically. If \a autoScaling is false, the returned value will be * expressed in physical device pixels, and no automatic scaling is applied. * * \sa SetSpacing(), Margin(), SetMargin() */ int Spacing( bool autoScaling = true ) const; /*! * Sets the spacing in pixels between items in this %Sizer object. * * If the \a autoScaling parameter is set to true, the specified \a spacing * will be converted from logical device-independent pixel units to physical * device pixels automatically. If \a autoScaling is false, the specified * \a spacing is assumed to be expressed in physical pixel units, and no * automatic scaling will be performed. * * \sa Spacing(), Margin(), SetMargin() */ void SetSpacing( int spacing, bool autoScaling = true ); /*! * Returns the ratio between physical screen pixels and device-independent * logical units for the parent control of this %Sizer object. This ratio is * used as a scaling factor by the LogicalPixelsToPhysical() and PhysicalPixelsToLogical() functions, and * is also applied automatically when \a autoScaling parameters are set to * true in a number of member functions; see the class description for more * information. * * The returned value is greater than or equal to one. Typical pixel ratios * are 2.0 for high-dpi displays such as Retina monitors, or 1.0 for normal * 96 dpi monitors. * * \sa LogicalPixelsToPhysical(), PhysicalPixelsToLogical() */ double DisplayPixelRatio() const; /*! * Returns the specified \a size in logical device-independent pixel units * converted to physical device pixels. * * \sa DisplayPixelRatio(), PhysicalPixelsToLogical() */ int LogicalPixelsToPhysical( int size ) const { return RoundInt( DisplayPixelRatio()*size ); } /*! * Returns the specified \a size in physical device pixels converted to * logical device-independent pixel units. * * \sa DisplayPixelRatio(), LogicalPixelsToPhysical() */ int PhysicalPixelsToLogical( int size ) const { return RoundInt( size/DisplayPixelRatio() ); } private: Sizer( void* h ) : UIObject( h ) { } void* CloneHandle() const override; friend class Control; }; // ---------------------------------------------------------------------------- /*! * \class HorizontalSizer * \brief Client-side interface to a PixInsight horizontal sizer. * * %HorizontalSizer lays out a sequence of items as a horizontal stack. */ class PCL_CLASS HorizontalSizer : public Sizer { public: /*! */ typedef Sizer::item_alignment item_alignment; /*! * Constructs a %HorizontalSizer object. */ HorizontalSizer() : Sizer( false ) { } /*! * Destroys a %HorizontalSizer object. */ virtual ~HorizontalSizer() { } }; // ---------------------------------------------------------------------------- /*! * \class VerticalSizer * \brief Client-side interface to a PixInsight vertical sizer. * * %VerticalSizer lays out a sequence of as a vertical stack. */ class PCL_CLASS VerticalSizer : public Sizer { public: /*! */ typedef Sizer::item_alignment item_alignment; /*! * Constructs a %VerticalSizer object. */ VerticalSizer() : Sizer( true ) { } /*! * Destroys a %VerticalSizer object. */ virtual ~VerticalSizer() { } }; // ---------------------------------------------------------------------------- #endif // __PCL_BUILDING_PIXINSIGHT_APPLICATION } // pcl #endif // __PCL_Sizer_h // ---------------------------------------------------------------------------- // EOF pcl/Sizer.h - Released 2022-03-12T18:59:29Z