window.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,007 行 · 第 1/5 页

CPP
2,007
字号
    if (win->HasFlag(wxSUNKEN_BORDER))
    {
        gtk_draw_shadow( widget->style,
                         widget->window,
                         GTK_STATE_NORMAL,
                         GTK_SHADOW_IN,
                         dx, dy,
                         widget->allocation.width-dw, widget->allocation.height-dh );
        return;
    }

    if (win->HasFlag(wxSIMPLE_BORDER))
    {
        GdkGC *gc;
        gc = gdk_gc_new( widget->window );
        gdk_gc_set_foreground( gc, &widget->style->black );
        gdk_draw_rectangle( widget->window, gc, FALSE,
                         dx, dy,
                         widget->allocation.width-dw-1, widget->allocation.height-dh-1 );
        gdk_gc_unref( gc );
        return;
    }
#endif // __WXUNIVERSAL__
}

//-----------------------------------------------------------------------------
// "expose_event" of m_widget
//-----------------------------------------------------------------------------

extern "C" {
static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win )
{
    if (gdk_event->count > 0) return FALSE;

    draw_frame( widget, win );

#ifdef __WXGTK20__

    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);

#endif
    return TRUE;
}
}

//-----------------------------------------------------------------------------
// "draw" of m_widget
//-----------------------------------------------------------------------------

#ifndef __WXGTK20__

extern "C" {
static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win )
{
    draw_frame( widget, win );
}
}

#endif // GTK+ < 2.0

//-----------------------------------------------------------------------------
// "size_request" of m_widget
//-----------------------------------------------------------------------------

// make it extern because wxStaticText needs to disconnect this one
extern "C" {
void wxgtk_window_size_request_callback(GtkWidget *widget,
                                        GtkRequisition *requisition,
                                        wxWindow *win)
{
    int w, h;
    win->GetSize( &w, &h );
    if (w < 2)
        w = 2;
    if (h < 2)
        h = 2;

    requisition->height = h;
    requisition->width = w;
}
}

extern "C" {
static
void wxgtk_combo_size_request_callback(GtkWidget *widget,
                                       GtkRequisition *requisition,
                                       wxComboBox *win)
{
    // This callback is actually hooked into the text entry
    // of the combo box, not the GtkHBox.

    int w, h;
    win->GetSize( &w, &h );
    if (w < 2)
        w = 2;
    if (h < 2)
        h = 2;

    GtkCombo *gcombo = GTK_COMBO(win->m_widget);

    GtkRequisition entry_req;
    entry_req.width = 2;
    entry_req.height = 2;
    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
        (gcombo->button, &entry_req );

    requisition->width = w - entry_req.width;
    requisition->height = entry_req.height;
}
}

//-----------------------------------------------------------------------------
// "expose_event" of m_wxwindow
//-----------------------------------------------------------------------------

extern "C" {
static int gtk_window_expose_callback( GtkWidget *widget,
                                       GdkEventExpose *gdk_event,
                                       wxWindow *win )
{
    DEBUG_MAIN_THREAD

    if (g_isIdle)
        wxapp_install_idle_handler();

#ifdef __WXGTK20__
    // This callback gets called in drawing-idle time under
    // GTK 2.0, so we don't need to defer anything to idle
    // time anymore.

    GtkPizza *pizza = GTK_PIZZA( widget );
    if (gdk_event->window != pizza->bin_window) return FALSE;

#if 0
    if (win->GetName())
    {
        wxPrintf( wxT("OnExpose from ") );
        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
            wxPrintf( win->GetClassInfo()->GetClassName() );
        wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x,
                                         (int)gdk_event->area.y,
                                         (int)gdk_event->area.width,
                                         (int)gdk_event->area.height );
    }

    gtk_paint_box
    (
        win->m_wxwindow->style,
        pizza->bin_window,
        GTK_STATE_NORMAL,
        GTK_SHADOW_OUT,
        (GdkRectangle*) NULL,
        win->m_wxwindow,
        (char *)"button", // const_cast
        20,20,24,24
    );
#endif

    win->GetUpdateRegion() = wxRegion( gdk_event->region );

    win->GtkSendPaintEvents();


    // Let parent window draw window less widgets
    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
#else
    // This gets called immediately after an expose event
    // under GTK 1.2 so we collect the calls and wait for
    // the idle handler to pick things up.

    win->GetUpdateRegion().Union( gdk_event->area.x,
                                  gdk_event->area.y,
                                  gdk_event->area.width,
                                  gdk_event->area.height );
    win->m_clearRegion.Union( gdk_event->area.x,
                                  gdk_event->area.y,
                                  gdk_event->area.width,
                                  gdk_event->area.height );

    // Actual redrawing takes place in idle time.
    // win->GtkUpdate();
#endif

    return FALSE;
}
}

//-----------------------------------------------------------------------------
// "event" of m_wxwindow
//-----------------------------------------------------------------------------

#ifndef __WXGTK20__

// GTK thinks it is clever and filters out a certain amount of "unneeded"
// expose events. We need them, of course, so we override the main event
// procedure in GtkWidget by giving our own handler for all system events.
// There, we look for expose events ourselves whereas all other events are
// handled normally.

