GtkWidget* wxPizza::New(long windowStyle) { GtkWidget* widget = GTK_WIDGET(g_object_new(type(), NULL)); wxPizza* pizza = WX_PIZZA(widget); pizza->m_scroll_x = 0; pizza->m_scroll_y = 0; pizza->m_is_scrollable = (windowStyle & (wxHSCROLL | wxVSCROLL)) != 0; // mask off border styles not useable with wxPizza pizza->m_border_style = int(windowStyle & BORDER_STYLES); #if GTK_CHECK_VERSION(3,0,0) || defined(GTK_DISABLE_DEPRECATED) gtk_widget_set_has_window(widget, true); #else gtk_fixed_set_has_window(GTK_FIXED(widget), true); #endif gtk_widget_add_events(widget, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK); return widget; }
GtkWidget* wxPizza::New(long windowStyle) { GtkWidget* widget = GTK_WIDGET(g_object_new(type(), NULL)); wxPizza* pizza = WX_PIZZA(widget); pizza->m_children = NULL; pizza->m_scroll_x = 0; pizza->m_scroll_y = 0; pizza->m_windowStyle = windowStyle; #ifdef __WXGTK3__ gtk_widget_set_has_window(widget, true); #else gtk_fixed_set_has_window(GTK_FIXED(widget), true); #endif gtk_widget_add_events(widget, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK); return widget; }
static void pizza_remove(GtkContainer* container, GtkWidget* widget) { GTK_CONTAINER_CLASS(parent_class)->remove(container, widget); wxPizza* pizza = WX_PIZZA(container); #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ for (GList* p = pizza->m_children; p; p = p->next) { wxPizzaChild* child = static_cast<wxPizzaChild*>(p->data); if (child->widget == widget) { pizza->m_children = g_list_delete_link(pizza->m_children, p); delete child; break; } } }
GtkWidget* wxPizza::New(long windowStyle,void* owner) { GtkWidget* widget = GTK_WIDGET(g_object_new(type(), NULL)); wxPizza* pizza = WX_PIZZA(widget); pizza->m_owner = owner; pizza->m_backing_window = NULL; pizza->m_scroll_x = 0; pizza->m_scroll_y = 0; pizza->m_is_scrollable = (windowStyle & (wxHSCROLL | wxVSCROLL)) != 0; // mask off border styles not useable with wxPizza pizza->m_border_style = int(windowStyle & BORDER_STYLES); gtk_fixed_set_has_window(GTK_FIXED(widget), true); gtk_widget_add_events(widget, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK); return widget; }
static void size_allocate(GtkWidget* widget, GtkAllocation* alloc) { wxPizza* pizza = WX_PIZZA(widget); int border_x, border_y; pizza->get_border_widths(border_x, border_y); int w = alloc->width - 2 * border_x; if (w < 0) w = 0; if (gtk_widget_get_realized(widget)) { int h = alloc->height - 2 * border_y; if (h < 0) h = 0; const int x = alloc->x + border_x; const int y = alloc->y + border_y; GdkWindow* window = gtk_widget_get_window(widget); int old_x, old_y; gdk_window_get_position(window, &old_x, &old_y); if (x != old_x || y != old_y || w != gdk_window_get_width(window) || h != gdk_window_get_height(window)) { gdk_window_move_resize(window, x, y, w, h); if (border_x + border_y) { // old and new border areas need to be invalidated, // otherwise they will not be erased/redrawn properly GdkWindow* parent = gtk_widget_get_parent_window(widget); gdk_window_invalidate_rect(parent, &widget->allocation, false); gdk_window_invalidate_rect(parent, alloc, false); } } } widget->allocation = *alloc; // adjust child positions for (const GList* list = pizza->m_fixed.children; list; list = list->next) { const GtkFixedChild* child = static_cast<GtkFixedChild*>(list->data); if (gtk_widget_get_visible(child->widget)) { GtkAllocation child_alloc; // note that child positions do not take border into // account, they need to be relative to widget->window, // which has already been adjusted child_alloc.x = child->x - pizza->m_scroll_x; child_alloc.y = child->y - pizza->m_scroll_y; GtkRequisition req; gtk_widget_get_child_requisition(child->widget, &req); child_alloc.width = req.width; child_alloc.height = req.height; if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) child_alloc.x = w - child_alloc.x - child_alloc.width; gtk_widget_size_allocate(child->widget, &child_alloc); } } }
static void pizza_size_allocate(GtkWidget* widget, GtkAllocation* alloc) { wxPizza* pizza = WX_PIZZA(widget); GtkBorder border; pizza->get_border(border); int w = alloc->width - border.left - border.right; if (w < 0) w = 0; if (gtk_widget_get_realized(widget)) { int h = alloc->height - border.top - border.bottom; if (h < 0) h = 0; const int x = alloc->x + border.left; const int y = alloc->y + border.top; GdkWindow* window = gtk_widget_get_window(widget); int old_x, old_y; gdk_window_get_position(window, &old_x, &old_y); if (x != old_x || y != old_y || w != gdk_window_get_width(window) || h != gdk_window_get_height(window)) { gdk_window_move_resize(window, x, y, w, h); if (border.left + border.right + border.top + border.bottom) { // old and new border areas need to be invalidated, // otherwise they will not be erased/redrawn properly GtkAllocation old_alloc; gtk_widget_get_allocation(widget, &old_alloc); GdkWindow* parent = gtk_widget_get_parent_window(widget); gdk_window_invalidate_rect(parent, &old_alloc, false); gdk_window_invalidate_rect(parent, alloc, false); } } } gtk_widget_set_allocation(widget, alloc); // adjust child positions for (const GList* p = pizza->m_children; p; p = p->next) { const wxPizzaChild* child = static_cast<wxPizzaChild*>(p->data); if (gtk_widget_get_visible(child->widget)) { GtkAllocation child_alloc; // note that child positions do not take border into // account, they need to be relative to widget->window, // which has already been adjusted child_alloc.x = child->x - pizza->m_scroll_x; child_alloc.y = child->y - pizza->m_scroll_y; child_alloc.width = child->width; child_alloc.height = child->height; if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) child_alloc.x = w - child_alloc.x - child_alloc.width; gtk_widget_size_allocate(child->widget, &child_alloc); } } }
static void unmap(GtkWidget* widget) { parent_class->unmap(widget); wxPizza* pizza = WX_PIZZA(widget); if (pizza->m_backing_window) gdk_window_hide(pizza->m_backing_window); }
static void hide(GtkWidget* widget) { if (widget->parent && WX_PIZZA(widget)->m_border_style) { // invalidate whole allocation so borders will be erased properly const GtkAllocation& a = widget->allocation; gtk_widget_queue_draw_area(widget->parent, a.x, a.y, a.width, a.height); } parent_class->hide(widget); }
static void unrealize(GtkWidget* widget) { parent_class->unrealize(widget); wxPizza* pizza = WX_PIZZA(widget); if (pizza->m_backing_window) { gdk_window_set_user_data(pizza->m_backing_window, NULL); gdk_window_destroy(pizza->m_backing_window); pizza->m_backing_window = NULL; } }
static void pizza_hide(GtkWidget* widget) { GtkWidget* parent = gtk_widget_get_parent(widget); if (parent && (WX_PIZZA(widget)->m_windowStyle & wxPizza::BORDER_STYLES)) { // invalidate whole allocation so borders will be erased properly GtkAllocation a; gtk_widget_get_allocation(widget, &a); gtk_widget_queue_draw_area(parent, a.x, a.y, a.width, a.height); } parent_class->hide(widget); }
static void pizza_remove(GtkContainer* container, GtkWidget* widget) { GTK_CONTAINER_CLASS(parent_class)->remove(container, widget); wxPizza* pizza = WX_PIZZA(container); for (GList* p = pizza->m_children; p; p = p->next) { wxPizzaChild* child = static_cast<wxPizzaChild*>(p->data); if (child->widget == widget) { pizza->m_children = g_list_delete_link(pizza->m_children, p); delete child; break; } } }
static void realize(GtkWidget* widget) { parent_class->realize(widget); wxPizza* pizza = WX_PIZZA(widget); if (pizza->m_border_style || pizza->m_is_scrollable) { int border_x, border_y; pizza->get_border_widths(border_x, border_y); int x = widget->allocation.x + border_x; int y = widget->allocation.y + border_y; int w = widget->allocation.width - 2 * border_x; int h = widget->allocation.height - 2 * border_y; if (w < 0) w = 0; if (h < 0) h = 0; if (pizza->m_is_scrollable) { // second window is created if wxWindow is scrollable GdkWindowAttr attr; attr.event_mask = 0; attr.x = x; attr.y = y; attr.width = w; attr.height = h; attr.wclass = GDK_INPUT_OUTPUT; attr.visual = gtk_widget_get_visual(widget); attr.colormap = gtk_widget_get_colormap(widget); attr.window_type = GDK_WINDOW_CHILD; pizza->m_backing_window = gdk_window_new( gdk_window_get_parent(widget->window), &attr, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP); gdk_window_set_user_data(pizza->m_backing_window, widget); gdk_window_reparent(widget->window, pizza->m_backing_window, 0, 0); gdk_window_resize(widget->window, w, h); // Parts of m_backing_window may be exposed temporarily while // resizing. Setting the backing pixmap to None prevents those // areas from being briefly painted black. gdk_window_set_back_pixmap(pizza->m_backing_window, NULL, false); } else gdk_window_move_resize(widget->window, x, y, w, h); } }
static void realize(GtkWidget* widget) { parent_class->realize(widget); wxPizza* pizza = WX_PIZZA(widget); if (pizza->m_border_style) { int border_x, border_y; pizza->get_border_widths(border_x, border_y); int x = widget->allocation.x + border_x; int y = widget->allocation.y + border_y; int w = widget->allocation.width - 2 * border_x; int h = widget->allocation.height - 2 * border_y; if (w < 0) w = 0; if (h < 0) h = 0; gdk_window_move_resize(widget->window, x, y, w, h); } }
static int GetBorderWidth(wxSystemMetric index, wxWindow* win) { if (win->m_wxwindow) { wxPizza* pizza = WX_PIZZA(win->m_wxwindow); GtkBorder border; pizza->get_border(border); switch (index) { case wxSYS_BORDER_X: case wxSYS_EDGE_X: case wxSYS_FRAMESIZE_X: return border.left; default: return border.top; } } return -1; }
static int GetBorderWidth(wxSystemMetric index, wxWindow* win) { if (win->m_wxwindow) { wxPizza* pizza = WX_PIZZA(win->m_wxwindow); int x, y; pizza->get_border_widths(x, y); switch (index) { case wxSYS_BORDER_X: case wxSYS_EDGE_X: case wxSYS_FRAMESIZE_X: return x; default: return y; } } return -1; }
static void pizza_realize(GtkWidget* widget) { parent_class->realize(widget); wxPizza* pizza = WX_PIZZA(widget); if (pizza->m_windowStyle & wxPizza::BORDER_STYLES) { GtkBorder border; pizza->get_border(border); GtkAllocation a; gtk_widget_get_allocation(widget, &a); int x = a.x + border.left; int y = a.y + border.top; int w = a.width - border.left - border.right; int h = a.height - border.top - border.bottom; if (w < 0) w = 0; if (h < 0) h = 0; gdk_window_move_resize(gtk_widget_get_window(widget), x, y, w, h); } }
//////////////////////////////////////////////////////////// /// Construct the wxSFMLCanvas //////////////////////////////////////////////////////////// wxSFMLCanvas::wxSFMLCanvas(wxWindow *Parent, wxWindowID Id, const wxPoint &Position, const wxSize &Size, long Style) : wxControl(Parent, Id, Position, Size, Style) { #ifdef __WXGTK__ // GTK implementation requires to go deeper to find the low-level X11 // identifier of the widget gtk_widget_realize(m_wxwindow); gtk_widget_set_double_buffered(m_wxwindow, false); GtkWidget *privHandle = m_wxwindow; wxPizza *pizza = WX_PIZZA(privHandle); GtkWidget *widget = GTK_WIDGET(pizza); // Get the internal gtk window... #if GTK_CHECK_VERSION(3, 0, 0) GdkWindow *win = gtk_widget_get_window(widget); #else GdkWindow *win = widget->window; #endif XFlush(GDK_WINDOW_XDISPLAY(win)); //...and pass it to the sf::RenderWindow. #if GTK_CHECK_VERSION(3, 0, 0) sf::RenderWindow::create(GDK_WINDOW_XID(win)); #else sf::RenderWindow::create(GDK_WINDOW_XWINDOW(win)); #endif #else // Tested under Windows XP only (should work with X11 and other Windows // versions - no idea about MacOS) sf::RenderWindow::create(static_cast<sf::WindowHandle>(GetHandle())); #endif }
static void size_allocate(GtkWidget* widget, GtkAllocation* alloc) { const bool is_resize = widget->allocation.width != alloc->width || widget->allocation.height != alloc->height; const bool is_move = widget->allocation.x != alloc->x || widget->allocation.y != alloc->y; wxPizza* pizza = WX_PIZZA(widget); int border_x, border_y; pizza->get_border_widths(border_x, border_y); int w = alloc->width - 2 * border_x; if (w < 0) w = 0; if (GTK_WIDGET_REALIZED(widget) && (is_move || is_resize)) { int h = alloc->height - 2 * border_y; if (h < 0) h = 0; if (pizza->m_is_scrollable) { // two windows, both same size gdk_window_move_resize(pizza->m_backing_window, alloc->x + border_x, alloc->y + border_y, w, h); if (is_resize) gdk_window_resize(widget->window, w, h); } else { // one window gdk_window_move_resize(widget->window, alloc->x + border_x, alloc->y + border_y, w, h); if (is_resize && (border_x || border_y)) { // old and new border areas need to be invalidated, // otherwise they will not be erased/redrawn properly const GtkAllocation& a1 = widget->allocation; const GtkAllocation& a2 = *alloc; GdkRectangle r1 = { a1.x, a1.y, a1.width, a1.height }; GdkRectangle r2 = { a2.x, a2.y, a2.width, a2.height }; gdk_window_invalidate_rect(widget->parent->window, &r1, false); gdk_window_invalidate_rect(widget->parent->window, &r2, false); } } } widget->allocation = *alloc; // adjust child positions for (const GList* list = pizza->m_fixed.children; list; list = list->next) { const GtkFixedChild* child = static_cast<GtkFixedChild*>(list->data); if (GTK_WIDGET_VISIBLE(child->widget)) { GtkAllocation child_old_alloc = child->widget->allocation; GtkAllocation child_alloc; // note that child positions do not take border into // account, they need to be relative to widget->window, // which has already been adjusted child_alloc.x = child->x - pizza->m_scroll_x; child_alloc.y = child->y - pizza->m_scroll_y; GtkRequisition req; gtk_widget_get_child_requisition(child->widget, &req); child_alloc.width = req.width; child_alloc.height = req.height; if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) child_alloc.x = w - child_alloc.x - child_alloc.width; gtk_widget_size_allocate(child->widget, &child_alloc); } } }
static void pizza_add(GtkContainer* container, GtkWidget* widget) { WX_PIZZA(container)->put(widget, 0, 0, 1, 1); }