2012-01-16 45 views
1

有时我必须实现像自定义拖动&拖放功能。代码可能是这样的:如何让鼠标事件处理更容易?

bool mouse_down = false; 
Vec2 mouse_pos; 
void on_mouse_down() { 
    mouse_down = true; 
    mouse_pos = cursor_pos(); 
} 
void on_mouse_move() { 
    if(mouse_down) { 
    Vec2f c = cursor_pos(); 
    Vec2f d = c - mouse_pos; 
    // dragging. make objects tracing the cursor. 
    // ... 
    } 
} 
void on_mouse_up() { 
    mouse_down = false; 
    // dropped 
    // ... 
} 

我知道这工作得很好,但我喜欢donnot冗余变量和这样的事情在所有的分离程序。在IP(命令式编程)中,这可能是不可避免的;我的问题是,有没有更好的方法来处理FP(函数式编程)中的这种事情?无论编程语言,Lisp,Scheme,F#,Ruby等,还是一些更好的方式在IP中执行此操作,都会赞赏任何想法和建议?

+0

什么多余的变量? – 2012-01-16 02:41:17

+0

上面的代码只是一个最简单的示例。如果我在整个系统中增加了更多的功能和限制,比如左,右,中间,轮子,双击,不同的操作,而光标移过不同的对象,变量账户将会爆炸...... – 2012-01-16 02:51:12

回答

1

由于没有人试图回答了一天,我给它一个镜头。我了解您正在讨论的问题,但答案应该取决于操作系统,语言和运行时库。

总的想法是,当鼠标出现故障,您激活一个异步计算。这个计算“阻塞”了事件,并在它自己的循环中处理它们,做你需要做的事情;它在鼠标按钮结束时存在。虽然这看起来它的工作原理是势在必行的线程,在现实中,当计算被“封杀”,它只是得到控制,它是从开始(主界面线程调用鼠标按下事件,大概)。以这种方式,状态被封装成看起来像是计算的词汇本地范围。这种魔法必须由语言的运行时间来处理,所以我们可以用语言和操作系统无关的方式得到答案。

至于这样的实现的例子,请检查this answerarticle by Tomas Petricek,两者都讨论你的问题,但在Windows,.NET和F#的狭窄设置。有一本由同一Perticek编写的书,Real World Functional Programming: With Examples in F# and C#,其中相同的想法在C#中令人惊讶地表达出来,通常不被视为功能语言。如果我的记忆服务于我,第十六章是你的。

至于在IP/OO语言程序封装的状态,您可以在MOUSE_DOWN处理程序创建一个类的实例。该实例将向运行时注册,以接收其他鼠标和UI事件,处理它们,完成所有工作,并在需要时(鼠标上移或窗口系统取消捕获模式),注销并自行销毁。不像函数式语言那么优雅,但在通用UI类中保持可变状态仍然更好。

+0

我会仔细阅读这些精彩的提示。谢谢! – 2012-01-17 17:12:33