diff --git a/src/main/scala/scala/swing/group/Alignments.scala b/src/main/scala/scala/swing/group/Alignments.scala deleted file mode 100644 index e6fe900..0000000 --- a/src/main/scala/scala/swing/group/Alignments.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.swing.group - -import javax.swing.GroupLayout - -/** Provides alignment constants for parallel groups in a `GroupPanel`. - * - * @author Andreas Flierl - */ -trait Alignments { - /** - * Represents an alignment of a component (or group) within a parallel group. - * - * @see javax.swing.GroupLayout.Alignment - */ - protected sealed class Alignment(private[group] val wrapped: GroupLayout.Alignment) - - /** Elements are aligned along their baseline. Only valid along the vertical axis. */ - object Baseline extends Alignment(GroupLayout.Alignment.BASELINE) - - /** Elements are centered inside the group. */ - object Center extends Alignment(GroupLayout.Alignment.CENTER) - - /** Elements are anchored to the leading edge (origin) of the group. */ - object Leading extends Alignment(GroupLayout.Alignment.LEADING) - - /** Elements are anchored to the trailing edge (end) of the group. */ - object Trailing extends Alignment(GroupLayout.Alignment.TRAILING) -} diff --git a/src/main/scala/scala/swing/group/BaselineAnchors.scala b/src/main/scala/scala/swing/group/BaselineAnchors.scala deleted file mode 100644 index 6ef4d6a..0000000 --- a/src/main/scala/scala/swing/group/BaselineAnchors.scala +++ /dev/null @@ -1,33 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.swing.group - -/** Provides baseline anchor constants for a `GroupPanel`. Baseline anchors - * may either be explicitly specified (using the Parallel.baseline(...) factory) - * or will be determined based on its elements: the baseline will be anchored - * to the bottom if and only if all the elements with a baseline, and that are - * aligned to the baseline, have a baseline resize behavior of - * `CONSTANT_DESCENT`. - * - * @author Andreas Flierl - */ -trait BaselineAnchors { - /** - * Allows to specify whether to anchor the baseline to the top or the bottom - * of a baseline-aligned parallel group. - */ - protected sealed class BaselineAnchor(private[group] val wrapped: Boolean) - - /** Anchor the baseline to the top of the group. */ - object AnchorToTop extends BaselineAnchor(true) - - /** Anchor the baseline to the bottom of the group. */ - object AnchorToBottom extends BaselineAnchor(false) -} \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/BaselineCustomization.scala b/src/main/scala/scala/swing/group/BaselineCustomization.scala new file mode 100644 index 0000000..4cb27bc --- /dev/null +++ b/src/main/scala/scala/swing/group/BaselineCustomization.scala @@ -0,0 +1,52 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +package scala.swing.group + +import swing._ +import javax.swing.{ GroupLayout, JPanel } +import java.awt.{ Component => AWTComp } +import scala.annotation.tailrec + +/** Allows to assign a baseline reference, i.e. a component that provides the + * baseline of the panel instead of the panel itself (which has no meaningful + * baseline by default). + * + * @author Andreas Flierl + */ +trait BaselineCustomization { this: Panel => + private[this] var customBaseline: Option[Component] = None + + object theBaselineReference { + def is(c: Component): Unit = { + if (! peer.isAncestorOf(c.peer)) throw new IllegalArgumentException( + "component to be used as baseline reference must be a descendant of this GroupPanel") + customBaseline = Some(c) + } + } + + def theDefaultBaselineIsUsed(): Unit = customBaseline = None + + /** The swing `JPanel` wrapped by this `Panel`. */ + override lazy val peer: JPanel = new JPanel with SuperMixin { + override def getBaseline(w: Int, h: Int): Int = { + customBaseline.map { c => + setSize(w, h) + validate + sumOfOffsets(c.peer, c.peer.getBaseline(c.peer.getWidth, c.peer.getHeight)) + }.getOrElse(super.getBaseline(w, h)) + } + + @tailrec + private[this] def sumOfOffsets(c: AWTComp, y: Int): Int = { + if (c == this || ! c.getParent.isInstanceOf[AWTComp]) y + else sumOfOffsets(c.getParent.asInstanceOf[AWTComp], y + c.getY) + } + } +} \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/ComponentsInGroups.scala b/src/main/scala/scala/swing/group/ComponentsInGroups.scala index b8cfb94..1ff3e41 100644 --- a/src/main/scala/scala/swing/group/ComponentsInGroups.scala +++ b/src/main/scala/scala/swing/group/ComponentsInGroups.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -18,32 +18,28 @@ import javax.swing.GroupLayout * * @author Andreas Flierl */ -trait ComponentsInGroups extends SizeTypes { this: GroupPanel => - /** - * Implicit conversion that puts a component into the correct context on demand. - */ +trait ComponentsInGroups { this: GroupPanel => + /** Implicit conversion that puts a component into the correct context on demand. */ protected final implicit def add[A <: G](comp: Component) = new ComponentInGroup[A](comp) /** Triplet of minimum, preferred and maximum size. */ private[group] case class Sizes(min: Size, pref: Size, max: Size) - /** - * Wraps an arbitrary component so that it may appear within a group of - * type `A`. - */ + /** Wraps an arbitrary component so that it may appear within a group of + * type `A`. + */ protected final class ComponentInGroup[A <: G](comp: Component) extends InGroup[A] with SizeHelpers[A] { override private[group] def build(parent: A) = parent.addComponent(comp.peer) - /** - * Specifies size constraints for this component. - * - * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - */ + /** Specifies size constraints for this component. + * + * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + */ def sized(min: Size, pref: Size, max: Size) = new ComponentWithSize[A](comp, Sizes(min, pref, max)) @@ -57,18 +53,15 @@ trait ComponentsInGroups extends SizeTypes { this: GroupPanel => */ def asBaseline = new ComponentInSequential(comp, None, true) - /** - * Specifies an alignment for this component. May only be used inside a - * parallel group. - * - * @param newAlign the alignment to use - */ + /** Specifies an alignment for this component. May only be used inside a + * parallel group. + * + * @param newAlign the alignment to use + */ def aligned(newAlign: Alignment) = new ComponentInParallel(comp, None, newAlign) } - /** - * Wraps an arbitrary component to allow for custom size constraints. - */ + /** Wraps an arbitrary component to allow for custom size constraints. */ protected final class ComponentWithSize[A <: G](comp: Component, sizes: Sizes) extends InGroup[A] { override private[group] def build(parent: A) = @@ -85,21 +78,19 @@ trait ComponentsInGroups extends SizeTypes { this: GroupPanel => */ def asBaseline = new ComponentInSequential(comp, Some(sizes), true) - /** - * Specifies an alignment for this component. May only be used inside a - * parallel group. - * - * @param newAlign the alignment to use - */ + /** Specifies an alignment for this component. May only be used inside a + * parallel group. + * + * @param newAlign the alignment to use + */ def aligned(newAlign: Alignment) = new ComponentInParallel(comp, Some(sizes), newAlign) } - /** - * Wraps a GUI component so that it may appear in a sequential group. - * - * @see javax.swing.GroupLayout.SequentialGroup - */ + /** Wraps a GUI component so that it may appear in a sequential group. + * + * @see javax.swing.GroupLayout.SequentialGroup + */ protected final class ComponentInSequential(comp: Component, sizes: Option[Sizes], useAsBaseline: Boolean) extends InSequential with SizeHelpers[GroupLayout#SequentialGroup] { @@ -110,22 +101,20 @@ trait ComponentsInGroups extends SizeTypes { this: GroupPanel => sizes.get.pref.pixels, sizes.get.max.pixels) else parent.addComponent(useAsBaseline, comp.peer) - /** - * Specifies size constraints for this component. - * - * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - */ + /** Specifies size constraints for this component. + * + * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + */ def sized(min: Size, pref: Size, max: Size) = new ComponentInSequential(comp, Some(Sizes(min, pref, max)), useAsBaseline) } - /** - * Wraps a GUI component so that it may appear in a parallel group. - * - * @see javax.swing.GroupLayout.ParallelGroup - */ + /** Wraps a GUI component so that it may appear in a parallel group. + * + * @see javax.swing.GroupLayout.ParallelGroup + */ protected final class ComponentInParallel(comp: Component, sizes: Option[Sizes], align: Alignment) extends InParallel with SizeHelpers[GroupLayout#ParallelGroup] { @@ -136,53 +125,44 @@ trait ComponentsInGroups extends SizeTypes { this: GroupPanel => sizes.get.pref.pixels, sizes.get.max.pixels) else parent.addComponent(comp.peer, align.wrapped) - /** - * Specifies size constraints for this component. - * - * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - */ + /** Specifies size constraints for this component. + * + * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + */ def sized(min: Size, pref: Size, max: Size) = new ComponentInParallel(comp, Some(Sizes(min, pref, max)), align) } - /** - * Additional methods for nicer control over resizing behaviour. - */ + /** Additional methods for nicer control over resizing behaviour. */ private[group] sealed trait SizeHelpers[A <: G] { - /** - * Specifies size constraints for this component. - * - * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) - */ + /** Specifies size constraints for this component. + * + * @param min minimum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param pref preferred size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @param max maximum size >= 0 (or one of `UseDefault`, `UsePreferred` and `Infinite`) + */ def sized(min: Size, pref: Size, max: Size): InGroup[A] - /** - * Fixes the size of this component to its default size. - */ + /** Fixes the size of this component to its default size. */ def fixedToDefaultSize = sized(UsePreferred, UseDefault, UsePreferred) - /** - * Fixes the size of this component to the specified size. - * - * @param size the desired size in pixels - */ + /** Fixes the size of this component to the specified size. + * + * @param size the desired size in pixels + */ def sized(size: Size): InGroup[A] = sized(UsePreferred, size, UsePreferred) - /** - * Forces this component to be resizable (useful e.g. for buttons). Its - * minimum size is set to its default size. - */ + /** Forces this component to be resizable (useful e.g. for buttons). Its + * minimum size is set to its default size. + */ def resizable(min: Size = UseDefault, pref: Size = UseDefault, max: Size = Infinite) = sized(min, pref, max) - /** - * Forces this component to be resizable (useful e.g. for buttons). Its - * minimum size is set to 0 pixels. - */ + /** Forces this component to be resizable (useful e.g. for buttons). Its + * minimum size is set to 0 pixels. + */ def fullyResizable(pref: Size = UseDefault) = sized(0, pref, Infinite) } } \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/Delegations.scala b/src/main/scala/scala/swing/group/Delegations.scala index 34874bd..5853179 100644 --- a/src/main/scala/scala/swing/group/Delegations.scala +++ b/src/main/scala/scala/swing/group/Delegations.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -20,47 +20,39 @@ import javax.swing.SwingConstants trait Delegations { val layout: GroupLayout - /** - * The component will not take up any space when it's invisible (default). - */ + /** The component will not take up any space when it's invisible (default). */ def honorVisibilityOf(comp: Component) = layout.setHonorsVisibility(comp.peer, true) - /** - * The component will still take up its space even when invisible. - */ + /** The component will still take up its space even when invisible. */ def ignoreVisibilityOf(comp: Component) = layout.setHonorsVisibility(comp.peer, false) - /** - * Links the sizes (horizontal and vertical) of several components. - * - * @param comps the components to link - */ + /** Links the sizes (horizontal and vertical) of several components. + * + * @param comps the components to link + */ def linkSize(comps: Component*) = layout.linkSize(comps.map(_.peer): _*) - /** - * Links the sizes of several components horizontally. - * - * @param comps the components to link - */ + /** Links the sizes of several components horizontally. + * + * @param comps the components to link + */ def linkHorizontalSize(comps: Component*) = layout.linkSize(SwingConstants.HORIZONTAL, comps.map(_.peer): _*) - /** - * Links the sizes of several components vertically. - * - * @param comps the components to link - */ + /** Links the sizes of several components vertically. + * + * @param comps the components to link + */ def linkVerticalSize(comps: Component*) = layout.linkSize(SwingConstants.VERTICAL, comps.map(_.peer): _*) - /** - * Replaces one component with another. Great for dynamic layouts. - * - * @param existing the component to be replaced - * @param replacement the component replacing the existing one - */ + /** Replaces one component with another. Great for dynamic layouts. + * + * @param existing the component to be replaced + * @param replacement the component replacing the existing one + */ def replace(existing: Component, replacement: Component) = layout.replace(existing.peer, replacement.peer) } \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/Gaps.scala b/src/main/scala/scala/swing/group/Gaps.scala index a17503c..12c90ba 100644 --- a/src/main/scala/scala/swing/group/Gaps.scala +++ b/src/main/scala/scala/swing/group/Gaps.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -20,94 +20,83 @@ import javax.swing.SwingConstants * * @author Andreas Flierl */ -trait Gaps extends SizeTypes { this: GroupPanel => - /** - * A manual gap between two components. - */ +trait Gaps { this: GroupPanel => + /** A manual gap between two components. */ protected object Gap { - /** - * Creates a rigid (non-resizable) gap with the specified size. - * - * @param size the size >= 0 of the gap - * - * @see GroupLayout.Group#addGap(int) - */ + /** Creates a rigid (non-resizable) gap with the specified size. + * + * @param size the size >= 0 of the gap + * + * @see GroupLayout.Group#addGap(int) + */ def apply[A <: G](size: GapSize) = new InGroup[A] { override private[group] def build(parent: A) = parent.addGap(size.pixels) } - /** - * Creates a resizable gap with the specified size constraints. - * - * @param min minimum size >= 0 - * @param pref preferred size >= 0 - * @param max maximum size >= 0 - * @see GroupLayout.Group#addGap(int, int, int) - */ + /** Creates a resizable gap with the specified size constraints. + * + * @param min minimum size >= 0 + * @param pref preferred size >= 0 + * @param max maximum size >= 0 + * @see GroupLayout.Group#addGap(int, int, int) + */ def apply[A <: G](min: GapSize, pref: GapSize, max: GapSize) = new InGroup[A] { override private[group] def build(parent: A) = parent.addGap(min.pixels, pref.pixels, max.pixels) } } - /** - * A gap between two components that acts like a ''spring'', pushing the two - * elements away from each other. - */ + /** A gap between two components that acts like a ''spring'', pushing the two + * elements away from each other. + */ protected object Spring { - /** - * Creates a preferred gap that acts like a ''spring'' with the specified - * size constraints between the two elements that surround this gap. - * The minimum size is the preferred size of the gap which is defined by - * the `LayoutStyle` used. - * - * @param relationship the relationship between the two components; - * the default for this parameter is `Related` - * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` - * or `Infinite`); the default for this parameter is `UseDefault` - * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement, int, int) - */ + /** Creates a preferred gap that acts like a ''spring'' with the specified + * size constraints between the two elements that surround this gap. + * The minimum size is the preferred size of the gap which is defined by + * the `LayoutStyle` used. + * + * @param relationship the relationship between the two components; + * the default for this parameter is `Related` + * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` + * or `Infinite`); the default for this parameter is `UseDefault` + * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement, int, int) + */ def apply(relationship: RelatedOrUnrelated = Related, preferred: PreferredGapSize = UseDefault) = PreferredGap(relationship, preferred, Infinite) } - /** - * A manual gap between a component and a container (or group) edge. - * Only valid inside a sequential group. - */ + /** A manual gap between a component and a container (or group) edge. + * Only valid inside a sequential group. + */ protected object ContainerGap { - /** - * Creates a gap between a component and a container edge, using the - * preferrerd size as specified in the `layoutStyle`. - * - * @see GroupLayout.Group#addContainerGap() - */ + /** Creates a gap between a component and a container edge, using the + * preferrerd size as specified in the `layoutStyle`. + * + * @see GroupLayout.Group#addContainerGap() + */ def apply() = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = parent.addContainerGap() } - /** - * Creates a new gap with the specified size constraints between a - * component and a container edge. - * - * @param pref the preferred size >= 0 of the gap (or one of `UseDefault` and `Infinite`) - * @param max the maximum size >= 0 of the gap (or one of `UseDefault`, `UsePreferred` and `Infinite`) - * @see GroupLayout.Group#addContainerGap(int, int) - */ + /** Creates a new gap with the specified size constraints between a + * component and a container edge. + * + * @param pref the preferred size >= 0 of the gap (or one of `UseDefault` and `Infinite`) + * @param max the maximum size >= 0 of the gap (or one of `UseDefault`, `UsePreferred` and `Infinite`) + * @see GroupLayout.Group#addContainerGap(int, int) + */ def apply(pref: PreferredGapSize, max: Size) = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = parent.addContainerGap(pref.pixels, max.pixels) } } - /** - * A gap between a component and a container (or group) edge that acts like - * a ''spring'', pushing the element away from the edge. - */ + /** A gap between a component and a container (or group) edge that acts like + * a ''spring'', pushing the element away from the edge. + */ protected object ContainerSpring { - /** - * Creates a resizable gap that acts like a ''spring''. + /** Creates a resizable gap that acts like a ''spring''. * * @param pref preferred size >= 0 (or one of `UseDefault` and `Infinite`) * the default for this parameter is `UseDefault` @@ -116,70 +105,65 @@ trait Gaps extends SizeTypes { this: GroupPanel => def apply[A <: G](pref: PreferredGapSize = UseDefault) = ContainerGap(pref, Infinite) } - /** - * A gap between two components with a size that is defined by the - * `LayoutStyle` used, depending on the relationship between - * the components. - */ + /** A gap between two components with a size that is defined by the + * `LayoutStyle` used, depending on the relationship between + * the components. + */ protected object PreferredGap { - /** - * Creates a preferred gap between the two elements that surround this - * gap. - * - * @param relationship the relationship between the two components - * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement) - */ + /** Creates a preferred gap between the two elements that surround this + * gap. + * + * @param relationship the relationship between the two components + * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement) + */ def apply(relationship: RelatedOrUnrelated) = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = parent.addPreferredGap(relationship.wrapped) } - /** - * Creates a preferred gap with the specified size constraints between the - * two elements that surround this gap. The minimum size is the preferred - * size of the gap which is defined by the `LayoutStyle` used. - * - * @param relationship the relationship between the two components - * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` and `Infinite`) - * @param the maximum size >= 0 of the gap (or one of `UseDefault`, `UsePreferred` - * and `Infinite`) - * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement, int, int) - */ + /** Creates a preferred gap with the specified size constraints between the + * two elements that surround this gap. The minimum size is the preferred + * size of the gap which is defined by the `LayoutStyle` used. + * + * @param relationship the relationship between the two components + * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` and `Infinite`) + * @param the maximum size >= 0 of the gap (or one of `UseDefault`, `UsePreferred` + * and `Infinite`) + * @see GroupLayout.Group#addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement, int, int) + */ def apply(relationship: RelatedOrUnrelated, preferred: PreferredGapSize, max: Size) = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = parent.addPreferredGap(relationship.wrapped, preferred.pixels, max.pixels) } - /** - * Creates a rigid gap between the two specified elements. The minimum - * size is the preferred size of the gap which is defined by the - * `LayoutStyle` used. - * - * @param comp1 the element "in front of" the gap - * @param comp2 the element "behind" the gap - * @param relationship the relationship between the two components - * @see GroupLayout.Group#addPreferredGap(javax.swing.JComponent, javax.swing.JComponent, javax.swing.LayoutStyle.ComponentPlacement) - */ + /** Creates a rigid gap between the two specified elements. The minimum + * size is the preferred size of the gap which is defined by the + * `LayoutStyle` used. + * + * @param comp1 the element "in front of" the gap + * @param comp2 the element "behind" the gap + * @param relationship the relationship between the two components + * @see GroupLayout.Group#addPreferredGap(javax.swing.JComponent, javax.swing.JComponent, javax.swing.LayoutStyle.ComponentPlacement) + */ def apply(comp1: Component, comp2: Component, relationship: Placement) = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = parent.addPreferredGap(comp1.peer, comp2.peer, relationship.wrapped) } - /** - * Creates a preferred gap with the specified size constraints between the - * two specified elements. The minimum size is the preferred size of the gap - * which is defined by the `LayoutStyle` used. - * - * @param comp1 the element "in front of" the gap - * @param comp2 the element "behind" the gap - * @param relationship the relationship between the two components - * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` - * and `Infinite`) - * @param the maximum size >= 0 of the gap (or one of `UseDefault` and `Infinite`) - * @see GroupLayout.Group#addPreferredGap(javax.swing.JComponent, javax.swing.JComponent, javax.swing.LayoutStyle.ComponentPlacement, int, int) - */ + /** Creates a preferred gap with the specified size constraints between the + * two specified elements. The minimum size is the preferred size of the gap + * which is defined by the `LayoutStyle` used. + * + * @param comp1 the element "in front of" the gap + * @param comp2 the element "behind" the gap + * @param relationship the relationship between the two components + * @param preferred the preferred size >= 0 of the gap (or one of `UseDefault` + * and `Infinite`) + * @param the maximum size >= 0 of the gap (or one of `UseDefault` and `Infinite`) + * @see GroupLayout.Group#addPreferredGap(javax.swing.JComponent, javax.swing.JComponent, javax.swing.LayoutStyle.ComponentPlacement, int, int) + */ def apply(comp1: Component, comp2: Component, relationship: Placement, preferred: PreferredGapSize, max: PreferredGapSize) = new InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = diff --git a/src/main/scala/scala/swing/group/GroupLayoutProperties.scala b/src/main/scala/scala/swing/group/GroupLayoutProperties.scala index b463672..ed9f81c 100644 --- a/src/main/scala/scala/swing/group/GroupLayoutProperties.scala +++ b/src/main/scala/scala/swing/group/GroupLayoutProperties.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -24,16 +24,14 @@ trait GroupLayoutProperties { /** Sets whether gaps between components are automatically created. */ def autoCreateGaps_=(flag: Boolean) = layout.setAutoCreateGaps(flag) - /** - * Indicates whether gaps between components and the container borders are - * automatically created. - */ + /** Indicates whether gaps between components and the container borders are + * automatically created. + */ def autoCreateContainerGaps = layout.getAutoCreateContainerGaps - /** - * Sets whether gaps between components and the container borders are - * automatically created. - */ + /** Sets whether gaps between components and the container borders are + * automatically created. + */ def autoCreateContainerGaps_=(flag: Boolean) = layout.setAutoCreateContainerGaps(flag) @@ -43,18 +41,16 @@ trait GroupLayoutProperties { /** Assigns a layout style to use. */ def layoutStyle_=(style: javax.swing.LayoutStyle) = layout.setLayoutStyle(style) - /** - * Indicates whether the visibilty of components is considered for the layout. - * If set to `false`, invisible components still take up space. - * Defaults to `true`. - */ + /** Indicates whether the visibilty of components is considered for the layout. + * If set to `false`, invisible components still take up space. + * Defaults to `true`. + */ def honorsVisibility = layout.getHonorsVisibility - /** - * Sets whether the visibilty of components should be considered for the - * layout. If set to `false`, invisible components still take up - * space. Defaults to `true`. - */ + /** Sets whether the visibilty of components should be considered for the + * layout. If set to `false`, invisible components still take up + * space. Defaults to `true`. + */ def honorsVisibility_=(flag: Boolean) = layout.setHonorsVisibility(flag) } \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/GroupPanel.scala b/src/main/scala/scala/swing/group/GroupPanel.scala index 8642b1f..8daaf63 100644 --- a/src/main/scala/scala/swing/group/GroupPanel.scala +++ b/src/main/scala/scala/swing/group/GroupPanel.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -41,11 +41,13 @@ import javax.swing.LayoutStyle.ComponentPlacement * * This section contains a few simple examples to showcase the basic * functionality of `GroupPanel`s. For all examples, it is assumed - * that everything from the package `scala.swing` is imported and the code is - * placed inside a [[scala.swing.SimpleSwingApplication]] like this: + * that everything from the package `scala.swing` and `scala.swing.group` + * is imported and the code is placed inside + * a [[scala.swing.SimpleSwingApplication]] like this: * * {{{ * import swing._ + * import group._ * * object Example extends SimpleSwingApplication { * override def top = new MainFrame { @@ -145,6 +147,17 @@ import javax.swing.LayoutStyle.ComponentPlacement * Since a text field's resizing behaviour is `CENTER_OFFSET`, it is * not resizable when used with baseline alignment. * + * ===Baseline reference=== + * + * Since panels do not provide a meaningful baseline by default, a `GroupPanel` + * allows to define a baseline reference, i.e. a component that provides the + * baseline for the panel instead. For example, to use `myButton` as the baseline + * reference, one may declare: + * + * {{{ + * theBaselineReference is myButton + * }}} + * * ==Gaps== * * The `GroupPanel` turns on automatic creation of gaps between @@ -183,7 +196,7 @@ import javax.swing.LayoutStyle.ComponentPlacement * the `Gap` object: * * {{{ - * bc.. theHorizontalLayout is Sequential( + * theHorizontalLayout is Sequential( * label, * Gap(10, 20, 100), * textField @@ -204,7 +217,7 @@ import javax.swing.LayoutStyle.ComponentPlacement * and `ContainerSpring` objects. * * {{{ - * bc.. theHorizontalLayout is Sequential( + * theHorizontalLayout is Sequential( * ContainerGap(), * label, * Spring(), // default is Related @@ -218,7 +231,7 @@ import javax.swing.LayoutStyle.ComponentPlacement * should be used - but can be resized to an arbitrary size. * * {{{ - * bc.. theHorizontalLayout is Sequential( + * theHorizontalLayout is Sequential( * ContainerGap(), * label, * Spring(Unrelated), @@ -231,7 +244,7 @@ import javax.swing.LayoutStyle.ComponentPlacement * or `Infinite` aka "as large as possible"): * * {{{ - * bc.. theHorizontalLayout is Sequential( + * theHorizontalLayout is Sequential( * ContainerGap(), * label, * Spring(Unrelated, Infinite), @@ -289,19 +302,15 @@ import javax.swing.LayoutStyle.ComponentPlacement * @author Andreas Flierl */ class GroupPanel extends Panel + with BaselineCustomization with GroupLayoutProperties with Delegations - with Alignments - with Placements with ComponentsInGroups with Groups with Gaps { private[group] type G = GroupLayout#Group - /** The swing `JPanel` wrapped by this `GroupPanel`. */ - override lazy val peer: javax.swing.JPanel = new javax.swing.JPanel with SuperMixin - /** This panel's underlying layout manager. */ val layout = new GroupLayout(peer) @@ -310,12 +319,12 @@ class GroupPanel extends Panel autoCreateContainerGaps = true /** Starting point for the horizontal layout. */ - val theHorizontalLayout = new { + object theHorizontalLayout { def is(group: Group) = layout.setHorizontalGroup(group.buildChildren) } /** Starting point for the vertical layout. */ - val theVerticalLayout = new { + object theVerticalLayout { def is(group: Group) = layout.setVerticalGroup(group.buildChildren) } } diff --git a/src/main/scala/scala/swing/group/Groups.scala b/src/main/scala/scala/swing/group/Groups.scala index fd8d0a4..b823902 100644 --- a/src/main/scala/scala/swing/group/Groups.scala +++ b/src/main/scala/scala/swing/group/Groups.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -16,16 +16,13 @@ import javax.swing.GroupLayout._ * * @author Andreas Flierl */ -trait Groups - extends Resizing - with BaselineAnchors { this: GroupPanel => +trait Groups { this: GroupPanel => - /** - * Elements with this trait may only appear in groups corresponding to the - * type `A`. - * - * @tparam A the type of the group: sequential, parallel or both - */ + /** Elements with this trait may only appear in groups corresponding to the + * type `A`. + * + * @tparam A the type of the group: sequential, parallel or both + */ protected trait InGroup[A <: G] { private[group] def build(parent: A): G } @@ -43,12 +40,11 @@ trait Groups private[group] def buildChildren: G } - /** - * Generic superclass for sequential and parallel groups. - * - * @tparam A the type of the (swing layout) group that surrounds the elements - * of this group - */ + /** Generic superclass for sequential and parallel groups. + * + * @tparam A the type of the (swing layout) group that surrounds the elements + * of this group + */ private class GroupImpl[A <: G](elems: List[InGroup[A]], val peerGroup: A) extends Group { @@ -59,127 +55,113 @@ trait Groups } /** Implicit conversion that puts a group into the correct context on demand. */ - protected final implicit def groupInSequential(grp: Group) = - new GroupInSequential(grp, None) + protected final implicit def groupInSequential(grp: Group) = new GroupInSequential(grp, None) /** Implicit conversion that puts a group into the correct context on demand. */ - protected final implicit def groupInParallel(grp: Group) = - new GroupInParallel(grp, None) + protected final implicit def groupInParallel(grp: Group) = new GroupInParallel(grp, None) - /** - * Wraps a group of components to extend it with actions only allowed inside - * a sequential group. - * - * @see javax.swing.GroupLayout.SequentialGroup - */ - protected sealed class GroupInSequential(wrapped: Group, - useAsBaseline: Option[Boolean]) extends InSequential { + /** Wraps a group of components to extend it with actions only allowed inside + * a sequential group. + * + * @see javax.swing.GroupLayout.SequentialGroup + */ + protected sealed class GroupInSequential(wrapped: Group, useAsBaseline: Option[Boolean]) extends InSequential { override private[group] def build(parent: GroupLayout#SequentialGroup) = if (useAsBaseline.isDefined) parent.addGroup(useAsBaseline.get, wrapped.buildChildren) else parent.addGroup(wrapped.buildChildren) - /** - * Use this group to calculate the baseline for the surrounding group. Only - * one member of that group should be marked this way. - */ + /** Use this group to calculate the baseline for the surrounding group. Only + * one member of that group should be marked this way. + */ def asBaseline = new GroupInSequential(wrapped, Some(true)) /** Do not use this group to calculate the baseline for the surrounding group. */ def notAsBaseline = new GroupInSequential(wrapped, Some(false)) } - /** - * Wraps a group of components to extend it with actions only allowed inside - * a parallel group. - * - * @see javax.swing.GroupLayout.ParallelGroup - */ + /** Wraps a group of components to extend it with actions only allowed inside + * a parallel group. + * + * @see javax.swing.GroupLayout.ParallelGroup + */ protected sealed class GroupInParallel(wrapped: Group, align: Option[Alignment]) extends InParallel { override private[group] def build(parent: GroupLayout#ParallelGroup) = if (align.isDefined) parent.addGroup(align.get.wrapped, wrapped.buildChildren) else parent.addGroup(wrapped.buildChildren) - /** - * Specifies an alignment for this component. - * - * @param newAlign the alignment to use - */ + /** Specifies an alignment for this component. + * + * @param newAlign the alignment to use + */ def aligned(newAlign: Alignment) = new GroupInParallel(wrapped, Some(newAlign)) } - /** - * Declares a sequential group, i.e. a group whose child components appear - * one after another within the available space. - * - * @see GroupLayout.SequentialGroup - */ + /** Declares a sequential group, i.e. a group whose child components appear + * one after another within the available space. + * + * @see GroupLayout.SequentialGroup + */ protected object Sequential { - /** - * Creates a new sequential group of the specified elements. - * - * @param elems the elements to group - * @see GroupLayout#createSequentialGroup - */ + /** Creates a new sequential group of the specified elements. + * + * @param elems the elements to group + * @see GroupLayout#createSequentialGroup + */ def apply(elems: InSequential*): Group = new GroupImpl(elems.toList, layout.createSequentialGroup) } - /** - * Declares a parallel group, i.e. a group whose child components share the - * same space. Because some components may (and will) be bigger than others, - * an alignment can be specified to resolve placement of the components - * relative to each other. - * - * @see GroupLayout.ParallelGroup - */ + /** Declares a parallel group, i.e. a group whose child components share the + * same space. Because some components may (and will) be bigger than others, + * an alignment can be specified to resolve placement of the components + * relative to each other. + * + * @see GroupLayout.ParallelGroup + */ protected object Parallel { - /** - * Creates a new parallel group of the specified elements. The default - * alignment is `leading`. - * - * @param elems the elements to group - * @see GroupLayout#createParallelGroup() - */ + /** Creates a new parallel group of the specified elements. The default + * alignment is `leading`. + * + * @param elems the elements to group + * @see GroupLayout#createParallelGroup() + */ def apply(elems: InParallel*): Group = new GroupImpl(elems.toList, layout.createParallelGroup) - /** - * Creates a new parallel group of the specified elements that aligns them - * in the specified way. - * - * @param align how to align the elements - * @param elems the elements to group - * @see GroupLayout#createParallelGroup(GroupLayout.Alignment) - */ + /** Creates a new parallel group of the specified elements that aligns them + * in the specified way. + * + * @param align how to align the elements + * @param elems the elements to group + * @see GroupLayout#createParallelGroup(GroupLayout.Alignment) + */ def apply(align: Alignment)(elems: InParallel*): Group = new GroupImpl(elems.toList, layout.createParallelGroup(align.wrapped)) - /** - * Creates a new parallel group of the specified elements that aligns them - * in the specified way and is resizable or not. - * - * @param align how to align the elements - * @param resizability whether the group is resizable or of fixed size - * (default: resizable) - * @param elems the elements to group - * @see GroupLayout#createParallelGroup(GroupLayout.Alignment, boolean) - */ + /** Creates a new parallel group of the specified elements that aligns them + * in the specified way and is resizable or not. + * + * @param align how to align the elements + * @param resizability whether the group is resizable or of fixed size + * (default: resizable) + * @param elems the elements to group + * @see GroupLayout#createParallelGroup(GroupLayout.Alignment, boolean) + */ def apply(align: Alignment, resizability: Resizability = Resizable)(elems: InParallel*): Group = new GroupImpl(elems.toList, layout.createParallelGroup(align.wrapped, resizability.wrapped)) - /** - * Creates a new parallel group of the specified elements that aligns them - * along their baseline, has the specified resizing behaviour and anchors - * the baseline to the top or the bottom of the group. - * - * @param resizability whether the group is resizable or of fixed size - * (default: resizable) - * @param anchor whether to anchor the baseline to the top or the bottom of - * the group - * @param elems the elements to group - * @see GroupLayout#createBaselineGroup(boolean, boolean) - */ + /** Creates a new parallel group of the specified elements that aligns them + * along their baseline, has the specified resizing behaviour and anchors + * the baseline to the top or the bottom of the group. + * + * @param resizability whether the group is resizable or of fixed size + * (default: resizable) + * @param anchor whether to anchor the baseline to the top or the bottom of + * the group + * @param elems the elements to group + * @see GroupLayout#createBaselineGroup(boolean, boolean) + */ def baseline(resizability: Resizability = Resizable, anchor: BaselineAnchor)(elems: InParallel*): Group = new GroupImpl(elems.toList, layout.createBaselineGroup(resizability.wrapped, diff --git a/src/main/scala/scala/swing/group/Placements.scala b/src/main/scala/scala/swing/group/Placements.scala deleted file mode 100644 index 62ffff5..0000000 --- a/src/main/scala/scala/swing/group/Placements.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.swing.group - -import javax.swing.LayoutStyle.ComponentPlacement - -/** Provides placement constants for a `GroupPanel`. - * - * @author Andreas Flierl - */ -trait Placements { - /** - * Specifies how two components are placed relative to each other. - * - * @see javax.swing.LayoutStyle.ComponentPlacement - */ - protected[Placements] sealed class Placement( - private[group] val wrapped: ComponentPlacement) - - /** - * Specifies if two components are related or not. - * - * @see javax.swing.LayoutStyle.ComponentPlacement - */ - protected[Placements] sealed class RelatedOrUnrelated( - cp: ComponentPlacement) extends Placement(cp) - - /** Used to request the distance between two visually related components. */ - object Related extends RelatedOrUnrelated(ComponentPlacement.RELATED) - - /** Used to request the distance between two visually unrelated components. */ - object Unrelated extends RelatedOrUnrelated(ComponentPlacement.UNRELATED) - - /** - * Used to request the (horizontal) indentation of a component that is - * positioned underneath another component. - */ - object Indent extends Placement(ComponentPlacement.INDENT) -} diff --git a/src/main/scala/scala/swing/group/Resizing.scala b/src/main/scala/scala/swing/group/Resizing.scala deleted file mode 100644 index 750b662..0000000 --- a/src/main/scala/scala/swing/group/Resizing.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.swing.group - -/** Provides constants to specify the resizing beheviour of groups in a - * `GroupPanel`. - * - * @author Andreas Flierl - */ -trait Resizing { - /** - * Allows to specify whether a parallel group should be resizable or of - * fixed size. - */ - protected sealed class Resizability(private[group] val wrapped: Boolean) - - /** The corresponding parallel group should be resizable. */ - object Resizable extends Resizability(true) - - /** The corresponding parallel group should be of fixed size. */ - object FixedSize extends Resizability(false) -} \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/SizeTypes.scala b/src/main/scala/scala/swing/group/SizeTypes.scala deleted file mode 100644 index 68fd4d4..0000000 --- a/src/main/scala/scala/swing/group/SizeTypes.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala.swing.group - -import javax.swing.GroupLayout - -/** Provides types and constants to ensure the correct use of pixel sizes and - * size hints in a `GroupLayout`. Integer values will be converted to a size - * type via an implicit conversion. These pixel sizes must always be >= 0. - * - * @author Andreas Flierl - */ -trait SizeTypes { - /** Pixel size and all size hints. Used to specify sizes of a component and - * the maximum size of `PreferredGap`s and `ContainerGap`s. - */ - protected sealed class Size(val pixels: Int) - - /** Pixel size and `Infinite`. Used to specify the size of a `Gap`. */ - protected sealed trait GapSize extends Size - - /** Pixel size, `UseDefault` and `Infinite`. Used to specify the preffered - * size of `PreferredGap`s and `ContainerGap`s. - */ - protected sealed trait PreferredGapSize extends Size - - /** Instructs the layout to use a component's default size. */ - object UseDefault extends Size(GroupLayout.DEFAULT_SIZE) with PreferredGapSize - - /** Instructs the layout to use a component's preferred size. */ - object UsePreferred extends Size(GroupLayout.PREFERRED_SIZE) - - /** Represents an arbitrarily large size. */ - object Infinite extends Size(Int.MaxValue) with GapSize with PreferredGapSize - - /** Implicitly converts an Int to a Size object when needed. - * - * @param pixels a size in pixels; must be >= 0 - */ - protected implicit def int2Size(pixels: Int) = { - require(pixels >= 0, "size must be >= 0") - new Size(pixels) with GapSize with PreferredGapSize - } -} \ No newline at end of file diff --git a/src/main/scala/scala/swing/group/package.scala b/src/main/scala/scala/swing/group/package.scala new file mode 100644 index 0000000..0ff5fcb --- /dev/null +++ b/src/main/scala/scala/swing/group/package.scala @@ -0,0 +1,151 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + + +package scala.swing + +import javax.swing.GroupLayout +import javax.swing.LayoutStyle.ComponentPlacement + +/** Quasi-enums for the configuration of a `GroupPanel`. + * + * @author Andreas Flierl + */ +package object group { + /** Represents an alignment of a component (or group) within a parallel group + * in a `GroupPanel`. The instances of this class can be found in the package + * object. + * + * @see javax.swing.GroupLayout.Alignment + */ + sealed class Alignment private[group] (private[group] val wrapped: GroupLayout.Alignment) + + /** Elements are aligned along their baseline. Only valid along the vertical axis. */ + val Baseline = new Alignment(GroupLayout.Alignment.BASELINE) + + /** Elements are centered inside the group. */ + val Center = new Alignment(GroupLayout.Alignment.CENTER) + + /** Elements are anchored to the leading edge (origin) of the group. */ + val Leading = new Alignment(GroupLayout.Alignment.LEADING) + + /** Elements are anchored to the trailing edge (end) of the group. */ + val Trailing = new Alignment(GroupLayout.Alignment.TRAILING) + + + + /** Type of baseline anchor constants for a `GroupPanel`, which allow + * to specify whether to anchor the baseline to the top or the bottom + * of a baseline-aligned parallel group. + * + * Baseline anchors may either be explicitly specified (using the + * Parallel.baseline(...) factory) or will be determined based on + * its elements: the baseline will be anchored to the bottom + * if and only if all the elements with a baseline, and that are + * aligned to the baseline, have a baseline resize behavior of + * `CONSTANT_DESCENT`. + * + * The instances of this class can be found in the package object. + */ + sealed class BaselineAnchor private[group] (private[group] val wrapped: Boolean) + + /** Anchor the baseline to the top of the group. */ + val AnchorToTop = new BaselineAnchor(true) + + /** Anchor the baseline to the bottom of the group. */ + val AnchorToBottom = new BaselineAnchor(false) + + + + /** Supertype for pixel sizes and size hints. Used to specify sizes + * of a component and the maximum size of `PreferredGap`s and + * `ContainerGap`s. + * + * The instances of this class can be found in the package object. + * + * Integer values can be converted to a size type via an implicit + * conversion, provided in the companion object. + * These pixel sizes must always be >= 0. + */ + sealed class Size private[group] (val pixels: Int) + object Size { + /** Implicitly converts an Int to a Size object when needed. + * + * @param pixels a size in pixels; must be >= 0 + */ + implicit def int2Size(pixels: Int) = { + require(pixels >= 0, "size must be >= 0") + new Size(pixels) with GapSize with PreferredGapSize + } + } + + /** Pixel size and `Infinite`. Used to specify the size of a `Gap`. + * The instances of this class can be found in the package object. + */ + sealed trait GapSize extends Size + + /** Pixel size, `UseDefault` and `Infinite`. Used to specify the preffered + * size of `PreferredGap`s and `ContainerGap`s. + * + * The instances of this class can be found in the package object. + */ + sealed trait PreferredGapSize extends Size + + /** Instructs the layout to use a component's default size. */ + val UseDefault = new Size(GroupLayout.DEFAULT_SIZE) with PreferredGapSize + + /** Instructs the layout to use a component's preferred size. */ + val UsePreferred = new Size(GroupLayout.PREFERRED_SIZE) + + /** Represents an arbitrarily large size. */ + val Infinite = new Size(Int.MaxValue) with GapSize with PreferredGapSize + + + + /** Specifies how two components are placed relative to each other. + * + * The instances of this class can be found in the package object. + * + * @see javax.swing.LayoutStyle.ComponentPlacement + */ + sealed class Placement private[group] (private[group] val wrapped: ComponentPlacement) + + /** Specifies if two components are related or not. + * + * The instances of this class can be found in the package object. + * + * @see javax.swing.LayoutStyle.ComponentPlacement + */ + sealed class RelatedOrUnrelated private[group] (cp: ComponentPlacement) extends Placement(cp) + + /** Used to request the distance between two visually related components. */ + val Related = new RelatedOrUnrelated(ComponentPlacement.RELATED) + + /** Used to request the distance between two visually unrelated components. */ + val Unrelated = new RelatedOrUnrelated(ComponentPlacement.UNRELATED) + + /** Used to request the (horizontal) indentation of a component that is + * positioned underneath another component. + */ + val Indent = new Placement(ComponentPlacement.INDENT) + + + + /** Allows to specify whether a parallel group in a `GroupPanel` should be + * resizable or of fixed size. + * + * The instances of this class can be found in the package object. + */ + sealed class Resizability private[group] (private[group] val wrapped: Boolean) + + /** The corresponding parallel group should be resizable. */ + val Resizable = new Resizability(true) + + /** The corresponding parallel group should be of fixed size. */ + val FixedSize = new Resizability(false) +} \ No newline at end of file diff --git a/src/main/scala/scala/swing/test/group/GroupLayoutDemo.scala b/src/main/scala/scala/swing/test/group/GroupLayoutDemo.scala index 3291240..2b4fd64 100644 --- a/src/main/scala/scala/swing/test/group/GroupLayoutDemo.scala +++ b/src/main/scala/scala/swing/test/group/GroupLayoutDemo.scala @@ -1,7 +1,7 @@ package scala.swing.test.group import scala.swing._ -import scala.swing.group.GroupPanel +import group._ object GroupLayoutDemo extends SimpleSwingApplication { override def top = new MainFrame {