dyoshidaさん、ありがとうございます。
ただ、SkinnedSRGTextFieldFeel の中でコンシュームするのをやめても、
View にまではESCのキーイベントは透過されないようです。
こうなると、RecordGrid が怪しくなってくるわけですが・・・。
Code:
{define-class public open CustomSkinnedSRGTextFieldFeel
{inherits SkinnedSRGTextFieldFeel}
||-- {method public open {on-start-composition-event
||-- e:StartCompositionEvent
||-- }:void
||-- {if-non-null ui = self.ui-object asa #SkinnableTextFieldUI then
||-- {if not e.consumed? then
||-- {type-switch {get-grid-cell ui}
||-- case srgc:StandardRecordGridCell do
||-- {srgc.reveal-if-hidden}
||-- {if not srgc.edit-active? then
||-- {ui.control.become-active-from-traversal}
||-- set srgc.edit-active? = true
||-- }
||-- }
||-- }
||-- }
||-- || FIXME: why don't we call into super here?
||-- }
{method public open {on-key-press ev:KeyPress}:void
{if-non-null ui = self.ui-object asa #SkinnableTextFieldUI then
let constant cell:StandardRecordGridCell =
{non-null {get-grid-cell ui}}
{cell.reveal-if-hidden}
|| Toggle edit mode if necessary.
{if not cell.edit-active? and
(ev.insertable? or
ev.value == KeyPressValue.backspace or
ev.value == KeyPressValue.delete or
ev.value == KeyPressValue.enter or
ev.value == KeyPressValue.f2)
then
set cell.edit-active? = true
{ui.control.become-active-from-traversal}
}
let constant rng:StringDataModelWritableRange =
(ui.control asa TextField).selected-range
let constant ui-reserved?:bool =
{if-non-null grid = cell.grid then
{grid.ui.reserved-key? ev}
else
false
}
|| Squelch grid keys, except right/left/home/end
|| when not fully selected.
{if cell.edit-active? and
(not ui-reserved? or
((ev.value == KeyPressValue.right or
ev.value == KeyPressValue.left or
ev.value == KeyPressValue.home or
ev.value == KeyPressValue.end) and
rng.size != rng.data-model.size))
then
{switch ev.value
case KeyPressValue.esc do
|| Escape reverts the cell.
{cell.refresh-data}
||↓ コンシュームしないようにしてもView は閉じない
|| (RecordGrid に握りつぶされている?)
|| {ev.consume}
case KeyPressValue.f2 do
|| f2 used by windows to collapse selection for editing.
{if rng.size == rng.data-model.size then
set rng.point = rng.max-index
{rng.collapse-to-point}
{ev.consume}
}
}
|| Suppress editing keys when non-editable.
{if ev.insertable? or
ev.value == KeyPressValue.delete or
ev.value == KeyPressValue.backspace
then
{if {grid-cell-can-update? ui} then
{super.on-key-press ev}
}
else
{super.on-key-press ev}
}
}
{forward-to-grid-cell ui, ev}
set ev.test-recorded? = true
else
{super.on-key-press ev}
}
}
}
||--{define-class public open CustomSkinnedSRGTextFieldFeel
||-- {inherits SkinnedSRGTextFieldFeel}
||--
||-- {method public open {on-key-press ev:KeyPress}:void
||--
||-- {super.on-key-press ev}
||-- || ESC で View を閉じる・・・のはさすがに無理やりすぎて嫌だなぁ
||-- {if-non-null ui = self.ui-object asa #SkinnableTextFieldUI then
||-- {if-non-null cell = {get-grid-cell ui} then
||-- {switch ev.value
||-- case KeyPressValue.esc do
||--
||-- {if-non-null v = {cell.get-view} then
||-- {v.destroy}
||-- }
||-- }
||-- }
||-- }
||-- }
||--}
{define-class public CustomSRGTextFieldUI {inherits SRGSkinnableTextFieldUI}}
{do
{type-switch
the-default-look-and-feel.target-look-and-feel
case slaf:StyledLookAndFeel do
{slaf.register-control-feel
CustomSRGTextFieldUI,
CustomSkinnedSRGTextFieldFeel
}
}
}
{define-class public CustomCell {inherits StandardStringCell }
{constructor public {default}
{construct-super}
}
{method protected open {create-editor}:TextField
def tf = {super.create-editor}
set tf.ui-object = {CustomSRGTextFieldUI}
{return tf}
}
}
{def grid =
{RecordGrid
record-source =
{RecordSet
{RecordFields
{RecordField "a", nullable? = true}
}
,
{RecordData a = ""}
},
{RecordGridColumn "a" , cell-spec =CustomCell}
}
}
||View の FocusManager に、ESC キーで閉じるイベントを設定する
{define-proc {add-esc v:View}:void
{if-non-null fm = {v.get-focus-manager} then
def ka =
{KeyAccel
key-accel-string = "Esc",
{on Action do
{v.close}
}
}
{fm.add-key-accel
ka
}
}
}
{CommandButton
label = "RecordGried の View",
{on Action do
def v = {View grid}
{add-esc v}
{v.show}
}
}
{CommandButton
label = "TextField の View",
{on Action do
def v = {View {TextField }}
{add-esc v}
{v.show}
}
}