Exemple #1
0
static void gui_get_screen_size(GtkLayout* screen, gint* width, gint* height) {
  if(screen == NULL) {
    *width = gdk_screen_width();
    *height = gdk_screen_height();
  } else {
    gtk_layout_get_size(screen, (guint*)width, (guint*)height);
  }
}
Exemple #2
0
int gui_height(GtkLayout* screen) {
  if(screen) {
    guint width;
    guint height;
    gtk_layout_get_size(screen, &width, &height);
    return (int)height;
  } else {
    return gdk_screen_height();
  }
}
Exemple #3
0
int
clip_GTK_LAYOUTGETSIZE(ClipMachine * cm)
{
	C_widget *clay = _fetch_cw_arg(cm);
        guint width;
        guint height;
	CHECKCWID(clay,GTK_IS_LAYOUT);

	gtk_layout_get_size(GTK_LAYOUT(clay->widget), &width, &height);
	_clip_storni(cm, width , 2, 0);
	_clip_storni(cm, height, 3, 0);
	return 0;
err:
	return 1;
}
gboolean FloatingWindow::on_status_bar_motion_notify (GdkEventMotion *event)
{
  if (resizing_window) {
    gw_destroy_source (resize_event_id);
    resize_event_id = g_timeout_add_full(G_PRIORITY_DEFAULT, 200, GSourceFunc(on_resize_timeout), gpointer(this), NULL);
    gtk_widget_hide (vbox_client);
    guint layout_width, layout_height;
    gtk_layout_get_size (GTK_LAYOUT (layout), &layout_width, &layout_height);
    gint event_x = event->x_root;
    gint event_y = event->y_root;
    if (previous_root_x >= 0) {
      bool resize_box = false;
      if (event_x != previous_root_x) {
        guint new_width = my_gdk_rectangle.width + event_x - previous_root_x;
        // Window should not become too narrow, or too wide for the screen.
        if (new_width >= 100) {
          if ((my_gdk_rectangle.x + new_width) <= layout_width) {
            my_gdk_rectangle.width = new_width;
            resize_box = true;
          }
        }
      }
      if (event_y != previous_root_y) {
        guint new_height = my_gdk_rectangle.height + event_y - previous_root_y;
        // Window should not become too short, or too tall for the screen.
        if (new_height >= 100) {
          if ((my_gdk_rectangle.y + new_height) <= layout_height) {
            my_gdk_rectangle.height = new_height;
            resize_box = true;
          }
        }
      }
      if (resize_box) {
        gtk_widget_set_size_request (vbox_window, my_gdk_rectangle.width, my_gdk_rectangle.height);
      }
    }
    previous_root_x = event_x;
    previous_root_y = event_y;
  }
  return false;
}
gboolean FloatingWindow::on_title_bar_motion_notify (GdkEventMotion *event)
{
  if (dragging_window) {
    guint layout_width, layout_height;
    gtk_layout_get_size (GTK_LAYOUT (layout), &layout_width, &layout_height);
    gint event_x = event->x_root;
    gint event_y = event->y_root;
    if (previous_root_x >= 0) {
      bool move_box = false;
      if (event_x != previous_root_x) {
        guint new_x = my_gdk_rectangle.x + event_x - previous_root_x;
        // The window does not move beyond the left or right side 
        if (new_x >= 0) {
          if ((new_x + my_gdk_rectangle.width) <= layout_width) {
            my_gdk_rectangle.x = new_x;
            move_box = true;
          }
        }
      }
      if (event_y != previous_root_y) {
        guint new_y = my_gdk_rectangle.y + event_y - previous_root_y;
        // The window does not move beyond the top or bottom.
        if (new_y >= 0) {
          if ((new_y + my_gdk_rectangle.height) <= layout_height) {
            my_gdk_rectangle.y = new_y;
            move_box = true;
          }
        }
      }
      if (move_box) {
        rectangle_set (my_gdk_rectangle);
      }
    }
    previous_root_x = event_x;
    previous_root_y = event_y;
  }
  return false;
}
void FloatingWindow::display(bool startup)
// Does the bookkeeping necessary for displaying the floating box.
// startup: whether the box is started at program startup.
{
  // Settings.
  extern Settings *settings;

  // The parameters of all the windows.
  WindowData window_parameters(false);

  // Clear the new window's position.
  my_gdk_rectangle.x = 0;
  my_gdk_rectangle.y = 0;
  my_gdk_rectangle.width = 0;
  my_gdk_rectangle.height = 0;

  // At program startup extract the position and size of the window from the general configuration.
  // It does not matter whether the space for the window is already taken up by another window,
  // because the user wishes to use the coordinates that he has set for this window.
  for (unsigned int i = 0; i < window_parameters.widths.size(); i++) {
    if ((window_parameters.ids[i] == window_id) && (window_parameters.titles[i] == title) && startup) {
      my_gdk_rectangle.x = window_parameters.x_positions[i];
      my_gdk_rectangle.y = window_parameters.y_positions[i];
      my_gdk_rectangle.width = window_parameters.widths[i];
      my_gdk_rectangle.height = window_parameters.heights[i];
    }
  }

  // Reject zero width and zero height values on startup.
  if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0))
    startup = false;

  // When a new window needs to be allocated, there are a few steps to be taken.
  if (!startup) {

    // Step 1: The area rectangle where the window should fit in is defined. 
    GdkRectangle area_rectangle;
    area_rectangle.x = 0;
    area_rectangle.y = 0;
    area_rectangle.width = 0;
    area_rectangle.height = 0;
    {
      guint width, height;
      gtk_layout_get_size (GTK_LAYOUT (layout), &width, &height);
      area_rectangle.width = width;
      area_rectangle.height = height;
    }

    // Step 2: An available region is made of that whole area.
    GdkRegion *available_region = gdk_region_rectangle(&area_rectangle);

    // Step 3: The regions of each of the open windows is substracted from the available region.
    for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
      FloatingWindow * floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
      GdkRectangle rectangle = floating_window->rectangle_get();
      GdkRegion *region = gdk_region_rectangle(&rectangle);
      gdk_region_subtract(available_region, region);
      gdk_region_destroy(region);
    }

    // Step 4: The rectangles that the area region consists of are requested,
    // and the biggest suitable rectangle is chosen for the window.
    // A rectangle is considered suitable if it has at least 10% of the width, and 10% of the height of the area rectangle.
    GdkRectangle *gdk_rectangles = NULL;
    gint rectangle_count = 0;
    gdk_region_get_rectangles(available_region, &gdk_rectangles, &rectangle_count);
    for (int i = 0; i < rectangle_count; ++i) {
      GdkRectangle & rectangle = gdk_rectangles[i];
      if (rectangle.width >= (area_rectangle.width / 10)) {
        if (rectangle.height >= (area_rectangle.height / 10)) {
          if ((rectangle.width * rectangle.height) > (my_gdk_rectangle.width * my_gdk_rectangle.height)) {
            my_gdk_rectangle = rectangle;
          }
        }
      }
    }
    g_free(gdk_rectangles);

    // Step 5: The available region is destroyed.
    gdk_region_destroy(available_region);

    // Step 6: If no area big enough is found, then the window that takes most space in the area is chosen, 
    // the longest side is halved, and the new window is put in that freed area.
    if ((my_gdk_rectangle.width == 0) || (my_gdk_rectangle.height == 0)) {
      FloatingWindow * resize_window_pointer = NULL;
      int largest_size = 0;
      for (unsigned int i = 0; i < settings->session.open_floating_windows.size(); i++) {
        FloatingWindow *floating_window = (FloatingWindow *) settings->session.open_floating_windows[i];
        GdkRectangle rectangle = floating_window->rectangle_get ();
        int size = rectangle.width * rectangle.height;
        if (size > largest_size) {
          resize_window_pointer = floating_window;
          largest_size = size;
        }
      }
      if (resize_window_pointer) {
        GdkRectangle resize_window_rectangle = resize_window_pointer->rectangle_get();
        my_gdk_rectangle = resize_window_pointer->rectangle_get();
        if (resize_window_rectangle.width > resize_window_rectangle.height) {
          resize_window_rectangle.width /= 2;
          my_gdk_rectangle.width /= 2;
          my_gdk_rectangle.x += resize_window_rectangle.width;
        } else {
          resize_window_rectangle.height /= 2;
          my_gdk_rectangle.height /= 2;
          my_gdk_rectangle.y += resize_window_rectangle.height;
        }
        resize_window_pointer->rectangle_set (resize_window_rectangle);
      }
    }
  }
  // Add the window to the layout and set its position and size.
  gtk_layout_put (GTK_LAYOUT (layout), vbox_window, my_gdk_rectangle.x, my_gdk_rectangle.y);
  rectangle_set (my_gdk_rectangle);
  // Store a pointer to this window in the Session.
  settings->session.open_floating_windows.push_back(gpointer (this));
}