OSDN Git Service

LinGui: create custom widget that manages multiple overlay layers
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 8 Apr 2009 17:26:10 +0000 (17:26 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Wed, 8 Apr 2009 17:26:10 +0000 (17:26 +0000)
composites the layers using per-pixel and global alpha values
the preview hud now uses this.

git-svn-id: svn://localhost/HandBrake/trunk@2312 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/Makefile.am
gtk/src/composite_example.c [new file with mode: 0644]
gtk/src/ghb.ui
gtk/src/ghbcompositor.c [new file with mode: 0644]
gtk/src/ghbcompositor.h [new file with mode: 0644]
gtk/src/main.c
gtk/src/preview.c

index 04cebe2..8abcc6f 100644 (file)
@@ -110,6 +110,8 @@ ghb_SOURCES = \
        renderer_button.c \
        ghbcellrenderertext.c \
        ghbcellrenderertext.h \
+    ghbcompositor.c \
+    ghbcompositor.h \
        ghb-dvd.c \
        ghb-dvd.h \
        marshalers.c \
diff --git a/gtk/src/composite_example.c b/gtk/src/composite_example.c
new file mode 100644 (file)
index 0000000..7918b30
--- /dev/null
@@ -0,0 +1,78 @@
+#include <gtk/gtk.h>
+#include "ghbcompositor.h"
+
+// GhbCompositor example
+int
+main(gint argc, gchar *argv[])
+{
+    GtkWidget *window;
+    GtkWidget *blender;
+    GtkWidget *eb_bottom;
+    GtkWidget *eb_top1;
+    GtkWidget *eb_top2;
+    GtkWidget *eb_top3;
+    GtkWidget *bottom;
+    GtkWidget *top1;
+    GtkWidget *top2;
+    GtkWidget *top3;
+    GtkWidget *table;
+    GtkWidget *image;
+
+    gtk_init(&argc, &argv);
+
+    // Make the top level window
+    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+    // Only widgets that have a GdkDrawing area can be composited
+    // These would be GtkEventBox or GtkDrawingArea
+    // Create the widgets that will be composited
+    eb_bottom = gtk_event_box_new();
+    eb_top1 = gtk_event_box_new();
+    eb_top2 = gtk_event_box_new();
+    eb_top3 = gtk_event_box_new();
+
+    // Create the compositor
+    blender = ghb_compositor_new();
+
+    // Create an button to put on the bottom layer
+    bottom = gtk_button_new_with_label("Bottom");
+    image = gtk_image_new_from_stock("gtk-help", 6);
+    gtk_button_set_image(GTK_BUTTON(bottom), image);
+
+    // The button must be placed inside an event box since
+    // buttons do not have their own window.
+    gtk_container_add(GTK_CONTAINER(eb_bottom), bottom);
+
+    // Create the buttons that will be visible on the top layer
+    top1 = gtk_button_new_with_label("Top 1");
+    top2 = gtk_button_new_with_label("Top 2");
+    top3 = gtk_button_new_with_label("Top 3");
+
+    // The buttons must be placed inside an event box since
+    // buttons do not have their own window.
+    gtk_container_add(GTK_CONTAINER(eb_top1), top1);
+    gtk_container_add(GTK_CONTAINER(eb_top2), top2);
+    gtk_container_add(GTK_CONTAINER(eb_top3), top3);
+
+    // Create the table that will be the top layer
+    // Using a layout widget gives flexibility in the layout of the layer
+    table = gtk_table_new(3, 3, TRUE);
+    gtk_table_attach(GTK_TABLE(table), eb_top1, 0, 1, 0, 1, 0, 0, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), eb_top2, 1, 2, 1, 2, 0, 0, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), eb_top3, 2, 3, 2, 3, 0, 0, 0, 0);
+
+    // Add the blender to the main window.
+    gtk_container_add(GTK_CONTAINER(window), blender);
+
+    // Set the blenders zlist, with opacity values
+    // Bottom layer is opaque, top layer 60%
+    ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), eb_bottom, 1, 1);
+    ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), table, 2, 0.6);
+
+    // Start the show
+    gtk_widget_show_all(window);
+
+    gtk_main();
+    return 0;
+}
+
index ccee23c..937c877 100644 (file)
@@ -4851,240 +4851,228 @@ location as the movie.</property>
     </child>
   </object>
 
