2009-07-23 2 views
1

Linux(GTK)とOSXで透明なウィンドウ(アルファチャンネル付き)を描きたい。それを行うためのAPIはありますか?グローバルな透明度を設定したくないことに注意してください。アルファレベルはピクセルごとに設定する必要があります。GTKとOSXでピクセル単位のAlpha Blendを実行するAPIはありますか?

私はこの例のように、WindowsのUpdateLayeredWindow関数と同じ種類のAPIを探しています:Per Pixel Alpha Blend

答えて

2

Mac OS Xの場合は、 RoundTransparentWindowサンプルコードを参照してください。これは、完全に透明なカスタムウィンドウを使用し、その中に図形を描画することによって機能します。この例では、硬いエッジ+全体的なアルファを持つシェイプのみを使用していますが、任意のアルファを使用できます。

この例ではカスタムウィンドウを使用していますが、同じテクニックを使用して、通常のウィンドウで穴をパンチするには、setOpaque:NOを呼び出します。 Hackyの例:

@implementation ClearView 

- (void)drawRect:(NSRect)rect 
{ 
    if (mask == nil) mask = [[NSImage imageNamed:@"mask"] retain]; 
    [self.window setOpaque:NO]; 
    [mask drawInRect:self.bounds 
      fromRect:(NSRect){{0, 0},mask.size} 
      operation:NSCompositeCopy 
      fraction:1.0]; 
} 

@end 

この手法の主な制限は、標準的なドロップシャドウはアルファブレンディングエッジとはあまりうまく相互作用しないということです。

1

このコードは今年の前半から私の実験フォルダに見つかりました。私はこれのどれくらいを書いているのか、インターネットの他の場所の例をどれだけ参考にしているのかを覚えていません。

この例では、完全に不透明なGTK +ボタンを中心に部分的に透明な青色のウィンドウが表示されます。たとえば、アルファブレンドPNGをウィンドウのどこかに描画すると、正しく合成されます。うまくいけば、これはあなたを正しい軌道に乗せるでしょう。

次でそれをコンパイルします。

$ gcc `pkg-config --cflags --libs gtk+-2.0` -o per-pixel-opacity per-pixel-opacity.c 

を今すぐコードを:

#include <gtk/gtk.h> 

static gboolean on_window_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) 
{ 
    cairo_t *cr; 
    cr = gdk_cairo_create(widget->window); // create cairo context 

    cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 0.2); 
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // set drawing compositing operator 
                // SOURCE -> replace destination 
    cairo_paint(cr); // paint source 

    cairo_destroy(cr); 

    return FALSE; 
} 

gint main(gint argc, gchar **argv) 
{ 
    GtkWidget *window, *button, *vbox; 
    GdkScreen *screen; 
    GdkColormap *colormap; 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL); 
    g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_window_expose_event), NULL); 

    gtk_window_set_decorated(GTK_WINDOW(window), FALSE); 
    gtk_container_set_border_width(GTK_CONTAINER(window), 20); 

    gtk_widget_set_app_paintable(window, TRUE); 

    screen = gtk_widget_get_screen(window); 
    colormap = gdk_screen_get_rgba_colormap(screen); 
    gtk_widget_set_colormap(window, colormap); 

    button = gtk_button_new(); 
    gtk_button_set_label(GTK_BUTTON(button), "Don't Press!"); 

    gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(button)); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 
関連する問題