/* This file is part of the KDE libraries
    Copyright (c) 1998 Emmeran Seehuber (the_emmy@hotmail.com)
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#ifndef KLGROUP_H
#define KLGROUP_H

#include "klchild.h"

/**
* KLGroup 
*
* Baseclass for all groups
*/
class KLGroup : public KLChild {
public:
  typedef QList<KLChild> KLChildList; 
  typedef QListIterator<KLChild> KLChildListIt;
  static const int DefaultSpacing;

protected:
  bool      a_sameSize;
  ulong     a_xSpacing;
  ulong     a_ySpacing;
  bool      a_spaceBorder; 
  bool      spacingOverwritten; 
  KLChildList   childs;

  ulong countShowedChilds();

public:
  const KLChildList &childList() const;

  /**
  * If true, all childs of this group will get the same room.
  * If the room is to big for a child, it will be centered
  *
  * Note: A samesize group completely ignore the weights
  * 
  * Each subclass of KLGroup should support this flag
  */
  void setSameSize(bool samesize);

  /**
  * Set the x space between the childs in pixel
  */
  void setXSpacing( ulong x );
  
  /**
  * Set the y spacing between the childs in pixel
  */
  void setYSpacing( ulong y );
  
  /**
  * If true, the group will get a spaceborder. This
  * means, that the group have at it borders xSpacing
  * and ySpacing pixel free room.
  */
  void setSpaceBorder( bool spaceBorder );
  
  /**
  * @return true if group is in SameSize modus
  * @see setSameSize()
  */
  bool sameSize() const;
  
  /**
  * @return X (row) spacing
  * @see setXSpacing()
  */
  ulong xSpacing() const;
  
  /**
  * @return Y (coloum) spacing
  * @see setYSpacing()
  */
  ulong ySpacing() const;
  
  /**
  * return true if samesize is on
  * @see setSpaceBorder()
  */
  bool spaceBorder() const;

public:
  KLGroup();
  ~KLGroup();

  virtual bool klSetup( KLSetupInfo *setupInfo );
  virtual void klHide();
  virtual void klCleanup();

  virtual KLChild *findChild( ulong x, ulong y ) const;

  /**
  * Add´s a child to this group
  *
  * If the group is showed at this moment,
  * this will force a relayout. Than also
  * this child will be showed
  *
  * NOTE: If a group get´s deleted,
  * it also deletes all of it´s childs
  *
  * @param child Child to insert into. 
  */
  bool addChild( KLChild *child );

  /**
  * Removes a child from this group
  *
  * If the group is showed, this will
  * force a relayout
  */
  void remChild( KLChild *child );

  /**
  * @return the list of childs this group containts
  */
  const KLChildList &children() const 
  { return childs; };

  virtual void setupGrap();
  virtual void cleanupGrap();

  virtual void addDropMarks( KLDropMarkList * dml );

  // Streaming group mainpulators
  typedef void (*_grp_change_func)(KLGroup&);

  /**
  * Apply a streaming manipulator
  */
  KLGroup &operator<<(_grp_change_func func);

  /**
  * Add a child via streaming 
  *
  * @see #addChild()
  */
  KLGroup &operator<<(KLChild *child);

  /**
  * Add a child via streaming
  *
  * @see #addChild()
  */
  KLGroup &operator<<(KLChild &child);

  /**
  * Apply a streaming manipulator
  */
  KLGroup &operator<<(_child_change_func func);

  /**
  * Apply a streaming manipulator
  */
  KLStreamHelp &operator<<(_child_change_p1_func func);

  DECLARE_KLMETA_STANDALONE();

};


/**
* KLHVGroup
*
* Horionzontal and vertical group. Layouts all childs in a row or a coloum
*/

class KLHVGroup : public KLGroup 
{
private:
  bool a_horiz; // Horionzontal, or not ?

  void askMinMaxSS(KLMinMaxSizes *mms);
  void askMinMaxN(KLMinMaxSizes *mms);
  bool showSS( ulong actX, ulong actY, ulong compAvailXSpace, ulong compAvailYSpace );
  bool showN( ulong actX, ulong actY, ulong compAvailXSpace, ulong compAvailYSpace );
  
  bool doShowChilds(ulong actX, ulong actY, ulong xSize, ulong ySize );
  void spreadRoundDiffs( ulong xDiff, ulong yDiff );

  void sumWeight( ulong &xWeight, ulong &yWeight );

  KLChild *getNextNotHidden(KLChild *child);
  KLChild *getPrevNotHidden(KLChild *child);

public:
  /**
  * If true, all visible childs of this group are layouted horionzontal,
  * from the left to the right.
  *
  * If false, all visible childs will be layouted vertical, from the 
  * top to the bottom
  *
  * Changing this will force a relayout
  *
  * @see #horiz()
  */
  void setHoriz(bool horiz);

  /**
  * @return true if the group is horionzontal
  */
  bool horiz();

public:
  KLHVGroup(bool horiz=false);

  virtual bool klAskMinMax(KLMinMaxSizes *minMaxSizes);
  virtual bool klShow(KLShowInfo *showInfo);
  virtual void addDropMarks( KLDropMarkList * dml );

  DECLARE_KLMETA_STANDALONE();
};

/**
* KLPageGroup
*
* This group shows only one of its child at once.
* 
* NOTE: It does not display any tabcontrols.
*/

class KLPageGroup : public KLGroup {
  ulong a_actPage;

public:
  /**
  * Changes the actual page number. 
  * This will hide the active page and
  * then show the new page
  *
  * If you give an invalid pagenumber, you will get
  * an assert, and the current page will not change.
  */
  void setActPage(ulong page);