-  <object class="GtkWindow" id="preview_window">
-    <property name="title" translatable="yes">Preview</property>
-    <property name="window_position">GTK_WIN_POS_CENTER</property>
-    <property name="skip_taskbar_hint">True</property>
-    <property name="skip_pager_hint">True</property>
-    <property name="resizable">False</property>
-    <property name="events">GDK_STRUCTURE_MASK | GDK_POINTER_MOTION_MASK</property>
-    <signal handler="preview_configure_cb" name="configure-event"/>
-    <signal handler="preview_window_delete_cb" name="delete_event"/>
+  <object class="GtkDrawingArea" id="preview_image">
+    <property name="visible">True</property>
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK</property>
+    <property name="app_paintable">True</property>
+    <signal name="motion-notify-event" handler="preview_motion_cb"/>
+    <signal name="leave-notify-event" handler="preview_leave_cb"/>
+  </object>
+
+  <object class="GtkAlignment" id="preview_hud">
+    <property name="visible">False</property>
+    <property name="xalign">.5</property>
+    <property name="yalign">.9</property>
+    <property name="xscale">0</property>
+    <property name="yscale">0</property>
     <child>
-      <object class="GtkAlignment" id="alignment111">
+      <object class="GtkEventBox" id="preview_event_box">
         <property name="visible">True</property>
-        <property name="xalign">.5</property>
-        <property name="yalign">.5</property>
-        <property name="xscale">0</property>
-        <property name="yscale">0</property>
+        <property name="width-request">500</property>
+        <property name="app-paintable">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
+        <signal name="enter-notify-event" handler="hud_enter_cb"/>
         <child>
-          <object class="GtkTable" id="table111">
+          <object class="GtkAlignment" id="alignment53">
             <property name="visible">True</property>
-            <property name="n_rows">1</property>
-            <property name="n_columns">1</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="left_padding">10</property>
+            <property name="right_padding">10</property>
+            <property name="top_padding">5</property>
+            <property name="bottom_padding">5</property>
             <child>
-              <object class="GtkDrawingArea" id="preview_image">
+              <object class="GtkVBox" id="vbox35">
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK</property>
-                <property name="app_paintable">True</property>
-                <signal name="motion-notify-event" handler="preview_motion_cb"/>
-                <signal name="leave-notify-event" handler="preview_leave_cb"/>
-              </object>
-              <packing>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkAlignment" id="preview_hud">
-                <property name="visible">False</property>
-                <property name="xalign">.5</property>
-                <property name="yalign">.9</property>
-                <property name="xscale">0</property>
-                <property name="yscale">0</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <child>
-                  <object class="GtkEventBox" id="preview_event_box">
+                  <object class="GtkHScale" id="preview_frame">
                     <property name="visible">True</property>
-                    <property name="width-request">500</property>
-                    <property name="app-paintable">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
-                    <signal name="enter-notify-event" handler="hud_enter_cb"/>
+                    <property name="can_focus">True</property>
+                    <property name="adjustment">adjustment19</property>
+                    <property name="digits">0</property>
+                    <property name="value_pos">bottom</property>
+                    <signal name="value_changed" handler="preview_frame_value_changed_cb"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox70">
+                    <property name="visible">True</property>
+                    <property name="spacing">5</property>
                     <child>
-                      <object class="GtkAlignment" id="alignment53">
+                      <object class="GtkButton" id="live_preview_play">
+                        <property name="height_request">30</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="relief">none</property>
+                        <signal name="clicked" handler="live_preview_start_cb"/>
+                        <child>
+                          <object class="GtkImage" id="live_preview_play_image">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-media-play</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkHScale" id="live_preview_progress">
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">preview_progress_adj</property>
+                        <property name="draw_value">False</property>
+                        <property name="value_pos">right</property>
+                        <signal name="value_changed" handler="live_preview_seek_cb"/>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkVBox" id="live_progress_box">
                         <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="left_padding">10</property>
-                        <property name="right_padding">10</property>
-                        <property name="top_padding">5</property>
-                        <property name="bottom_padding">5</property>
                         <child>
-                          <object class="GtkVBox" id="vbox35">
+                          <object class="GtkLabel" id="label71">
+                            <property name="height_request">1</property>
+                            <property name="visible">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkProgressBar" id="live_encode_progress">
+                            <property name="height_request">16</property>
                             <property name="visible">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <child>
