2015-11-12 8 views
9

私は、クリックアンドドラッグ機能を備えたHaskellプログラムを作成しています。そのため、各マウス移動イベントで更新がウィンドウに描画されます。現時点では私が使用していますGtk2hsでカイロのアップデートを行う正しい方法は何ですか?

renderWithDrawable myCanvas update 

しかし、これは多くのちらつきです。私は、別のドロウアブル(「サーフェス」?)を作成してそれにレンダリングし、それをスクリーンウィンドウに1回の操作でblitする必要があると私は理解しています。しかし、私はこれを行う正しい方法について混乱しています。

私はdrawWindowBeginPaintRegionを見つけました。これは、ちらつきをなくすことについて話しています。 しかし、Gtk3で削除されたのはです。 Haddockドキュメントだから私はこれを使うべきかどうか分からない。それは非難されるようだ。

私はまた、カイロでrenderWithSimilarSurfaceを見つけました。これは、何か類似しているようです。

また、これらの機能がrenderWithDrawableにどのように関係しているかわかりません:その機能の中でそれらを使用する必要がありますか?

これを行う正しい方法は何ですか?

編集

これは、カイロで既知のものだそうです。私はHaskellでこれを処理する方法を理解しようとしています。

+0

最小限の自己完結型の例を投稿できますか? – Cactus

+0

@Cactus、簡単にはありません。フリッカー問題のデモでは、アニメーションやマウスイベントハンドラが何度か繰り返されて再描画が必要になるため、小さくならないでしょう。また、ちらつきの程度はプラットフォームによって異なるようです。代わりに私は他の言語での問題の議論へのポインタでポストを更新します。PixMapに描画し、それをスクリーンに描画することは、他の言語では標準的なようです。そのため、Haskellで標準的な方法があることを期待していました。 –

+2

'clip'関数を見たいかもしれません。それはあなたが必要なもの(あなたの場合、ドラッグされたオブジェクトの最初の矩形(古い位置)と新しい矩形(新しい位置))だけを再描画することができます。 – antoyo

答えて

4

これを行うための正しい方法は、すべての描画が公開するイベントの中から来ていることを確認するためのものであり、イベントが提供する描画ウィンドウ上で動作し。領域を「ダーティ」としてマークし、drawWindowInvalidateRect,drawWindowInvalidateRegion、またはwidgetQueueDrawを使用して合成エクスポーズイベントをトリガすることができます。

描画パイプラインを設定する簡単な例を次に示します。それは私が以前にサイドプロジェクトのために作った、ドラッグ&リリース操作でスムーズな動きでスタイルをパニングするGoogleマップのカスタムViewportタイプから抜粋されています。これをサポートするためには、マウスモーションイベントを再描画する必要があります。そのため、説明されている問題と同様のユースケースに対応しています。私は重要なビットを強調するために無関係のものを...と逃しました。今すぐ完全プロジェクトをアップロードして、Viewportの詳細を見るためにリポジトリを参照できます。 (これは、しかし年をされているので、bitrotの公平なビットは、おそらくあります - プロジェクトはちょうど構築し、現代GHCs /パッケージで実行するように期待しないでください。)

viewportNew :: Viewport -> IO DrawingArea 
viewportNew v = do 
    da <- drawingAreaNew 
    -- ... 
    on da exposeEvent $ exposeViewport posRef (draw v) 
    -- ... 

exposeViewport :: IORef Position -> RegionRenderer -> EventM EExpose Bool 
exposeViewport posRef draw = do 
    dw  <- eventWindow 
    region <- eventRegion >>= liftIO . regionGetRectangles 
    -- ... 
    liftIO . renderWithDrawable dw $ do 
     -- Cairo() action goes here 
     -- can reference region to decide which things to draw 
     draw region 
    return True -- see documentation of exposeEvent for what this means 

は、このテンプレートは、GTKの内蔵を活用する必要がありますダブルバッファリングで、gtkgtk3パッケージの両方で動作します。

+0

ありがとうございます。私は試してみましょう、それがうまくいくなら私はこれを受け入れたものとしてマークします。 –

関連する問題