870920 Menu

JUCE复合控件之DragAndDropContainer

ComponentDragger可实现以鼠标拖拽的方式改变某个组件或其子组件的定位(手工移动)。该类比较简单,如要实现更复杂的拖放操作,比如:程序内部的自定义组件的拖放、操作系统的文件拖放到本程序,外部程序中的文本拖放到本程序等等,这些情况下,需用到:DragAndDropContainer拖放容器、DragAndDropTarget拖放目标、FileDragAndDropTarget文件拖放目标和TextDragAndDropTarget文本拖放目标这几个类。

实现上述拖放操作的关键有四点

  1. 要让某个内容组件所容纳并显示的所有子组件均具有可拖放属性,并且本身也可以接受并处理拖放事件,则该内容组件类需继承DragAndDropContainer。换句话说,内容组件此时成为拖放容器,它容纳并显示拖放源子组件和拖放目标子组件,并且能够产生和接收任何拖放事件。
  2. 被拖拽的来源组件能够产生目标组件所需的文本描述。目标组件需基于该描述进行判断处理。
  3. 要接收拖拽源的目标组件,需继承上述几个拖放目标类,实现其纯虚函数并重写必要的虚函数。
  4. 目标组件类的对象由内容组件声明并管理之。即:拖放目标组件是内容组件所容纳并显示的子组件。

先了解DragAndDropTarget拖放目标类。该类为抽象基类,有两个纯虚函数需实现:
 isInterestedInDragSource () 判断本类是否对拖放到此的东西感兴趣
 itemDropped () 当某些东西拖放到此后,自动调用该函数

该类其它几个很重要的成员函数,派生类可重写:
 itemDragEnter () 某些东西拖放到此组件时,自动调用此函数
 itemDragMove () 鼠标正拖拽某些东西,并在该组件内移动时,自动调用此函数
 itemDragExit () 鼠标正拖拽某些东西,并移动到组件之外时,自动调用此函数
 shouldDrawDragImageWhenOver () 是否通知拖放容器绘制拖放对象的图像

DragAndDropTarget有一个嵌套类SourceDetails,该类的public属性用于保存DragAndDropContainer类所产生的消息的对应描述,比如:本次拖放的文本描述、来源组件、鼠标位置。这些数据被DragAndDropTarget类的多个函数所使用(DragAndDropTarget::SourceDetails的对象将作为这些函数的引用型参数),作为判断和处理的依据与来源。无需显式创建该类的对象,系统内部会自动创建并为其赋值。

DragAndDropContainer和DragAndDropTarget均为独立的类,这两个类派生类有:

DragAndDropContainerDragAndDropTarget

图 4 11 DragAndDropContainer和DragAndDropTarget的派生层次

DragAndDropContainer类的成员函数与静态函数:(网站发布,略)

示例代码(4个基本步骤):略。

采用上述思路和流程,可以满足绝大多数情况下GUI组件拖放方面的需求。如果只是拖放操作系统的文件到内容组件中,则无需继承拖放容器类,但必须继承FileDragAndDropTarget文件拖放目标类,实现并重写其虚函数。该类的派生层次为:

FileDragAndDropTarget

图 4 12 FileDragAndDropTarget的派生图示

FileDragAndDropTarget的成员函数:略。

综合示例:略

以上综合演示了DragAndDropTarget、FileDragAndDropTarget和TextDragAndDropTarget这3个拖放目标类的使用步骤与完整编码。这3个类均为抽象基类,无父类,各自独立,彼此之间并无瓜葛,既没有派生与继承的关系,也没有组合与聚合的关系。