-                              <object class="GtkHScale" id="preview_frame">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="adjustment">adjustment19</property>
-                                <property name="digits">0</property>
-                                <property name="value_pos">bottom</property>
-                                <signal name="value_changed" handler="preview_frame_value_changed_cb"/>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkHBox" id="hbox70">
-                                <property name="visible">True</property>
-                                <property name="spacing">5</property>
-                                <child>
-                                  <object class="GtkButton" id="live_preview_play">
-                                    <property name="height_request">30</property>
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">True</property>
-                                    <property name="relief">none</property>
-                                    <signal name="clicked" handler="live_preview_start_cb"/>
-                                    <child>
-                                      <object class="GtkImage" id="live_preview_play_image">
-                                        <property name="visible">True</property>
-                                        <property name="stock">gtk-media-play</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkHScale" id="live_preview_progress">
-                                    <property name="can_focus">True</property>
-                                    <property name="adjustment">preview_progress_adj</property>
-                                    <property name="draw_value">False</property>
-                                    <property name="value_pos">right</property>
-                                    <signal name="value_changed" handler="live_preview_seek_cb"/>
-                                  </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkVBox" id="live_progress_box">
-                                    <property name="visible">True</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label71">
-                                        <property name="height_request">1</property>
-                                        <property name="visible">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkProgressBar" id="live_encode_progress">
-                                        <property name="height_request">16</property>
-                                        <property name="visible">True</property>
-                                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkLabel" id="label72">
-                                        <property name="height_request">1</property>
-                                        <property name="visible">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="position">2</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkHBox" id="hbox26">
-                                <property name="visible">True</property>
-                                <property name="spacing">10</property>
-                                <child>
-                                  <object class="GtkHBox" id="hbox60">
-                                    <property name="visible">True</property>
-                                    <property name="spacing">2</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label37">
-                                        <property name="visible">True</property>
-                                        <property name="label" translatable="yes">&lt;b&gt;Duration:&lt;/b&gt;</property>
-                                        <property name="use_markup">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkSpinButton" id="live_duration">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                        <property name="adjustment">adjustment21</property>
-                                        <property name="numeric">True</property>
-                                        <signal name="value_changed" handler="preview_duration_changed_cb"/>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkToggleButton" id="preview_fullscreen">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="tooltip-text" translatable="yes">View Fullscreen Preview</property>
-                                    <property name="label" translatable="yes">Fullscreen</property>
-                                    <signal handler="fullscreen_clicked_cb" name="clicked"/>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="settings_button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="tooltip-text" translatable="yes">Open Picture Settings</property>
-                                    <property name="label" translatable="yes">Settings</property>
-                                    <signal handler="picture_settings_alt2_clicked_cb" name="clicked"/>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label72">
+                            <property name="height_request">1</property>
+                            <property name="visible">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
                         </child>
                       </object>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
                     </child>
                   </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox26">
+                    <property name="visible">True</property>
+                    <property name="spacing">10</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox60">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkLabel" id="label37">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Duration:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSpinButton" id="live_duration">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="adjustment">adjustment21</property>
+                            <property name="numeric">True</property>
+                            <signal name="value_changed" handler="preview_duration_changed_cb"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkToggleButton" id="preview_fullscreen">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="tooltip-text" translatable="yes">View Fullscreen Preview</property>
+                        <property name="label" translatable="yes">Fullscreen</property>
+                        <signal handler="fullscreen_clicked_cb" name="clicked"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="settings_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="tooltip-text" translatable="yes">Open Picture Settings</property>
+                        <property name="label" translatable="yes">Settings</property>
+                        <signal handler="picture_settings_alt2_clicked_cb" name="clicked"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">2</property>
+                  </packing>
                 </child>
               </object>
-              <packing>
-              </packing>
             </child>
           </object>
         </child>
       </object>
     </child>
   </object>
+
+  <object class="GtkWindow" id="preview_window">
+    <property name="title" translatable="yes">Preview</property>
+    <property name="window_position">GTK_WIN_POS_CENTER</property>
+    <property name="skip_taskbar_hint">True</property>
+    <property name="skip_pager_hint">True</property>
+    <property name="resizable">False</property>
+    <property name="events">GDK_STRUCTURE_MASK | GDK_POINTER_MOTION_MASK</property>
+    <signal handler="preview_configure_cb" name="configure-event"/>
+    <signal handler="preview_window_delete_cb" name="delete_event"/>
+    <child>
+      <object class="GtkAlignment" id="preview_window_alignment">
+        <property name="visible">True</property>
+        <property name="xalign">.5</property>
+        <property name="yalign">.5</property>
+        <property name="xscale">0</property>
+        <property name="yscale">0</property>
+      </object>
+    </child>
+  </object>
+
   <object class="GtkAboutDialog" id="hb_about">
     <property name="border_width">5</property>
     <property name="title" translatable="yes">About HandBrake</property>
