示例#1
0
文件: mdi.cpp 项目: beanhome/dev
void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
{
    wxASSERT_MSG( m_menuBar == NULL, "Only one menubar allowed" );

    m_menuBar = menu_bar;

    if (m_menuBar)
    {
        wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->GetParent();

        m_menuBar->SetParent( mdi_frame );

        /* insert the invisible menu bar into the _parent_ mdi frame */
        m_menuBar->Show(false);
        gtk_box_pack_start(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, false, false, 0);
        gtk_box_reorder_child(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0);

        gulong handler_id = g_signal_handler_find(
            m_menuBar->m_widget,
            GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
            g_signal_lookup("size_request", GTK_TYPE_WIDGET),
            0, NULL, NULL, m_menuBar);
        if (handler_id != 0)
            g_signal_handler_disconnect(m_menuBar->m_widget, handler_id);
        gtk_widget_set_size_request(m_menuBar->m_widget, -1, -1);
    }
}
示例#2
0
void wxFrame::SetToolBar(wxToolBar *toolbar)
{
    m_frameToolBar = toolbar;
    if (toolbar)
    {
        if (toolbar->IsVertical())
        {
            // Vertical toolbar and m_wxwindow go into an hbox, inside the
            // vbox (m_mainWidget). hbox is created on demand.
            GtkWidget* hbox = gtk_widget_get_parent(m_wxwindow);
            if (!GTK_IS_HBOX(hbox))
            {
                hbox = gtk_hbox_new(false, 0);
                gtk_widget_show(hbox);
                gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox);
                gtk_widget_reparent(m_wxwindow, hbox);
            }
            gtk_widget_reparent(toolbar->m_widget, hbox);
            gtk_box_set_child_packing(GTK_BOX(hbox),
                toolbar->m_widget, false, false, 0, GTK_PACK_START);

            int pos = 0;  // left
            if (toolbar->HasFlag(wxTB_RIGHT))
                pos = 1;  // right
            gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
        }
        else
        {
            // Horizontal toolbar goes into vbox (m_mainWidget)
            gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
            gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
                toolbar->m_widget, false, false, 0, GTK_PACK_START);

            int pos = 0;  // top
            if (m_frameMenuBar)
                pos = 1;  // below menubar
            if (toolbar->HasFlag(wxTB_BOTTOM))
                pos += 2;  // below client area (m_wxwindow)
            gtk_box_reorder_child(
                GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
        }

        // disconnect wxWindowGTK "size_request" handler,
        // it interferes with sizing of detached GtkHandleBox
        gulong handler_id = g_signal_handler_find(
            toolbar->m_widget,
            GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
            g_signal_lookup("size_request", GTK_TYPE_WIDGET),
            0, NULL, NULL, toolbar);
        if (handler_id != 0)
            g_signal_handler_disconnect(toolbar->m_widget, handler_id);

        // reset size request to allow native sizing to work
        gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
    }
    // make sure next size_allocate causes a wxSizeEvent
    m_oldClientWidth = 0;
}
示例#3
0
文件: menu.cpp 项目: mael15/wxWidgets
wxMenu::~wxMenu()
{
    // Destroying a menu generates a "hide" signal even if it's not shown
    // currently, so disconnect it to avoid dummy wxEVT_MENU_CLOSE events
    // generation.
    g_signal_handlers_disconnect_matched(m_menu,
        GSignalMatchType(G_SIGNAL_MATCH_DATA), 0, 0, NULL, NULL, this);

    if (m_owner)
    {
        gtk_widget_destroy(m_owner);
        g_object_unref(m_owner);
    }
    else
        gtk_widget_destroy(m_menu);

    g_object_unref(m_menu);
    g_object_unref(m_accel);
}
示例#4
0
文件: menu.cpp 项目: mael15/wxWidgets
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
{
    if ( !wxMenuBase::DoRemove(item) )
        return NULL;

    GtkWidget * const mitem = item->GetMenuItem();

    g_signal_handlers_disconnect_matched(mitem,
        GSignalMatchType(G_SIGNAL_MATCH_DATA), 0, 0, NULL, NULL, item);

#ifdef __WXGTK3__
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), NULL);
#else
    gtk_menu_item_remove_submenu(GTK_MENU_ITEM(mitem));
