| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // Copyright 2025 The tk9.0-go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package tk9_0 // import "modernc.org/tk9.0"
- import (
- "errors"
- "fmt"
- )
- // OperationCallback is the signature for a WidgetProxy operation callback.
- type OperationCallback func(args []string)
- // widgetProxy wraps a widget window, providing the means to intercept its
- // internal operations, and modify their behaviour.
- // For example, it can provide access to a TextWidget's internal 'insert' and
- // 'delete' operations.
- type widgetProxy struct {
- window *Window
- originalPath string
- commandName uintptr
- operations map[string]OperationCallback
- }
- // newWidgetProxy creates a proxy that facilitates hooking in to
- // a widget window's internal operations.
- func newWidgetProxy(window *Window) widgetProxy {
- if !extensionInitialized("eval") {
- fail(errors.New("use of WidgetProxy requires the 'eval' extension to be enabled, but it is not"))
- }
- proxy := widgetProxy{
- window: window,
- originalPath: window.String() + "_original",
- operations: make(map[string]OperationCallback),
- }
- // Rename the Tcl command within Tcl:
- evalErr(fmt.Sprintf("rename %s %s", window, proxy.originalPath))
- // Register an event dispatcher for the window.
- proxy.registerEventDispatcher()
- return proxy
- }
- // Close undoes the wrapping of its Window.
- // All registered operations are unregistered.
- func (proxy *widgetProxy) Close() {
- // Unregister all registered operations.
- for operation := range proxy.operations {
- proxy.Unregister(operation)
- }
- // Restore the original widget Tcl command.
- proxy.unregisterEventDispatcher()
- // Restore the Tcl command within Tcl:
- evalErr(fmt.Sprintf("rename %s %s", proxy.originalPath, proxy.window))
- }
- // Register registers a callback for an operation supported by the wrapped Window.
- //
- // The operation name is widget-specific. It is not possible to validate whether
- // the operation name is support by the wrapped widget. If an unsupported
- // operation name is used it will be silently ignored.
- //
- // The operation's arguments are passed to the callback. The callback may perform
- // the operation on the wrapped widget by calling the EvalWrapped method with the
- // arguments. The arguments may be modified if desired.
- func (proxy *widgetProxy) Register(operation string, callback OperationCallback) {
- proxy.operations[operation] = callback
- }
- // Unregister unregisters an operation callback.
- // If there is no registered callback for the operation, it is silently ignored.
- func (proxy *widgetProxy) Unregister(operation string) {
- delete(proxy.operations, operation)
- }
- // EvalWrapped evaluates the arguments as a raw Tcl string against the wrapped Window.
- func (proxy *widgetProxy) EvalWrapped(args []string) {
- evalErr(fmt.Sprintf("%s %s", proxy.originalPath, tclSafeStrings(args...)))
- }
- // TextWidgetProxy wraps a TextWidget.
- // It provides the ability to intercept the widget's internal operations (such as
- // 'insert' and 'delete'), and modify their behaviour.
- type TextWidgetProxy struct {
- *TextWidget
- widgetProxy
- }
- // NewTextWidgetProxy creates a TextWidgetProxy, wrapping the
- // provided TextWidget.
- //
- // Note that because the EvalWrapped method evaluates raw Tcl, the "eval" extension
- // must be enabled in the main package before calling this function.
- func NewTextWidgetProxy(widget *TextWidget) TextWidgetProxy {
- return TextWidgetProxy{
- TextWidget: widget,
- widgetProxy: newWidgetProxy(widget.Window),
- }
- }
|