diff --git a/gtk/src/ghbcompositor.c b/gtk/src/ghbcompositor.c
new file mode 100644 (file)
index 0000000..eec5c09
--- /dev/null
@@ -0,0 +1,657 @@
+/* "Borrowed" from: */
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkprivate.h>
+#include <gtk/gtkmarshal.h>
+#include "ghbcompositor.h"
+
+#ifdef ENABLE_NLS
+#define P_(String) g_dgettext(GETTEXT_PACKAGE "-properties",String)
+#else
+#define P_(String) (String)
+#endif
+
+enum {
+    PROP_0,
+};
+
+enum {
+    CHILD_PROP_0,
+    CHILD_PROP_Z_POS,
+    CHILD_PROP_OPACITY
+};
+
+#define GHB_COMPOSITOR_GET_PRIVATE(obj)  G_TYPE_INSTANCE_GET_PRIVATE((obj), GHB_TYPE_COMPOSITOR, GhbCompositorPrivate)
+
+static void     ghb_compositor_finalize      (GObject        *object);
+static void     ghb_compositor_realize       (GtkWidget      *widget);
+static void     ghb_compositor_unrealize     (GtkWidget      *widget);
+static void     ghb_compositor_size_request  (GtkWidget      *widget,
+                                             GtkRequisition  *requisition);
+static void     ghb_compositor_size_allocate (GtkWidget      *widget,
+                                             GtkAllocation   *allocation);
+static gboolean ghb_compositor_expose        (GtkWidget      *widget,
+                                             GdkEventExpose  *event);
+static void     ghb_compositor_set_property  (GObject        *object,
+                                             guint            prop_id,
+                                             const GValue    *value,
+                                             GParamSpec      *pspec);
+static void     ghb_compositor_get_property  (GObject        *object,
+                                             guint            prop_id,
+                                             GValue          *value,
+                                             GParamSpec      *pspec);
+static void     ghb_compositor_add          (GtkContainer    *container,
+                                             GtkWidget       *widget);
+static void     ghb_compositor_remove       (GtkContainer    *container,
+                                             GtkWidget       *widget);
+static void     ghb_compositor_forall       (GtkContainer    *container,
+                                             gboolean         include_internals,
+                                             GtkCallback      callback,
+                                             gpointer         data);
+static GType    ghb_compositor_child_type   (GtkContainer    *container);
+static void     ghb_compositor_set_child_property  (GtkContainer *container,
+                                             GtkWidget       *child,
+                                             guint            prop_id,
+                                             const GValue    *value,
+                                             GParamSpec      *pspec);
+static void     ghb_compositor_get_child_property  (GtkContainer *container,
+                                             GtkWidget       *child,
+                                             guint            prop_id,
+                                             GValue          *value,
+                                             GParamSpec      *pspec);
+
+G_DEFINE_TYPE (GhbCompositor, ghb_compositor, GTK_TYPE_BIN)
+
+static void
+ghb_compositor_class_init (GhbCompositorClass *class)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+    GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
+
+    gobject_class->finalize = ghb_compositor_finalize;
+
+    gobject_class->set_property = ghb_compositor_set_property;
+    gobject_class->get_property = ghb_compositor_get_property;
+
+    widget_class->size_request = ghb_compositor_size_request;
+    widget_class->size_allocate = ghb_compositor_size_allocate;
+
+    widget_class->realize = ghb_compositor_realize;
+    widget_class->unrealize = ghb_compositor_unrealize;
+
+    widget_class->expose_event = ghb_compositor_expose;
+
+    container_class->add = ghb_compositor_add;
+    container_class->remove = ghb_compositor_remove;
+    container_class->forall = ghb_compositor_forall;
+    container_class->child_type = ghb_compositor_child_type;
+    container_class->set_child_property = ghb_compositor_set_child_property;
+    container_class->get_child_property = ghb_compositor_get_child_property;
+
+    gtk_container_class_install_child_property (container_class,
+                        CHILD_PROP_Z_POS,
+                        g_param_spec_uint ("z-pos",
+                            P_("Position in Z-List"),
+                            P_("Sets the blending order of the child."),
+                            0, 65535, 0,
+                            GTK_PARAM_READWRITE));
+
+    gtk_container_class_install_child_property (container_class,
+                        CHILD_PROP_OPACITY,
+                        g_param_spec_double ("opacity",
+                            P_("Opacity"),
+                            P_("Sets the opacity of the child."),
+                            0.0, 1.0, 1.0,
+                            GTK_PARAM_READWRITE));
+
+}
+
+static GType
+ghb_compositor_child_type(GtkContainer *container)
+{
+    return GTK_TYPE_WIDGET;
+}
+
+static void 
+ghb_compositor_get_property (
+    GObject    *object,
+    guint       prop_id,
+    GValue     *value,
+    GParamSpec *pspec)
+{
+    GhbCompositor *compositor;
+
+    compositor = GHB_COMPOSITOR (object);
+
+    switch (prop_id)
+    {
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void 
+ghb_compositor_set_property (
+    GObject      *object,
+    guint         prop_id,
+    const GValue *value,
+    GParamSpec   *pspec)
+{
+    GhbCompositor *compositor;
+
+    compositor = GHB_COMPOSITOR (object);
+
+    switch (prop_id)
+    {
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static gint
+zsort(gconstpointer a, gconstpointer b)
+{
+    GhbCompositorChild *cca, *ccb;
+
+    cca = (GhbCompositorChild*)a;
+    ccb = (GhbCompositorChild*)b;
+
+    return (cca->z_pos - ccb->z_pos);
+}
+
+static void 
+ghb_compositor_set_child_property(
+    GtkContainer *container,
+    GtkWidget    *child,
+    guint         prop_id,
+    const GValue *value,
+    GParamSpec   *pspec)
+{
+    GhbCompositor *compositor;
+    GhbCompositorChild *cc;
+    GList *link;
+
+    compositor = GHB_COMPOSITOR(container);
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        if (cc->widget == child)
+            break;
+    }
+    if (link == NULL)
+    {
+        GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(container, prop_id, pspec);
+        return;
+    }
+
+    switch (prop_id)
+    {
+    case CHILD_PROP_Z_POS:
+    {
+        cc->z_pos = g_value_get_uint(value);
+        compositor->children = g_list_sort(compositor->children, zsort);
+    } break;
+    case CHILD_PROP_OPACITY:
+    {
+        cc->opacity = g_value_get_double(value);
+    } break;
+    default:
+        GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(container, prop_id, pspec);
+        break;
+    }
+
+    if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (compositor))
+        gtk_widget_queue_resize (child);
+
+}
+
+static void 
+ghb_compositor_get_child_property(
+    GtkContainer *container,
+    GtkWidget    *child,
+    guint         prop_id,
+    GValue       *value,
+    GParamSpec   *pspec)
+{
+    GhbCompositor *compositor;
+    GhbCompositorChild *cc;
+    GList *link;
+
+    compositor = GHB_COMPOSITOR(container);
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        if (cc->widget == child)
+            break;
+    }
+    if (link == NULL)
+    {
+        GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(container, prop_id, pspec);
+        return;
+    }
+
+    switch (prop_id)
+    {
+    case CHILD_PROP_Z_POS:
+    {
+        g_value_set_uint(value, cc->z_pos);
+    } break;
+    case CHILD_PROP_OPACITY:
+    {
+        g_value_set_double(value, cc->opacity);
+    } break;
+    default:
+        GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(container, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+ghb_compositor_init (GhbCompositor *compositor)
+{
+    GTK_WIDGET_UNSET_FLAGS (compositor, GTK_NO_WINDOW);
+}
+
+GtkWidget*
+ghb_compositor_new (void)
+{
+    return GTK_WIDGET(g_object_new (GHB_TYPE_COMPOSITOR, NULL));
+}
+
+#if 0
+static void
+showtype(const gchar *msg, GtkWidget *widget)
+{
+       GType type;
+       gchar *str;
+
+       type = GTK_WIDGET_TYPE(widget);
+       if (type == GTK_TYPE_DRAWING_AREA)
+               str = "drawing area";
+       else if (type == GTK_TYPE_ALIGNMENT)
+               str = "alignment";
+       else if (type == GTK_TYPE_EVENT_BOX)
+               str = "event box";
+       else if (type == GTK_TYPE_EVENT_BOX)
+               str = "event box";
+       else
+               str = "unknown";
+       g_message("%s: %s", msg, str);
+}
+#endif
+
+static GList*
+find_drawables(GList *drawables, GtkWidget *widget)
+{
+    if (!GTK_WIDGET_NO_WINDOW(widget))
+    {
+        drawables = g_list_append(drawables, widget);
+        return drawables;
+    }
+    if (GTK_IS_CONTAINER(widget))
+    {
+        GList *children, *link;
+
+        children = gtk_container_get_children(GTK_CONTAINER(widget));
+        // Look for a child with a window
+        for (link = children; link != NULL; link = link->next)
+        {
+            if (!GTK_WIDGET_NO_WINDOW(GTK_WIDGET(link->data)))
+            {
+                drawables = g_list_append(drawables, link->data);
+            }
+            else
+            {
+                drawables = find_drawables(drawables, GTK_WIDGET(link->data));
+            }
+        }
+    }
+    return drawables;
+}
+
+/**
+ * ghb_compositor_zlist_insert:
+ * @compositor: a #GhbCompositor
+ * @child: widgets to insert
+ * @z_pos: position
+ * @opacity: global opacity for this widget
+ *
+ * Insert in the given position of the zlist in the compositor.
+ * All children in the zlist must have associated GdkDrawable's
+ * This means they must be GtkDrawingArea or GtkEventBox
+ * 
+ **/
+void
+ghb_compositor_zlist_insert (
+    GhbCompositor *compositor,
+    GtkWidget *child, 
+    gint z_pos, 
+    gdouble opacity)
+{
+    GtkWidget *widget;
+    GhbCompositorChild *cc;
+    GdkDisplay *display;
+
+    g_return_if_fail (GHB_IS_COMPOSITOR (compositor));
+    g_return_if_fail (GTK_IS_WIDGET (child));
+    g_return_if_fail (child->parent == NULL);
+
+    widget = GTK_WIDGET (compositor);
+
+    cc = g_new(GhbCompositorChild, 1);
+    cc->widget = child;
+    cc->z_pos = z_pos;
+    cc->opacity = opacity;
+    compositor->children = g_list_insert_sorted(
+                                compositor->children, cc, zsort);
+
+    gtk_widget_set_parent(child, GTK_WIDGET(compositor));
+
+    display = gtk_widget_get_display (GTK_WIDGET(compositor));
+    if (gdk_display_supports_composite(display))
+    {
+        GList *link;
+
+        cc->drawables = find_drawables(NULL, cc->widget);
+
+        for (link = cc->drawables; link != NULL; link = link->next)
+        {
+            gtk_widget_realize(GTK_WIDGET(link->data));
+            gdk_window_set_composited(GTK_WIDGET(link->data)->window, TRUE);
+        }
+    }
+}
+
+static void
+ghb_compositor_add(GtkContainer *container, GtkWidget *child)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR(container);
+    GhbCompositorChild *cc;
+    gint z_pos = 0;
+    GList *last = g_list_last(compositor->children);
+
+    if (last != NULL)
+    {
+        cc = (GhbCompositorChild*)last->data;
+        z_pos = cc->z_pos + 1;
+    }
+    ghb_compositor_zlist_insert(compositor, child, z_pos, 1.0);
+}
+
+static void
+ghb_compositor_remove(GtkContainer *container, GtkWidget *child)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR(container);
+    GhbCompositorChild *cc;
+    GList *link;
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        if (cc->widget == child)
+        {
+            gboolean was_visible = GTK_WIDGET_VISIBLE( child );
+            gtk_widget_unparent(child);
+            compositor->children = g_list_remove(compositor->children, child);
+            g_free(child);
+
+            if (was_visible && GTK_WIDGET_VISIBLE (container))
+                gtk_widget_queue_resize(GTK_WIDGET(container));
+            break;
+        }
+    }
+}
+
+static void
+ghb_compositor_forall(
+    GtkContainer *container,
+    gboolean      include_internals,
+    GtkCallback   callback,
+    gpointer      data)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR (container);
+    GhbCompositorChild *cc;
+    GList *link;
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        (*callback)(cc->widget, data);
+    }
+}
+
+static void
+ghb_compositor_finalize (GObject *object)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR (object);
+    GhbCompositorChild *cc;
+    GList *link;
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        g_list_free(cc->drawables);
+        g_free(cc);
+    }
+    g_list_free(compositor->children);
+    G_OBJECT_CLASS (ghb_compositor_parent_class)->finalize (object);
+}
+
+
+static void
+ghb_compositor_realize (GtkWidget *widget)
+{
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+    gint border_width;
+    gboolean visible_window;
+
+    GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+    border_width = GTK_CONTAINER (widget)->border_width;
+
+    attributes.x = widget->allocation.x + border_width;
+    attributes.y = widget->allocation.y + border_width;
+    attributes.width = widget->allocation.width - 2*border_width;
+    attributes.height = widget->allocation.height - 2*border_width;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events (widget)
+            | GDK_BUTTON_MOTION_MASK
+            | GDK_BUTTON_PRESS_MASK
+            | GDK_BUTTON_RELEASE_MASK
+            | GDK_EXPOSURE_MASK
+            | GDK_ENTER_NOTIFY_MASK
+            | GDK_LEAVE_NOTIFY_MASK;
+
+    visible_window = !GTK_WIDGET_NO_WINDOW (widget);
+    if (visible_window)
+    {
+        attributes.visual = gtk_widget_get_visual (widget);
+        attributes.colormap = gtk_widget_get_colormap (widget);
+        attributes.wclass = GDK_INPUT_OUTPUT;
+
+        attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+        widget->window = gdk_window_new(gtk_widget_get_parent_window (widget),
+                                        &attributes, attributes_mask);
+        gdk_window_set_user_data (widget->window, widget);
+    }
+    else
+    {
+        widget->window = gtk_widget_get_parent_window (widget);
+        g_object_ref (widget->window);
+    }
+
+    widget->style = gtk_style_attach (widget->style, widget->window);
+
+    if (visible_window)
+        gtk_style_set_background(widget->style, widget->window, 
+                                GTK_STATE_NORMAL);
+}
+
+static void
+ghb_compositor_unrealize (GtkWidget *widget)
+{
+    GTK_WIDGET_CLASS (ghb_compositor_parent_class)->unrealize (widget);
+}
+
+static void
+ghb_compositor_size_request(
+    GtkWidget      *widget,
+    GtkRequisition *requisition)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR (widget);
+    GList *link;
+    GhbCompositorChild *cc;
+    gint width = 0, height = 0;
+    GtkRequisition child_requisition;
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        if (GTK_WIDGET_VISIBLE(cc->widget))
+        {
+            gtk_widget_size_request(cc->widget, NULL);
+            gtk_widget_get_child_requisition(cc->widget, &child_requisition);
+            width = MAX(child_requisition.width, width);
+            height = MAX(child_requisition.height, height);
+        }
+    }
+
+    requisition->width = width + GTK_CONTAINER (widget)->border_width * 2;
+    requisition->height = height + GTK_CONTAINER (widget)->border_width * 2;
+g_message("request_size %d x %d", requisition->width, requisition->height);
+}
+
+static void
+ghb_compositor_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+    GhbCompositor *compositor;
+    GtkAllocation child_allocation;
+    GhbCompositorChild *cc;
+    GList *link;
+
+    widget->allocation = *allocation;
+    compositor = GHB_COMPOSITOR (widget);
+
+    if (GTK_WIDGET_NO_WINDOW (widget))
+    {
+        child_allocation.x = allocation->x + 
+                            GTK_CONTAINER(widget)->border_width;
+        child_allocation.y = allocation->y + 
+                            GTK_CONTAINER(widget)->border_width;
+    }
+    else
+    {
+        child_allocation.x = 0;
+        child_allocation.y = 0;
+    }
+    child_allocation.width = MAX (allocation->width - 
+                                GTK_CONTAINER (widget)->border_width * 2, 0);
+    child_allocation.height = MAX (allocation->height - 
+                                GTK_CONTAINER (widget)->border_width * 2, 0);
+
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if (!GTK_WIDGET_NO_WINDOW (widget))
+        {
+            gdk_window_move_resize (widget->window,
+                allocation->x + GTK_CONTAINER (widget)->border_width,
+                allocation->y + GTK_CONTAINER (widget)->border_width,
+                child_allocation.width,
+                child_allocation.height);
+        }
+    }
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+        cc = (GhbCompositorChild*)link->data;
+        gtk_widget_size_allocate (cc->widget, &child_allocation);
+    }
+}
+
+static void
+ghb_compositor_blend (GtkWidget *widget, GdkEventExpose *event)
+{
+    GhbCompositor *compositor = GHB_COMPOSITOR (widget);
+    GList *link, *draw;
+    GdkRegion *region;
+    GtkWidget *child;
+    cairo_t *cr;
+    GhbCompositorChild *cc;
+
+    /* create a cairo context to draw to the window */
+    cr = gdk_cairo_create (widget->window);
+
+    for (link = compositor->children; link != NULL; link = link->next)
+    {
+
+        cc = (GhbCompositorChild*)link->data;
+        for (draw = cc->drawables; draw != NULL; draw = draw->next)
+        {
+            /* get our child */
+            child = GTK_WIDGET(draw->data);
+            /* the source data is the (composited) event box */
+            gdk_cairo_set_source_pixmap (cr, child->window,
+                                        child->allocation.x,
+                                        child->allocation.y);
+            /* draw no more than our expose event intersects our child */
+            region = gdk_region_rectangle (&child->allocation);
+            gdk_region_intersect (region, event->region);
+            gdk_cairo_region (cr, region);
+            cairo_clip (cr);
+            /* composite, with an opacity */
+            cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+            cairo_paint_with_alpha (cr, cc->opacity);
+            cairo_reset_clip(cr);
+        }
+    }
+    /* we're done */
+    cairo_destroy (cr);
+}
+
+static gboolean
+ghb_compositor_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+    if (GTK_WIDGET_DRAWABLE (widget))
+    {
+        if (!GTK_WIDGET_NO_WINDOW (widget))
+            ghb_compositor_blend (widget, event);
+
+        GTK_WIDGET_CLASS(
+            ghb_compositor_parent_class)->expose_event(widget, event);
+    }
+
+    return FALSE;
+}
diff --git a/gtk/src/ghbcompositor.h b/gtk/src/ghbcompositor.h
new file mode 100644 (file)
index 0000000..2dd62c5
--- /dev/null
@@ -0,0 +1,74 @@
+/* "Borrowed" from: */
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+#ifndef __GHB_COMPOSITOR_H__
+#define __GHB_COMPOSITOR_H__
+
+
+#include <gtk/gtkbin.h>
+
+
+G_BEGIN_DECLS
+
+#define GHB_TYPE_COMPOSITOR              (ghb_compositor_get_type ())
+#define GHB_COMPOSITOR(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHB_TYPE_COMPOSITOR, GhbCompositor))
+#define GHB_COMPOSITOR_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GHB_TYPE_COMPOSITOR, GhbCompositorClass))
+#define GHB_IS_COMPOSITOR(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHB_TYPE_COMPOSITOR))
+#define GHB_IS_COMPOSITOR_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GHB_TYPE_COMPOSITOR))
+#define GHB_COMPOSITOR_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GHB_TYPE_COMPOSITOR, GhbCompositorClass))
+
+typedef struct _GhbCompositor       GhbCompositor;
+typedef struct _GhbCompositorClass  GhbCompositorClass;
+typedef struct _GhbCompositorChild  GhbCompositorChild;
+
+struct _GhbCompositor
+{
+    GtkContainer  container;
+    GList        *children;
+};
+
+struct _GhbCompositorClass
+{
+    GtkContainerClass parent_class;
+};
+
+struct _GhbCompositorChild
+{
+    GtkWidget *widget;
+    GList     *drawables;
+    guint      z_pos;
+    gdouble    opacity;
+};
+
+GType      ghb_compositor_get_type           (void) G_GNUC_CONST;
+GtkWidget* ghb_compositor_new                (void);
+void       ghb_compositor_zlist_insert       (GhbCompositor *compositor,
+                                              GtkWidget *child, 
+                                              gint z_pos, gdouble opacity);
+
+G_END_DECLS
+
+#endif /* __GHB_COMPOSITOR_H__ */
index d0d020c..ebb7348 100644 (file)
@@ -50,6 +50,7 @@
 #include "resources.h"
 #include "presets.h"
 #include "preview.h"
