{curl 6.0 applet}
{curl-file-attributes character-encoding = "windows-latin-1"}
{define-class public AutoResizeTextFieldUI {inherits StandardTextFieldUI}
{constructor package {default control:#TextField = null, ... }
{construct-super control = control, opaque-to-events? = true, ...}
}
{method public open {get-width-preference lc:LayoutContext}:Dimension
{return
{self.adjust-width-preference
{super.get-width-preference lc}, lc
}
}
}
{method public open {constrain-height
lc:LayoutContext,
ascent:Distance,
descent:Distance}:Dimension
{return
{self.adjust-width-preference
{super.constrain-height lc, ascent, descent}, lc
}
}
}
|| This returns the cell preferences of the child of this UI. So the default width
|| that was returned by StandardTextFieldUI is completely ignored. If the child
|| preference is less than 4pt, it returns 4pt.
{method protected open {adjust-width-preference
d:Dimension, lc:LayoutContext
}:Dimension
{return
{if-non-null child = self.child then
def oe:OriginElastic = child.cell-width-preference
{if oe.preferred-size < 4pt then
4pt
else
oe
}
else
d
}
}
}
}
{define-class package NoBevelAutoResizeTextFieldUI {inherits AutoResizeTextFieldUI}
field public constant no-bevel?:bool
{constructor package {default
control:#TextField = null,
no-bevel?:bool = true,
...
}
set self.no-bevel? = no-bevel?
{construct-super control = control, ...}
}
|| This setter is called when the TextFieldUI is associated with the TextField. We
|| use this opportunity to set any border and/or margin that was set on the UI or
|| its children.
{setter public open {control value:Control}:void
set super.control = value
{self.flatten-hierarchy}
}
|| Resursively remove the border and margin for each child elements as
|| we want that this TextFieldUI should not take any more space than it
|| is needed..
{method private {flatten-hierarchy}:void
{if not self.no-bevel? then {return}}
{self.visit-subtree
self,
{proc {g:Graphic}:void
set g.border-width = 0pt
set g.margin = 0pt
set g.border-spec = null
}
}
}
{method private {visit-subtree
g:Graphic,
action-proc:{proc-type {Graphic}:void}
}:void
{action-proc g}
{type-switch g
case b:Box do
{for child:Graphic in b.graphical-children do
{self.visit-subtree child, action-proc}
}
}
}
|| Do not draw any bevels.
{method protected open {overdraw-control renderer2d:Renderer2d}:void
{if not self.no-bevel? then
{super.overdraw-control renderer2d}
}
}
}
{TextField
value = "Hello There!",
ui-object = {AutoResizeTextFieldUI control-content-background = "lime"}
}
{TextField
value = "Hello There!",
ui-object =
{NoBevelAutoResizeTextFieldUI control-content-background = "lime"}
}
{TextField
value = "Hello There!",
editable? = false,
ui-object =
{NoBevelAutoResizeTextFieldUI control-content-background = "lime"},
{on e:PointerRelease at tf:TextField do
{if e.button == right-button and
e.state-mask.shift? and
not e.moved-since-press?
then
set tf.editable? = true
}
},
{on e:ValueFinished at tf:TextField do
set tf.editable? = false
}
}
{define-class package CustomTextField {inherits TextField}
field private cached-value:#String
{constructor package {default
data-model:#StringDataModel = null,
value:#String = null,
prompt:#String = null,
max-chars:int = -1,
ui-object:#TextFieldUI = null,
...
}
{construct-super
data-model = data-model,
value = value,
prompt = prompt,
max-chars = max-chars,
ui-object = ui-object,
...
}
set self.cached-value = self.value
{self.add-event-handler
{on e:ValueFinished do
{self.maybe-commit}
}
}
}
{method public open {maybe-commit}:void
let constant val:#String = self.value
{if val == null or val.empty? then
{self.revert}
else
{self.commit}
}
}
{method public open {on-focus-out e:FocusOut}:void
{super.on-focus-out e}
{self.maybe-commit}
}
{method private {revert}:void
{if-non-null val = self.cached-value then
set self.value = val
else
{self.unset-value}
}
set self.editable? = false
{self.enqueue-event {Action}}
}
{method private {commit}:void
set self.cached-value = self.value
set self.value = {non-null self.cached-value}
set self.editable? = false
{self.enqueue-event {Action}}
}
{method public open {on-key-press e:KeyPress}:void
{if e.value == KeyPressValue.esc then
{self.revert}
{e.consume}
}
{super.on-key-press e}
}
}
{CustomTextField
editable? = false,
value = "Fruits",
ui-object =
{NoBevelAutoResizeTextFieldUI control-content-background = "lime"},
{on e:PointerRelease at tf:TextField do
{if e.button == right-button and
e.state-mask.shift? and
not e.moved-since-press? and
not tf.editable?
then
{dump e}
set tf.editable? = true
{e.consume}
}
}
}
{define-proc package {get-tab-label str:String}:Graphic
let label:Label = {Label str}
def frm:Frame = {Frame opaque-to-events? = true, label}
def tf:TextField =
{CustomTextField
value = str,
ui-object = {AutoResizeTextFieldUI},
editable? = true
}
{frm.add-event-handler
{on e:PointerRelease at frm:Frame do
{if e.button == right-button and
not e.moved-since-press?
then
{if frm.child == null or frm.child.graphic != tf then
set tf.editable? = true
{frm.add tf, replace? = true}
{tf.become-active}
}
}
{e.consume}
}
}
{tf.add-event-handler
{on e:Action do
|| We create a new Label as there seems to be no API that we
|| can call on a Label to change its text and honour the nemonic
|| associated with it.
def new-label = {Label {tf.get-text}}
{frm.add new-label, replace? = true}
set label = new-label
}
}
{return frm}
}
{TabContainer
{TabPane
label = {get-tab-label "&One"},
tab-button-tooltip = "first tab",
{TextFlowBox font-size = 28pt, "1"}
},
{TabPane
label = {get-tab-label "&Two"},
tab-button-tooltip = "second tab",
show? = true,
{TextFlowBox font-size = 28pt, "2"}
},
{TabPane
label = {get-tab-label "T&hree"},
tab-button-tooltip = "third tab",
{TextFlowBox font-size = 28pt, "3"}
}
}
There are no comments on this document