;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; this is an invisible box.
;; should be used to introduce invisible flex widgets.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
register-widget spring:
  lambda spring-ctor ()
    define super new-basic-widget()
    method-lambda padding-widget
      super: (self)
        super
      type: (self)
        spring:
      else
        super


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; padding widget.
;; it automatically became fixed size when "width:" or "height:" is set.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
register-widget padding:
  lambda padding-ctor ()
    define super new-basic-widget()
    define size 2
    method-lambda padding-widget
      super: (self)
        super
      type: (self)
        padding:
      size: (self)
        size
      size-set!: (self value)
        assert {{fixnum? value} and {value >= 0}} "invalid padding size"
        {size := value}
        self
      ;;
      flex: (self)
        0
      pref-width: (self)
        if self[parent:][horiz?:]
          self[size:]
          0
      pref-height: (self)
        if self[parent:][vert?:]
          self[size:]
          0
      min-width: (self) self[pref-width:]
      max-width: (self) self[pref-width:]
      min-height: (self) self[pref-height:]
      max-height: (self) self[pref-height:]
      ;;
      handle-property: (self name value)
        self[property-changed: name value]
        case name
          (size:)
            {self[size:] := value}
            #t
          else
            inherited handle-property: name value
      ;;
      else
        super


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; static text label
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
register-widget label:
  lambda label-ctor ()
    define super new-basic-widget()
    define activate-id #nil
    define raw-text #f
    ;;
    define text-w(str)
      if raw-text
        lgfx:text-width str
        lgfx:text-width-hi str
    ;;
    method-lambda label-widget
      super: (self)
        super
      type: (self)
        label:
      ;;
      raw-text: (self)
        raw-text
      raw-text-set!: (self value)
        assert {boolean? value} "label raw-text property should be a boolean"
        if {raw-text <> value}
          need-repaint!()
        {raw-text := value}
        self
      ;;
      text-set!: (self value)
        assert {string? value} "invalid text property"
        inherited text-set!: value
        {self[pref-width:] := {text-w(value) + 2}}
        self
      ;;
      activate-id: (self) activate-id
      activate-id-set!: (self value)
        {activate-id := value}
        self
      ;;
      pref-width-set!: (self value)
        define text self[text:]
        define tw {text-w(text) + 2}
        {value := max(value tw)}
        inherited pref-width-set!: value
        self
      ;;
      paint: (self)
        define text self[text:]
        define tw text-w(text)
        define x0 {{self[final-width:] - tw} div 2}
        define y0 {{{self[final-height:] - lgfx:text-height()} div 2} + lgfx:text-ascender()}
        if raw-text
          lgfx:print-str x0 y0 text self[style-prop: text-color:]
          lgfx:print-str-hi x0 y0 text self[style-prop: text-color:] self[style-prop: hi-color:]
        self
      ;;
      handle-event: (self evt)
        if (and evt[alive?:]
                evt[key-broadcast?:]
                {evt[type:] eq? 'KEY-DOWN}
                sdl:names-equal?(self[hotkey:] evt[keysym:]))
          then
            evt[eat!:]
            define cbox self[find-widget: self[activate-id:]]
            self[top-widget:][activate-widget: cbox]
            self[perform-action:]
        if evt[alive?:]
          inherited handle-event: evt
      ;;
      handle-property: (self name value)
        self[property-changed: name value]
        case name
          (activate-id:)
            {self[activate-id:] := value}
            #t
          (raw-text:)
            {self[raw-text:] := value}
            #t
          else
            inherited handle-property: name value
      ;;
      else
        super