+#include "ghbcompositor.h"
 
 
 /*
@@ -83,18 +84,20 @@ create_builder_or_die(const gchar * name)
 {
        guint res = 0;
        GValue *gval;
+       GError *error = NULL;
        const gchar *ghb_ui;
 
     const gchar *markup =
         N_("<b><big>Unable to create %s.</big></b>\n"
         "\n"
-        "Internal error. Could not parse UI description.\n");
+        "Internal error. Could not parse UI description.\n"
+               "%s");
        g_debug("create_builder_or_die ()\n");
        GtkBuilder *xml = gtk_builder_new();
        gval = ghb_resource_get("ghb-ui");
        ghb_ui = g_value_get_string(gval);
        if (xml != NULL)
-               res = gtk_builder_add_from_string(xml, ghb_ui, -1, NULL);
+               res = gtk_builder_add_from_string(xml, ghb_ui, -1, &error);
     if (!xml || !res) 
        {
         GtkWidget *dialog = gtk_message_dialog_new_with_markup(NULL,
@@ -102,7 +105,7 @@ create_builder_or_die(const gchar * name)
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_CLOSE,
             _(markup),
-            name);
+            name, error->message);
         gtk_dialog_run(GTK_DIALOG(dialog));
         gtk_widget_destroy(dialog);
         exit(EXIT_FAILURE);
@@ -541,43 +544,27 @@ main (int argc, char *argv[])
        watch_volumes (ud);
        ud->builder = create_builder_or_die (BUILDER_NAME);
 
-       GtkWidget *window, *event, *draw;
-       GdkScreen *screen;
-       GdkColormap *rgba;
+       // Set up the "hud" control overlay for the preview window
+       GtkWidget *window, *eb, *draw, *hud, *blender, *align;
        GdkColor color;
 
-       /* Make the widgets */
-       //event = gtk_event_box_new ();
-       event = GHB_WIDGET(ud->builder, "preview_event_box");
-       draw = GHB_WIDGET(ud->builder, "preview_image");
        window = GHB_WIDGET(ud->builder, "preview_window");
