splash.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:5k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /*
  2.  *  Celestia GTK+ Front-End
  3.  *  Copyright (C) 2005 Pat Suwalski <pat@suwalski.net>
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  $Id: splash.cpp,v 1.4 2006-07-24 17:31:24 christey Exp $
  11.  */
  12. #ifdef HAVE_CONFIG_H
  13. #include <config.h>
  14. #endif /* HAVE_CONFIG_H */
  15. #include <gtk/gtk.h>
  16. #ifdef CAIRO
  17. #include <cairo/cairo.h>
  18. #endif /* CAIRO */
  19. #include "splash.h"
  20. #include "common.h"
  21. /* Declarations */
  22. static gboolean splashExpose(GtkWidget* win, GdkEventExpose *event, SplashData* ss);
  23. /* OBJECT: Overrides ProgressNotifier to receive feedback from core */
  24. GtkSplashProgressNotifier::GtkSplashProgressNotifier(SplashData* _splash) :
  25. splash(_splash) {};
  26. void GtkSplashProgressNotifier::update(const string& filename)
  27. {
  28. splashSetText(splash, filename.c_str());
  29. }
  30. GtkSplashProgressNotifier::~GtkSplashProgressNotifier() {};
  31. /* ENTRY: Creates a new SplashData struct, starts the splash screen */
  32. SplashData* splashStart(AppData* app, gboolean showSplash)
  33. {
  34. SplashData* ss = g_new0(SplashData, 1);
  35. ss->app = app;
  36. ss->notifier = new GtkSplashProgressNotifier(ss);
  37. ss->hasARGB = FALSE;
  38. ss->redraw = TRUE;
  39. /* Continue the "wait" cursor until the splash is done */
  40. gtk_window_set_auto_startup_notification(FALSE);
  41. /* Don't do anything else if the splash is not to be shown */
  42. if (showSplash == FALSE) return ss;
  43. ss->splash = gtk_window_new(GTK_WINDOW_POPUP);
  44. gtk_window_set_position(GTK_WINDOW(ss->splash), GTK_WIN_POS_CENTER);
  45. gtk_widget_set_app_paintable(ss->splash, TRUE);
  46. #ifdef CAIRO
  47. /* Colormap Magic */
  48. GdkScreen* screen = gtk_widget_get_screen(ss->splash);
  49. GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen);
  50. if (colormap != NULL)
  51. {
  52. gtk_widget_set_colormap(ss->splash, colormap);
  53. ss->hasARGB = TRUE;
  54. }
  55. #endif
  56. GtkWidget* gf = gtk_fixed_new();
  57. gtk_container_add(GTK_CONTAINER(ss->splash), gf);
  58. GtkWidget* i = gtk_image_new_from_file("splash/splash.png");
  59. gtk_fixed_put(GTK_FIXED(gf), i, 0, 0);
  60. /* The information label is right-aligned and biased to the lower-right
  61.  * of the window. It's designed to be the full width and height of the
  62.  * opaque parts of the splash. */
  63. ss->label = gtk_label_new(NULL);
  64. gtk_misc_set_alignment(GTK_MISC(ss->label), 1, 1);
  65. gtk_label_set_justify(GTK_LABEL(ss->label), GTK_JUSTIFY_RIGHT);
  66. gtk_widget_modify_fg(ss->label, GTK_STATE_NORMAL, &ss->label->style->white);
  67. gtk_widget_show_all(ss->splash);
  68. /* Size allocations available after showing splash. */
  69. gtk_widget_set_size_request(ss->label, i->allocation.width - 80,
  70.                                        i->allocation.height / 2);
  71. gtk_fixed_put(GTK_FIXED(gf), ss->label, 40, i->allocation.height / 2 - 40);
  72. gtk_widget_show(ss->label);
  73. g_signal_connect (ss->splash, "expose_event",
  74.   G_CALLBACK (splashExpose),
  75.      ss);
  76. while (gtk_events_pending()) gtk_main_iteration();
  77. return ss;
  78. }
  79. /* ENTRY: destroys the splash screen */
  80. void splashEnd(SplashData* ss)
  81. {
  82. if (ss->splash)
  83. gtk_widget_destroy(ss->splash);
  84. /* Return the cursor from wait to normal */
  85. gdk_notify_startup_complete();
  86. delete ss->notifier;
  87. g_free(ss);
  88. }
  89. /* ENTRY: Sets the text to be shown in the splash */
  90. void splashSetText(SplashData* ss, const char* text)
  91. {
  92. char message[255];
  93. if (!ss->splash)
  94. return;
  95. sprintf(message, "Version " VERSION "n%s", text);
  96. gtk_label_set_text(GTK_LABEL(ss->label), message);
  97. /* Update the GTK event queue */
  98. while (gtk_events_pending()) gtk_main_iteration();
  99. }
  100. /* CALLBACK: Called when the splash screen is exposed */
  101. static gboolean splashExpose(GtkWidget* win, GdkEventExpose *event, SplashData* ss)
  102. {
  103. /* All of this code is only needed at the very first drawing. This
  104.  * operation is quite expensive. */
  105. if (ss->redraw != TRUE) return FALSE;
  106. if (ss->hasARGB)
  107. {
  108. #ifdef CAIRO
  109. /* Use cairo for true transparent windows */
  110. cairo_t *cr = gdk_cairo_create(win->window);
  111. cairo_rectangle(cr, event->area.x,
  112.     event->area.y,
  113.     event->area.width,
  114.     event->area.height);
  115.         cairo_clip(cr);
  116. /* Draw a fully transparent rectangle the size of the window */
  117. cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
  118. cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
  119. cairo_paint(cr);
  120. cairo_destroy(cr);
  121. #endif /* CAIRO */
  122. }
  123. else
  124. {
  125. /* Fall back to compositing a screenshot of whatever is below the
  126.  * area we are drawing in. */
  127. GdkPixbuf* bg;
  128. int x, y, w, h;
  129. gdk_window_get_root_origin(win->window, &x, &y);
  130. gdk_drawable_get_size(win->window, &w, &h);
  131. bg = gdk_pixbuf_get_from_drawable(NULL,
  132.                                   gtk_widget_get_root_window(win),
  133.                                   NULL, x, y, 0, 0, w, h);
  134. gdk_draw_pixbuf(win->window, NULL, bg, 0, 0, 0, 0, w, h,
  135.                 GDK_RGB_DITHER_NONE, 0, 0);
  136. gdk_pixbuf_unref(bg);
  137. }
  138. /* Never redraw again */
  139. ss->redraw = FALSE;
  140. return FALSE;
  141. }