  /**
  * Get the actual page number
  */
  ulong actPage();

public:
  /**
  * Calculation Mode of the page group
  *
  * - ActMax: The maximumsize of the group is the maximumsize of the actual
  *           page.
  * - MaxMax: The maximumsize of this group is the maximumsize of all pages
  */
  enum CalcMode { ActMax, MaxMax };
  KLPageGroup(CalcMode calcMode = MaxMax);
  virtual bool klAskMinMax(KLMinMaxSizes *minMaxSizes);
  virtual bool klShow(KLShowInfo *showInfo);

  /**
  * @return the actual calcMode
  */
  CalcMode calcMode();

  /**
  * Sets the CalcMode
  *
  * Will force a relayout
  */
  void setCalcMode( CalcMode calcMode );

  DECLARE_KLMETA_STANDALONE(); 
private:
  CalcMode a_calcMode;
};

/**
* KLGridGroup
*
* Provides a grid (=table) layout.
*
*/

class KLGridGroup : public KLGroup {
private:
  bool   a_rowGrid; 
  ulong  a_rowColCount;  

  ulong xDim;   // Dimension of the grid
  ulong yDim;   // "           "

  class KLSizeNode : public KLMinMaxSizes {
  public:
    ulong size;
    KLSizeNode() : size(0) {};
  };

  QList<KLSizeNode> xList;
  QList<KLSizeNode> yList;

  void calcAndSetDim(); // Calculates the dimension of the size array
  void askMinMax_InitSizes();
  void askMinMaxN( KLMinMaxSizes *minMaxSizes );
  void askMinMaxSS( KLMinMaxSizes *minMaxSizes );
  void askMinMax_CorrectBorder( KLMinMaxSizes *minMaxSizes );

  void showSS( ulong availXSpace, ulong availYSpace );
  void showN( ulong availXSpace, ulong availYSpace );
  void spreadRoundDiffs( ulong availXSpace, ulong availYSpace );
  bool doShowChilds( KLShowInfo *showInfo, ulong actX, ulong actY );

  KLChild *getChild(ulong x, ulong y);

public:
  /**
  * Contructs a Gridgroup with rowColCount Coloums or
  * Rows. rowGrid says, if this a coloum(false) or a 
  * row grid
  *
  * Note: Before you can show a grid, you MUST make sure
  * that the count of showed nodes % rowColCount == 0.
  * Otherwise you will get an assert and nothing displayed
  *
  * If you want to change the attributes rowColCount, you
  * should stop the layouting (if the widget is showed). 
  * 
  * Known Bug: It ignores any weight settings fully (at the moment)
  *
  * @see setRowColCount(), setRowGrid()
  */
  KLGridGroup(ulong rowColCount = 2, bool rowGrid = false);
  ~KLGridGroup() {}; 


  virtual bool klAskMinMax(KLMinMaxSizes *minMaxSizes);
  virtual bool klShow(KLShowInfo *showInfo);

  /**
  * TRUE when a rowGrid. This means, that the 
  * grid uses its mebers to fill up rows:
  * (e.g. you´ve 20 members and a rowColCount of 4)
  *
  * <pre>
  * 1 | 5 | 9 | 13| 17|
  * --+---+---+---+---+
  * 2 | 6 |10 | 14| 18|
  * --+---+---+---+---+
  * 3 | 7 |11 | 15| 19|
  * --+---+---+---+---+
  * 4 | 8 |12 | 16| 20|
  * </pre>
  *
  *
  * (of course, there are no seperators between the cols and rows)
  *
  * if rowGrid = false, it will look like this:
  *
  * <pre>
  * 1  | 2  | 3  | 4
  * 5  | 6  | 7  | 8 
  * 9  | 10 | 11 | 12
  * 13 | 14 | 15 | 16
  * 17 | 18 | 19 | 20
  * </pre>
  *
  * @see KLGridGroup(), rowColCount()
  */
  bool  rowGrid(); 

  /**
  * Count of rows or coloums. If it are rows
  * or coloums depends on rowTab()
  *
  * @see KLGridGroup(), rowTab()
  */
  ulong rowColCount();  

  /**
  * Sets rowGrid. 
  *
  * Will force a relayout 
  * @see rowGrid()
  */
  void setRowGrid(bool);

  /**
  * Sets the row or coloum count
  *
  * Will force a relayout 
  * @see rowColCount()
  */
  void setRowColCount(ulong);

  /**
  * Validates the grid. This means, that the grid
  * will be filled up with KLReplaceMe´s so that the
  * assertion mebmercount % rowColCount() == 0 is true.
  *
  * After filling up, it will try to remove as much
  * KLReplaceMe´s from the end as possible
  */ 
  void validateGrid();

  DECLARE_KLMETA_STANDALONE();
};


/////////////////////////////////////////////////////////////////////
// Streaming operators inline functions
/////////////////////////////////////////////////////////////////////
/**
* Stream operator for group. Sets SameSize = TRUE
*/
inline void setSameSize(KLGroup& group)
{ group.setSameSize(TRUE); }
inline void setSpaceBorder(KLGroup &group)
{ group.setSpaceBorder(true); }

/////////////////////////////////////////////////////////////////////
// Other inline funcs
/////////////////////////////////////////////////////////////////////
inline bool KLGridGroup::rowGrid()
{ return a_rowGrid; }

inline ulong KLGridGroup::rowColCount()
{ return a_rowColCount; }


#endif

Documentation generated by emmy@gate on Tue Sep 22 21:13:27 MEST 1998