/* Copyright 2010 Aaron J. Radke Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cc.drx object Style{ //#---Properties sealed trait Property{ /**composing two Style properties creates a Style*/ def ~(that:Property):Style = Style(Set(this,that)) } case object Default extends Property case class Background(c:Color) extends Property trait ColorOption{ def colorOption:Option[Color] } sealed trait FillOption extends Property with ColorOption case object FillNone extends FillOption{ def colorOption:Option[Color] = None } case class Fill(c:Color) extends FillOption{ def colorOption:Option[Color] = Some(c) } //Strokes sealed trait StrokeOption extends Property with ColorOption case object StrokeNone extends StrokeOption{ def colorOption:Option[Color] = None } case class Stroke(c:Color) extends StrokeOption{ /**convenience function for composition*/ def weight(w:Double) = this ~ Weight(w) def colorOption:Option[Color] = Some(c) } case class Weight(value:Double) extends Property //##---Property -> Font object Font{ def apply(size:Double):Font = Font("Helvetica",size) def apply(name:String):Font = Font(name,12) // def list(g:DrawContext):List[Font] = g.listFonts //TODO } case class Font(name:String,size:Double) extends Property //##---Property -> Alignment sealed trait AlignHorizontal extends Property case object Left extends AlignHorizontal case object Right extends AlignHorizontal case object Center extends AlignHorizontal sealed trait AlignVertical extends Property case object Top extends AlignVertical case object Bottom extends AlignVertical case object Midline extends AlignVertical //Vertical Center case class Align(horz:AlignHorizontal, vert:AlignVertical) extends Property //##---Property -> Transformation case class Translate(t:Vec) extends Property case class ScaleProperty(t:Vec) extends Property case class Rotate(r:Angle) extends Property case class Transform(translate:Vec=Vec(0,0),rotate:Angle=Angle(0),scale:Vec=Vec(1,1)) extends Property object Transform{ def apply(translate:Vec,rotate:Angle,scale:Double):Transform = new Transform(translate, rotate, Vec(scale,scale)) def apply(translate:Vec,scale:Double):Transform = new Transform(translate, Angle(0), Vec(scale,scale)) def apply(a:Rect, b:Rect):Transform = { val s = b.width/a.width //TODO add hight scale as well val d = a.a - b.a Transform(translate = d, scale = Vec(s,s)) } } implicit class DrxStyleString(val string:String) extends AnyVal{ //TODO 2017-07-30("use Text(string,v) instead it is hard to see what is going on and search","v.0.2.15??") def ~(v:Vec):Text = Text(string,v) //TODO this feels very hacky because Text is not a style but often used in a similar manner } } /**A style is a set of style properties*/ case class Style(properties:Set[Style.Property]=Set()) extends Iterable[Style.Property]{ // def foreach[U](f: Style.Property => U):Unit = properties foreach f //Implements Traversable prior to 2.13 def iterator:Iterator[Style.Property] = properties.iterator /**add a style property to the set (clobber if one already exists*/ def ~(additionalProperty:Style.Property):Style = Style(properties + additionalProperty) /**merge a Style (clobber if some properties already exist)*/ def ~(mergeStyle:Style):Style = Style(properties ++ mergeStyle.properties) }