はじめに
Curlは、ドラッグ&ドロップといった操作性を向上させる機能を簡単に実装できます。また、アプレットに特権を与えることによって、ローカルにあるファイルの読み書きすることもできます。Win32APIを直接呼ぶことも可能です。
ポータル・スケジューラーでは、このような特徴を使って操作性が良くなるようにしています。今回は、開発するにあたり工夫した点を紹介します。
ドラッグ&ドロップ
ドラッグ&ドロップの実装は簡単に行えます。イベントは、
- DragEnter(ターゲットに入ったときに発生)
- DragLeave(ターゲットの外に出たとき発生)
- DragOver(ターゲットにドラッグされたときに発生)
- Drop(ターゲットにドロップされたときに発生)
があります。
{HBox spacing = 100pt, valign = "center", {EllipseGraphic width = 1cm, height = 1cm, dragee = {ImageDragee}}, {Frame width = 40pt, height = 40pt, background = "red", {on e:DragOver do {e.will-accept-drop? {proc {type:Type, x:Distance, y:Distance, effect:#DragEffect}:DragEffect {return drag-effect-copy} } } }, {on e:Drop do {e.accept-drop {proc {a:any, x:Distance, y:Distance, effect:#DragEffect}:DropResult {return {DropResultCopy action = {proc {}:void {popup-message "ドロップされた"} } } } } } } } }
このドラッグ&ドロップ機能を活用して、以下のような機能を実装しています。
予定のドラッグ&ドロップ
予定をドラッグ&ドロップすることでコピー・移動が簡単に行えるようにしました。
エクスプローラからのドロップ
ランチャには、アプリケーション・ファイル・フォルダのショートカットを登録できます。登録する際には、デスクトップ・エクスプローラからのドロップからも行えるようにしました。
ファイルをダウンロードして開く
ファイル集や予定には、ファイルを添付できます。添付したファイルは、サーバにそのまま保存しています。画面上ではアイコンで表示され、ダブルクリックするとサーバからローカルにダウンロードし、関連付いたアプリケーションで実行されます。例えば、*.xlsの場合はExcelが起動することになります。
ファイルを関連付けされているアプリケーションで開くのは、Win32APIのShellExecuteを使って実現しました。
{define-dll-class public Win32API_ShellExecute {defaults calling-convention = stdcall, string-rep = CStringUTF16 } let public constant HIDE: int = 0 let public constant SHOWNORMAL: int = 1 let public constant NORMAL: int = 1 let public constant SHOWMINIMIZED: int = 2 let public constant SHOWMAXIMIZED: int = 3 let public constant MAXIMIZE: int = 3 let public constant SHOWNOACTIVATE: int = 4 let public constant SHOW: int = 5 let public constant MINIMIZE: int = 6 let public constant SHOWMINNOACTIVE: int = 7 let public constant SHOWNA: int = 8 let public constant RESTORE: int = 9 let public constant SHOWDEFAULT: int = 10 let public constant MAX: int = 10 {constructor public {default} {construct-super {SharedLibrary "shell32"} } } {dll-method public {executeA ("ShellExecuteA") hwnd: CPointer, op: StringInterface (rep = CString), file: StringInterface (rep = CString), params: StringInterface (rep = CString), dir: StringInterface (rep = CString), cmd: int }: int } {dll-method public {execute ("ShellExecuteW") hwnd: CPointer, op: StringInterface, file: StringInterface, params: StringInterface, dir: StringInterface, cmd: int }: int {if-missing {return {self.executeA hwnd, op, file, params, dir, cmd} } } } }