window.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 2,007 行 · 第 1/5 页
CPP
2,007 行
if (win->m_wxwindow)
{
GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow);
xx += pizza->xoffset;
yy += pizza->yoffset;
}
wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
while (node)
{
wxWindowGTK *child = node->GetData();
node = node->GetNext();
if (!child->IsShown())
continue;
if (child->IsTransparentForMouse())
{
// wxStaticBox is transparent in the box itself
int xx1 = child->m_x;
int yy1 = child->m_y;
int xx2 = child->m_x + child->m_width;
int yy2 = child->m_y + child->m_height;
// left
if (((xx >= xx1) && (xx <= xx1+10) && (yy >= yy1) && (yy <= yy2)) ||
// right
((xx >= xx2-10) && (xx <= xx2) && (yy >= yy1) && (yy <= yy2)) ||
// top
((xx >= xx1) && (xx <= xx2) && (yy >= yy1) && (yy <= yy1+10)) ||
// bottom
((xx >= xx1) && (xx <= xx2) && (yy >= yy2-1) && (yy <= yy2)))
{
win = child;
x -= child->m_x;
y -= child->m_y;
break;
}
}
else
{
if ((child->m_wxwindow == (GtkWidget*) NULL) &&
(child->m_x <= xx) &&
(child->m_y <= yy) &&
(child->m_x+child->m_width >= xx) &&
(child->m_y+child->m_height >= yy))
{
win = child;
x -= child->m_x;
y -= child->m_y;
break;
}
}
}
return win;
}
//-----------------------------------------------------------------------------
// "button_press_event"
//-----------------------------------------------------------------------------
extern "C" {
static gint gtk_window_button_press_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
/*
wxPrintf( wxT("1) OnButtonPress from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
wxPrintf( wxT(".\n") );
*/
if (!win->m_hasVMT) return FALSE;
if (g_blockEventsOnDrag) return TRUE;
if (g_blockEventsOnScroll) return TRUE;
if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
{
gtk_widget_grab_focus( win->m_wxwindow );
/*
wxPrintf( wxT("GrabFocus from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
wxPrintf( wxT(".\n") );
*/
}
// GDK sends surplus button down event
// before a double click event. We
// need to filter these out.
if (gdk_event->type == GDK_BUTTON_PRESS)
{
GdkEvent *peek_event = gdk_event_peek();
if (peek_event)
{
if ((peek_event->type == GDK_2BUTTON_PRESS) ||
(peek_event->type == GDK_3BUTTON_PRESS))
{
gdk_event_free( peek_event );
return TRUE;
}
else
{
gdk_event_free( peek_event );
}
}
}
wxEventType event_type = wxEVT_NULL;
// GdkDisplay is a GTK+ 2.2.0 thing
#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 2, 0)
if ( gdk_event->type == GDK_2BUTTON_PRESS &&
!gtk_check_version(2,2,0) &&
gdk_event->button >= 1 && gdk_event->button <= 3 )
{
// Reset GDK internal timestamp variables in order to disable GDK
// triple click events. GDK will then next time believe no button has
// been clicked just before, and send a normal button click event.
GdkDisplay* display = gtk_widget_get_display (widget);
display->button_click_time[1] = 0;
display->button_click_time[0] = 0;
}
#endif // GTK 2+
if (gdk_event->button == 1)
{
// note that GDK generates triple click events which are not supported
// by wxWidgets but still have to be passed to the app as otherwise
// clicks would simply go missing
switch (gdk_event->type)
{
// we shouldn't get triple clicks at all for GTK2 because we
// suppress them artificially using the code above but we still
// should map them to something for GTK1 and not just ignore them
// as this would lose clicks
case GDK_3BUTTON_PRESS: // we could also map this to DCLICK...
case GDK_BUTTON_PRESS:
event_type = wxEVT_LEFT_DOWN;
break;
case GDK_2BUTTON_PRESS:
event_type = wxEVT_LEFT_DCLICK;
break;
default:
// just to silence gcc warnings
;
}
}
else if (gdk_event->button == 2)
{
switch (gdk_event->type)
{
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_PRESS:
event_type = wxEVT_MIDDLE_DOWN;
break;
case GDK_2BUTTON_PRESS:
event_type = wxEVT_MIDDLE_DCLICK;
break;
default:
;
}
}
else if (gdk_event->button == 3)
{
switch (gdk_event->type)
{
case GDK_3BUTTON_PRESS:
case GDK_BUTTON_PRESS:
event_type = wxEVT_RIGHT_DOWN;
break;
case GDK_2BUTTON_PRESS:
event_type = wxEVT_RIGHT_DCLICK;
break;
default:
;
}
}
else if (gdk_event->button == 4 || gdk_event->button == 5)
{
if (gdk_event->type == GDK_BUTTON_PRESS )
{
event_type = wxEVT_MOUSEWHEEL;
}
}
if ( event_type == wxEVT_NULL )
{
// unknown mouse button or click type
return FALSE;
}
wxMouseEvent event( event_type );
InitMouseEvent( win, event, gdk_event );
AdjustEventButtonState(event);
// wxListBox actually get mouse events from the item, so we need to give it
// a chance to correct this
win->FixUpMouseEvent(widget, event.m_x, event.m_y);
// find the correct window to send the event too: it may be a different one
// from the one which got it at GTK+ level because some control don't have
// their own X window and thus cannot get any events.
if ( !g_captureWindow )
win = FindWindowForMouseEvent(win, event.m_x, event.m_y);
gs_timeLastClick = gdk_event->time;
#ifndef __WXGTK20__
if (event_type == wxEVT_LEFT_DCLICK)
{
// GTK 1.2 crashes when intercepting double
// click events from both wxSpinButton and
// wxSpinCtrl
if (GTK_IS_SPIN_BUTTON(win->m_widget))
{
// Just disable this event for now.
return FALSE;
}
}
#endif
if (win->GetEventHandler()->ProcessEvent( event ))
{
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
return TRUE;
}
if (event_type == wxEVT_RIGHT_DOWN)
{
// generate a "context menu" event: this is similar to right mouse
// click under many GUIs except that it is generated differently
// (right up under MSW, ctrl-click under Mac, right down here) and
//
// (a) it's a command event and so is propagated to the parent
// (b) under some ports it can be generated from kbd too
// (c) it uses screen coords (because of (a))
wxContextMenuEvent evtCtx(
wxEVT_CONTEXT_MENU,
win->GetId(),
win->ClientToScreen(event.GetPosition()));
evtCtx.SetEventObject(win);
return win->GetEventHandler()->ProcessEvent(evtCtx);
}
return FALSE;
}
}
//-----------------------------------------------------------------------------
// "button_release_event"
//-----------------------------------------------------------------------------
extern "C" {
static gint gtk_window_button_release_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT) return FALSE;
if (g_blockEventsOnDrag) return FALSE;
if (g_blockEventsOnScroll) return FALSE;
if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
wxEventType event_type = wxEVT_NULL;
switch (gdk_event->button)
{
case 1:
event_type = wxEVT_LEFT_UP;
break;
case 2:
event_type = wxEVT_MIDDLE_UP;
break;
case 3:
event_type = wxEVT_RIGHT_UP;
break;
default:
// unknwon button, don't process
return FALSE;
}
wxMouseEvent event( event_type );
InitMouseEvent( win, event, gdk_event );
AdjustEventButtonState(event);
// same wxListBox hack as above
win->FixUpMouseEvent(widget, event.m_x, event.m_y);
if ( !g_captureWindow )
win = FindWindowForMouseEvent(win, event.m_x, event.m_y);
if (win->GetEventHandler()->ProcessEvent( event ))
{
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
return TRUE;
}
return FALSE;
}
}
//-----------------------------------------------------------------------------
// "motion_notify_event"
//-----------------------------------------------------------------------------
extern "C" {
static gint gtk_window_motion_notify_callback( GtkWidget *widget,
GdkEventMotion *gdk_event,
wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT) return FALSE;
if (g_blockEventsOnDrag) return FALSE;
if (g_blockEventsOnScroll) return FALSE;
if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
if (gdk_event->is_hint)
{
int x = 0;
int y = 0;
GdkModifierType state;
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
gdk_event->x = x;
gdk_event->y = y;
}
/*
printf( "OnMotion from " );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
printf( win->GetClassInfo()->GetClassName() );
printf( ".\n" );
*/
wxMouseEvent event( wxEVT_MOTION );
InitMouseEvent(win, event, gdk_event);
if ( g_captureWindow )
{
// synthetize a mouse enter or leave event if needed
GdkWindow *winUnderMouse = gdk_window_at_pointer(NULL, NULL);
// This seems to be necessary and actually been added to
// GDK itself in version 2.0.X
gdk_flush();
bool hasMouse = winUnderMouse == gdk_event->window;
if ( hasMouse != g_captureWindowHasMouse )
{
// the mouse changed window
g_captureWindowHasMouse = hasMouse;
wxMouseEvent event(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW
: wxEVT_LEAVE_WINDOW);
InitMouseEvent(win, event, gdk_event);
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
}
}
else // no capture
{
win = FindWindowForMouseEvent(win, event.m_x, event.m_y);
}
if ( !g_captureWindow )
{
wxSetCursorEvent cevent( event.m_x, event.m_y );
if (win->GetEventHandler()->ProcessEvent( cevent ))
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?