【问题标题】:Why Rebol engage doesn't work?为什么 Rebol 参与不起作用?
【发布时间】:2010-09-05 19:21:14
【问题描述】:

我添加了键盘事件,但没有检测到为什么?

plot: [
    pen green line 5x404 5x440 pen gold fill-pen 0.255.0 box 3x424 7x418 line 10x396 10x422 pen gold fill-pen 0.255.0 box 8x418 12x402 line 15x397 15x436 pen gold fill-pen 255.0.0 box 13x401 17x435 line 20x429 20x447 pen gold fill-pen 255.0.0 box 18x434 22x446 line 25x441 25x464 pen gold fill-pen 255.0.0 box 23x446 27x463 line 30x445 30x493 pen gold fill-pen 255.0.0 box 28x461 32x482 line 35x470 35x504 pen gold fill-pen 255.0.0 box 33x481 37x492 line 40x466 40x498 pen gold fill-pen 0.255.0 box 38x491 42x477
]

  grid: [1100 600]
  step-grid: 5
  max-n-points: (grid/1 / step-grid) - 1
  x-axis-border: 20
  Y-margin: 10
  X0: 5
  grid-color: coal


  main: layout [
      origin 20x0
      space 1x1
      panel1: box 1100x580 black effect reduce [
      'line-pattern 4 4
      'grid 30x30 0x0 (grid-color)
      'draw plot
      ] feel [
        engage: func [face action event] [
            if action = 'down [drag-start: event/offset]
            if action = 'up [drag-end: event/offset
                scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
            ]
            if action = 'key [
                probe event/key
                either word? event/key [
                    probe event/key
                    if (event/key = 'left) [
                        probe event/key
                    ]
                    if (event/key = 'right) [
                        probe event/key
                    ]
                ][

                ]
            ]
        ]
    ]
      panel2: box 1100x0 black
      panel3: box 1100x20 black
  ]

  view main
  focus panel1

【问题讨论】:

    标签: functional-programming rebol


    【解决方案1】:

    答:很简单,只有当面部是焦点时,才会触发关键事件。

    这是您的应用程序的部分重写(更快,也更易读),它使用全局事件处理程序和 'SWITCHes 而不是 'IFs。

    输入处理程序接收所有窗口的所有事件,并可用于执行全局技巧,如热键。

    显然,您可以改进事件处理程序以检测每个窗口,并检测鼠标所在的位置,以便仅在适当时启用键。您还可以构建一个替代的焦点跟踪,它在通常的处理之外工作并且不进入文本编辑模式。

    我在上面添加了一个字段,以便您可以试验激活聚焦面部的效果以及如何在事件处理程序中检测它。

    rebol []
    
    plot: []
    data: reduce [ ]
    
    refresh: func [/local clr delta prev-pos pos] [
        clear plot
        prev-pos: 0x300
        foreach [clr delta] data [
            pos: prev-pos + (delta * 0x1) + 7x0
            append plot compose [
                pen (clr) line (prev-pos) (pos) fill-pen (clr) pen none circle dot-size (pos) 
            ]
            prev-pos: pos
        ]
        show panel1
    ]
    add-data: func [i][loop i [append data reduce [(random white * .85) + (white * .15) (-20 + random 40)]] refresh]
    
    grid: [800 600]
    step-grid: 5
    max-n-points: (grid/1 / step-grid) - 1
    x-axis-border: 20
    Y-margin: 10
    X0: 5
    grid-color: coal
    dot-size: 1
    
    ; open up console before vid window
    prin "!"
    main: layout [
        origin 20x0
        space 1x1
        field 800
        panel1: box 800x580 black effect [
            line-pattern 4 4
            grid 30x30 0x0 grid-color
            draw plot
        ] feel [
            engage: func [face action event] [
                switch action [
                    down [
                        drag-start: event/offset
                    ]
                    up [
                        drag-end: event/offset
                        scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
                    ]
                ]
            ]
        ]
        panel2: box 800x0 black
        panel3: box 800x20 black
    ]
    
    insert-event-func [
        either all [
            event/type = 'key 
            none? system/view/focal-face
        ][
            print ["shortcut: " event/key]
            switch event/key [
                ; escape
                #"^[" [quit]
                ; enter/return
                #"^M" [print "resampling data" clear data add-data 100]
                up [dot-size: dot-size + 1 show panel1]
                down [dot-size: dot-size - 1 show panel1]
                left [clear skip tail plot -12 clear skip tail data -2 show panel1]
                right [add-data 2]
            ]
            none
        ][
            event
        ]
    ]
    add-data 100
    refresh
    view main
    focus panel1
    

    请注意,当您在其中使用单词时,无需减少代码块。 VID 会自动为您解析单词引用,一旦您知道这一点,制作动态 GUI 就会变得更容易(并且速度更快)。作为证明,按住向上或向下箭头键,您会看到点的大小调整非常流畅,即使在完整的图表上也是如此。

    还要注意 event-handler func 的返回值是事件,如果你想让视图继续处理事件,或者没有,如果你的处理程序“消耗”事件。

    HTH!

    【讨论】:

      【解决方案2】:

      我尝试使用 dummy func 和我自己的示例进行 insert-event-func,但我不明白为什么它不起作用:

      plot: [
          pen green line 5x404 5x440 pen gold fill-pen 0.255.0 box 3x424 7x418 line 10x396 10x422 pen gold fill-pen 0.255.0 box 8x418 12x402 line 15x397 15x436 pen gold fill-pen 255.0.0 box 13x401 17x435 line 20x429 20x447 pen gold fill-pen 255.0.0 box 18x434 22x446 line 25x441 25x464 pen gold fill-pen 255.0.0 box 23x446 27x463 line 30x445 30x493 pen gold fill-pen 255.0.0 box 28x461 32x482 line 35x470 35x504 pen gold fill-pen 255.0.0 box 33x481 37x492 line 40x466 40x498 pen gold fill-pen 0.255.0 box 38x491 42x477
      ]
      
        grid: [1100 600]
        step-grid: 5
        max-n-points: (grid/1 / step-grid) - 1
        x-axis-border: 20
        Y-margin: 10
        X0: 5
        grid-color: coal
      
      
        main: layout [
            origin 20x0
            space 1x1
            panel1: box 1100x580 black effect reduce [
            'line-pattern 4 4
            'grid 30x30 0x0 (grid-color)
            'draw plot
            ] feel [
              engage: func [face action event] [
                  if action = 'down [drag-start: event/offset]
                  if action = 'up [drag-end: event/offset
                      scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
                  ]
              ]
          ]
            panel2: box 1100x0 black
            panel3: box 1100x20 black
        ]
      
        insert-event-func [
            either all [
                event/type = 'key 
                none? system/view/focal-face
            ][
                print ["shortcut: " event/key]
                switch event/key [
                    ; escape
                    #"^[" [quit]
                    ; enter/return
                    #"^M" [print "resampling data" clear data add-data 100]
                    up [print "up"]
                    down [print "down"]
                    left [print "left"]
                    right [print "right"]
                ]
                none
            ][
                event
            ]
          ]
      
      
        view main
        focus panel1
      

      【讨论】:

      • 它对我有用,打印语句被转储到我的控制台窗口。不要忘记激活应用程序窗口。如果 rebol 控制台是活动窗口,它不会向应用程序发送关键事件,这允许您停止应用程序(在控制台中按 Escape)、调试它,甚至通过调用 do- 重新启动应用程序事件处理控制台中的事件。
      • 您的代码确实适用于我的电脑,但不适用于我的电脑,尽管我单击图表区域以确保它具有焦点。你真的试过我的吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多