extern "C" {
static
gint gtk_window_event_event_callback( GtkWidget *widget,
                                      GdkEventExpose *event,
                                      wxWindow *win )
{
    if (event->type == GDK_EXPOSE)
    {
        gint ret = gtk_window_expose_callback( widget, event, win );
        return ret;
    }

    return FALSE;
}
}

#endif // !GTK+ 2

//-----------------------------------------------------------------------------
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------

#ifndef __WXGTK20__

// This callback is a complete replacement of the gtk_pizza_draw() function,
// which is disabled.

extern "C" {
static void gtk_window_draw_callback( GtkWidget *widget,
                                      GdkRectangle *rect,
                                      wxWindow *win )
{
    DEBUG_MAIN_THREAD

    if (g_isIdle)
        wxapp_install_idle_handler();

    // if there are any children we must refresh everything
    //
    // VZ: why?
    if ( !win->HasFlag(wxFULL_REPAINT_ON_RESIZE) &&
            win->GetChildren().IsEmpty() )
    {
        return;
    }

#if 0
    if (win->GetName())
    {
        wxPrintf( wxT("OnDraw from ") );
        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
            wxPrintf( win->GetClassInfo()->GetClassName() );
        wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x,
                                         (int)rect->y,
                                         (int)rect->width,
                                         (int)rect->height );
    }
#endif

#ifndef __WXUNIVERSAL__
    GtkPizza *pizza = GTK_PIZZA (widget);

    if (win->GetThemeEnabled() && win->GetBackgroundStyle() == wxBG_STYLE_SYSTEM)
    {
        wxWindow *parent = win->GetParent();
        while (parent && !parent->IsTopLevel())
            parent = parent->GetParent();
        if (!parent)
            parent = win;

        gtk_paint_flat_box (parent->m_widget->style,
                            pizza->bin_window,
                            GTK_STATE_NORMAL,
                            GTK_SHADOW_NONE,
                            rect,
                            parent->m_widget,
                            (char *)"base",
                            0, 0, -1, -1);
    }
#endif

    win->m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
    win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );

    // Update immediately, not in idle time.
    win->GtkUpdate();

#ifndef __WXUNIVERSAL__
    // Redraw child widgets
    GList *children = pizza->children;
    while (children)
    {
        GtkPizzaChild *child = (GtkPizzaChild*) children->data;
        children = children->next;

        GdkRectangle child_area;
        if (gtk_widget_intersect (child->widget, rect, &child_area))
        {
            gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
        }
    }
#endif
}
}

#endif

//-----------------------------------------------------------------------------
// "key_press_event" from any window
//-----------------------------------------------------------------------------

// set WXTRACE to this to see the key event codes on the console
#define TRACE_KEYS  _T("keyevent")

// translates an X key symbol to WXK_XXX value
//
// if isChar is true it means that the value returned will be used for EVT_CHAR
// event and then we choose the logical WXK_XXX, i.e. '/' for GDK_KP_Divide,
// for example, while if it is false it means that the value is going to be
// used for KEY_DOWN/UP events and then we translate GDK_KP_Divide to
// WXK_NUMPAD_DIVIDE
static long wxTranslateKeySymToWXKey(KeySym keysym, bool isChar)
{
    long key_code;

    switch ( keysym )
    {
        // Shift, Control and Alt don't generate the CHAR events at all
        case GDK_Shift_L:
        case GDK_Shift_R:
            key_code = isChar ? 0 : WXK_SHIFT;
            break;
        case GDK_Control_L:
        case GDK_Control_R:
            key_code = isChar ? 0 : WXK_CONTROL;
            break;
        case GDK_Meta_L:
        case GDK_Meta_R:
        case GDK_Alt_L:
        case GDK_Alt_R:
        case GDK_Super_L:
        case GDK_Super_R:
            key_code = isChar ? 0 : WXK_ALT;
            break;

        // neither do the toggle modifies
        case GDK_Scroll_Lock:
            key_code = isChar ? 0 : WXK_SCROLL;
            break;

        case GDK_Caps_Lock:
            key_code = isChar ? 0 : WXK_CAPITAL;
            break;

        case GDK_Num_Lock:
            key_code = isChar ? 0 : WXK_NUMLOCK;
            break;


        // various other special keys
        case GDK_Menu:
            key_code = WXK_MENU;
            break;

        case GDK_Help:
            key_code = WXK_HELP;
            break;

        case GDK_BackSpace:
            key_code = WXK_BACK;
            break;

        case GDK_ISO_Left_Tab:
        case GDK_Tab:
            key_code = WXK_TAB;
            break;

        case GDK_Linefeed:
        case GDK_Return:
            key_code = WXK_RETURN;
            break;

        case GDK_Clear:
            key_code = WXK_CLEAR;
            break;

        case GDK_Pause:
            key_code = WXK_PAUSE;
            break;

        case GDK_Select:
            key_code = WXK_SELECT;
            break;

        case GDK_Print:
            key_code = WXK_PRINT;
            break;

        case GDK_Execute:
            key_code = WXK_EXECUTE;
            break;

        case GDK_Escape:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?