+       align = GHB_WIDGET(ud->builder, "preview_window_alignment");
+       draw = GHB_WIDGET(ud->builder, "preview_image");
+       hud = GHB_WIDGET(ud->builder, "preview_hud");
+       eb = GHB_WIDGET(ud->builder, "preview_event_box");
+
+       // Set up compositing for hud
+       blender = ghb_compositor_new();
+       gtk_container_add(GTK_CONTAINER(align), blender);
+       ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), draw, 1, 1);
+       ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), hud, 2, .85);
+       gtk_widget_show(blender);
 
        gdk_color_parse("black", &color);
        gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);
        gdk_color_parse("gray18", &color);
-       gtk_widget_modify_bg(event, GTK_STATE_NORMAL, &color);
-       /* Set the colourmap for the event box.
-       ** Must be done before the event box is realised.
-       **/
-       screen = gtk_widget_get_screen (draw);
-       rgba = gdk_screen_get_rgba_colormap (screen);
-       //gtk_widget_set_colormap (draw, rgba);
-
-       gtk_widget_set_colormap (event, rgba);
-
-       /* Set up the compositing handler.
-       ** Note that we do _after_ so that the normal (red) background is drawn
-       ** by gtk before our compositing occurs.
-       **/
-       g_signal_connect_after (window, "expose-event",
-                                               G_CALLBACK (preview_window_expose_cb), ud);
-       /* Set the event box GdkWindow to be composited.
-       ** Obviously must be performed after event box is realised.
-       **/
-       gtk_widget_realize(draw);
-       gtk_widget_realize(event);
-       gdk_window_set_composited (draw->window, TRUE);
-       gdk_window_set_composited (event->window, TRUE);
+       gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &color);
 
        // Redirect stderr to the activity window
        ghb_preview_init(ud);
index c7e825e..5b10d9b 100644 (file)
@@ -1107,6 +1107,7 @@ settings_configure_cb(
        return FALSE;
 }
 
+#if 0
 G_MODULE_EXPORT gboolean
 preview_window_expose_cb(
        GtkWidget *widget,
@@ -1158,3 +1159,4 @@ preview_window_expose_cb(
        return FALSE;
 }
 
+#endif