#endif

    gtk_widget_destroy(mitem);
    item->SetMenuItem(NULL);

    return item;
}
示例#5
0
void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
{
    wxFrameBase::AttachMenuBar(menuBar);

    if (m_frameMenuBar)
    {
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
        hildon_window_set_menu(HILDON_WINDOW(m_widget),
                               GTK_MENU(m_frameMenuBar->m_menubar));
#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
        m_frameMenuBar->SetParent(this);

        // menubar goes into top of vbox (m_mainWidget)
        gtk_box_pack_start(
            GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
        gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);

        // disconnect wxWindowGTK "size_request" handler,
        // it interferes with sizing of detached GtkHandleBox
        gulong handler_id = g_signal_handler_find(
            menuBar->m_widget,
            GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
            g_signal_lookup("size_request", GTK_TYPE_WIDGET),
            0, NULL, NULL, menuBar);
        if (handler_id != 0)
            g_signal_handler_disconnect(menuBar->m_widget, handler_id);

        // reset size request to allow native sizing to work
        gtk_widget_set_size_request(menuBar->m_widget, -1, -1);

        gtk_widget_show( m_frameMenuBar->m_widget );
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
    }
    // make sure next size_allocate causes a wxSizeEvent
    m_oldClientWidth = 0;
}
示例#6
0
bool wxTopLevelWindowGTK::Show( bool show )
{
    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );

#ifdef GDK_WINDOWING_X11
    bool deferShow = show && !m_isShown && m_deferShow;
    if (deferShow)
    {
        deferShow = m_deferShowAllowed && gs_requestFrameExtentsStatus != 2 &&
            !gtk_widget_get_realized(m_widget) &&
            g_signal_handler_find(m_widget,
                GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
                g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET),
                0, NULL, NULL, this);
        if (deferShow)
        {
            GdkScreen* screen = gtk_widget_get_screen(m_widget);
            GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
            deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0;

            // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes
            // to m_decorSize, it breaks saving/restoring window size with
            // GetSize()/SetSize() because it makes window bigger between each
            // restore and save.
            m_updateDecorSize = deferShow;
        }

        m_deferShow = deferShow;
    }
    if (deferShow)
    {
        // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer
        // calling gtk_widget_show() until _NET_FRAME_EXTENTS property
        // notification is received, so correct frame extents are known.
        // This allows resizing m_widget to keep the overall size in sync with
        // what wxWidgets expects it to be without an obvious change in the
        // window size immediately after it becomes visible.

        // Realize m_widget, so m_widget->window can be used. Realizing normally
        // causes the widget tree to be size_allocated, which generates size
        // events in the wrong order. However, the size_allocates will not be
        // done if the allocation is not the default (1,1).
        GtkAllocation alloc;
        gtk_widget_get_allocation(m_widget, &alloc);
        const int alloc_width = alloc.width;
        if (alloc_width == 1)
        {
            alloc.width = 2;
            gtk_widget_set_allocation(m_widget, &alloc);
        }
        gtk_widget_realize(m_widget);
        if (alloc_width == 1)
        {
            alloc.width = 1;
            gtk_widget_set_allocation(m_widget, &alloc);
        }

        // send _NET_REQUEST_FRAME_EXTENTS
        XClientMessageEvent xevent;
        memset(&xevent, 0, sizeof(xevent));
        xevent.type = ClientMessage;
        GdkWindow* window = gtk_widget_get_window(m_widget);
        xevent.window = GDK_WINDOW_XID(window);
        xevent.message_type = gdk_x11_atom_to_xatom_for_display(
            gdk_window_get_display(window),
            gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false));
        xevent.format = 32;
        Display* display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(window));
        XSendEvent(display, DefaultRootWindow(display), false,
            SubstructureNotifyMask | SubstructureRedirectMask,
            (XEvent*)&xevent);

        if (gs_requestFrameExtentsStatus == 0)
        {
            // if WM does not respond to request within 1 second,
            // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working
            m_netFrameExtentsTimerId =
                g_timeout_add(1000, request_frame_extents_timeout, this);
        }

        // defer calling gtk_widget_show()
        m_isShown = true;
        return true;
    }
#endif // GDK_WINDOWING_X11

    if (show && !gtk_widget_get_realized(m_widget))
    {
        // size_allocate signals occur in reverse order (bottom to top).
        // Things work better if the initial wxSizeEvents are sent (from the
        // top down), before the initial size_allocate signals occur.
        wxSizeEvent event(GetSize(), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }

    bool change = base_type::Show(show);

    if (change && !show)
    {
        // make sure window has a non-default position, so when it is shown
        // again, it won't be repositioned by WM as if it were a new window
        // Note that this must be done _after_ the window is hidden.
        gtk_window_move((GtkWindow*)m_widget, m_x, m_y);
    }

    return change;
}