SOL9 2.0 Class: FlowLayout

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree  SOL9 ClassList 

Source code

/******************************************************************************
 *
 * Copyright (c) 1999-2008 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) 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.
 *
 *
 *  FlowLayout.h
 *
 *****************************************************************************/

// SOL++2000

#pragma once

#include <sol\LayoutManager.h>
#include <sol\LinkedList.h>
#include <sol/View.h>

namespace SOL {

class View;
//class Panel;

class FlowLayout :public LayoutManager {
private:
  LinkedList list;
  int    direction;
  int    vgap;
  int    hgap;
  int    vspacing;
  int    hspacing;
  int    alignment;
public:
  // Direction

  static const int HORIZONTAL = 0;
  static const int VERTICAL   = 1;

  // Alignment
  static const int LEFT   = 0;
  static const int CENTER = 1;
  static const int RIGHT  = 2;

public:
  //2009/06/27
  FlowLayout(int dir=HORIZONTAL, int align = LEFT) 
    :list(False),
    direction(dir),
    vgap(4),
    hgap(4),
    vspacing(4),
    hspacing(4),
    alignment(align)
  {
  }

public:
  ~FlowLayout()
  {
  }

public:
  virtual void add(View* view) 
  {
    list.addLast(view);
  }

public:
  virtual void getExtension(Dimension& dim, int w, int h)
  {
    ListEntry* ptr = list.getEntry();
    int maxX = 0;
    int maxY = 0;
    int x = 0;
    int y = 0;
    int maxHeight = 0;

    if (alignment == LEFT) {
      x = hspacing;
      y = vspacing;
  
      while (ptr) {
        View* view = (View*)ptr -> getObject();
        Dimension d;
        view ->getPreferredSize(d);
        if (d.getHeight() > maxHeight) {
          maxHeight = d.getHeight();
        }

        if (direction == HORIZONTAL && (x+d.getWidth() >w )) {
          x = hspacing;
          y += maxHeight + vgap;
          maxHeight = 0;
        }
        //
        if (x + d.getWidth() > maxX) {
          maxX = x+d.getWidth();
        }
        if (y + d.getHeight() > maxY) {
          maxY = y+d.getHeight();
        }

        if (direction == HORIZONTAL) {
          x += d.getWidth() + hgap;
        } else {
          y += d.getHeight() + vgap;
        }
        ptr = ptr -> getNext();
      }
      maxX += hspacing;
      maxY += vspacing;
      dim.set(maxX, maxY);
    }
  
    if (alignment == CENTER && direction == HORIZONTAL) {
      y = vspacing;
      maxY = y;
      int tw = 0;
      ListEntry* sptr = ptr;
      int x1 = 0;
      while (ptr) {
        Dimension d;
        View* view = (View*)ptr -> getObject();
        view ->getPreferredSize(d);
        if ((tw + d.getWidth()) > w) {
          x1 = (w - (tw - hgap))/2;
          maxHeight = 0;
          ListEntry* end = ptr;
          if (ptr ->getNext() == NULL) end = NULL;
          while(sptr != end) {
            View* v = (View*)sptr ->getObject();
            Dimension s;
            v -> getPreferredSize(s);

            if (x1 + s.getWidth() > maxX) {
              maxX = x1 + s.getWidth();
            }
            x1 += s.getWidth() + hgap;
            if (s.getHeight() > maxHeight) {
              maxHeight = s.getHeight();
            }
            sptr = sptr -> getNext();
          }
          sptr = ptr;
          y += maxHeight + vgap;
          maxY = y;
          tw = d.getWidth() + hgap;
        }
        else {
          tw += d.getWidth() + hgap;
        }

        ptr = ptr -> getNext();
      }

      maxHeight = 0;
      while (sptr) {
        View* v = (View*)sptr ->getObject();
        Dimension s;
        v -> getPreferredSize(s);

        if (x1 + s.getWidth() > maxX) {
          maxX = x1 + s.getWidth();
        }
        x1 += s.getWidth() + hgap;

        if (s.getHeight() > maxHeight) {
          maxHeight = s.getHeight();
        }
        sptr = sptr -> getNext();
      }
      maxY += maxHeight + vgap;

      maxY -= vgap;
      maxX += hspacing;
      maxY += vspacing;
      dim.set(maxX, maxY);
    }
  }

public:
  virtual void layout(int x, int y, int w, int h) 
  {
    x = hspacing;
    y = vspacing;
  
    int maxHeight = 0;

    ListEntry* ptr = list.getEntry();
    if (alignment == LEFT) {
      x = hspacing;
      y = vspacing;
  
      int maxHeight = 0;
      while (ptr) {
        View* view = (View*)ptr -> getObject();
        Dimension d;
        view ->getPreferredSize(d);
        if (d.getHeight() > maxHeight) {
          maxHeight = d.getHeight();
        }

        if (direction == HORIZONTAL && (x+d.getWidth() >w )) {
          x = hspacing;
          y += maxHeight + vgap;
          maxHeight = 0;
        }
        view ->layout(x, y, d.getWidth(), d.getHeight());

        if (direction == HORIZONTAL) {
          x += d.getWidth() + hgap;
        } else {
          y += d.getHeight() + vgap;
        }
        ptr = ptr -> getNext();
      }
    }

    if (alignment == CENTER && direction == HORIZONTAL) {
      int tw = 0;
      ListEntry* sptr = ptr;
      int x1 = 0;
      while (ptr) {
        Dimension d;
        View* view = (View*)ptr -> getObject();
        view ->getPreferredSize(d);
        if ((tw + d.getWidth()) > w ) {
          x1 = (w - (tw - hgap))/2;
          maxHeight = 0;
          ListEntry* end = ptr;
          while(sptr != end) {
            View* v = (View*)sptr ->getObject();
            Dimension s;
            v -> getPreferredSize(s);
            v -> layout(x1, y, s.getWidth(), s.getHeight());
            x1 += s.getWidth() + hgap;
            if (s.getHeight() > maxHeight) {
              maxHeight = s.getHeight();
            }
            sptr = sptr -> getNext();
          }
          sptr = ptr;
          y += maxHeight + vgap;
          tw = d.getWidth() + hgap;
        }
        else {
          tw += d.getWidth() + hgap;
        }

        ptr = ptr -> getNext();
      }

      x1 = (w - (tw - hgap))/2;
      while (sptr) {
        View* v = (View*)sptr ->getObject();
        Dimension s;
        v -> getPreferredSize(s);
        v -> layout(x1, y, s.getWidth(), s.getHeight());
        x1 += s.getWidth() + hgap;
        sptr = sptr -> getNext();
      }
    }
  }

public:
  void  setAlignment(int align) { alignment = align; }
  
public:
  void  setVertSpacing(int v) { vspacing = v; }

public:
  void  setHorizSpacing(int v) { hspacing = v; }
  
public:
  void  setVertGap(int v) { vgap = v; }

public:
  void  setHorizGap(int v) { hgap = v; }
  
};

}



Last modified: 5 May 2019

Copyright (c) 2009-2019 Antillia.com ALL RIGHTS RESERVED.