1. Assorted Motif fixes

a) tear off menus
 b) native dialogs
 c) crash in ~wxWindow fixed
 d) compilation and linking fixes
2. test code removed from minimal sample, text one compiles without clipboard
3. wxAppBase/wxApp small fixes


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3074 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-07-21 16:10:18 +00:00
parent 20a8b34e2c
commit ee31c392ac
16 changed files with 633 additions and 462 deletions

View File

@@ -12,7 +12,7 @@ SUFFIXES = .cpp .c
DEFS = $(TOOLKIT_DEF) $(WXDEBUG_DEFINE)
LIBS = $(GUILIBS)
VPATH = .:${srcdir}:${srcdir}/xmcombo:${srcdir}/../common:${srcdir}/../generic:${EXTRA_VPATH}
VPATH = .:${srcdir}:${srcdir}/xmcombo:${srcdir}/../common:${srcdir}/../generic:${srcdir}/../html:${EXTRA_VPATH}
EXTRA_DIST = "${srcdir}/../common ${srcdir}/../generic ${srcdir}"

View File

@@ -10,7 +10,8 @@
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "app.h"
#pragma implementation "app.h"
#pragma implementation "appbase.h"
#endif
#include "wx/frame.h"
@@ -77,7 +78,7 @@ bool wxApp::Initialize()
wxClassInfo::InitializeClasses();
// GL: I'm annoyed ... I don't know where to put this and I don't want to
// GL: I'm annoyed ... I don't know where to put this and I don't want to
// create a module for that as it's part of the core.
#if wxUSE_THREADS
wxPendingEvents = new wxList();
@@ -261,7 +262,7 @@ int wxEntry( int argc, char *argv[] )
};
// Static member initialization
wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
wxApp::wxApp()
{
@@ -272,9 +273,7 @@ wxApp::wxApp()
m_appName = "";
argc = 0;
argv = NULL;
m_printMode = wxPRINT_POSTSCRIPT;
m_exitOnFrameDelete = TRUE;
m_auto3D = TRUE;
m_mainColormap = (WXColormap) NULL;
m_appContext = (WXAppContext) NULL;
@@ -339,10 +338,24 @@ void wxApp::ProcessXEvent(WXEvent* _event)
{
XEvent* event = (XEvent*) _event;
if ((event->type == KeyPress) && CheckForAccelerator(_event))
if (event->type == KeyPress)
{
// Do nothing! We intercepted and processed the event as an accelerator.
if (CheckForAccelerator(_event))
{
// Do nothing! We intercepted and processed the event as an
// accelerator.
return;
}
else if (CheckForKeyDown(_event))
{
// We intercepted and processed the key down event
return;
}
else
{
XtDispatchEvent(event);
return;
}
}
else if (event->type == PropertyNotify)
{
@@ -351,10 +364,10 @@ void wxApp::ProcessXEvent(WXEvent* _event)
}
else if (event->type == ResizeRequest)
{
/* Terry Gitnick <terryg@scientech.com> - 1/21/98
* If resize event, don't resize until the last resize event for this
* window is recieved. Prevents flicker as windows are resized.
*/
/* Terry Gitnick <terryg@scientech.com> - 1/21/98
* If resize event, don't resize until the last resize event for this
* window is recieved. Prevents flicker as windows are resized.
*/
Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
Window win = event->xany.window;
@@ -527,21 +540,6 @@ void wxApp::ProcessPendingEvents()
}
#endif // wxUSE_THREADS
wxLog* wxApp::CreateLogTarget()
{
return new wxLogGui;
}
wxWindow* wxApp::GetTopWindow() const
{
if (m_topWindow)
return m_topWindow;
else if (wxTopLevelWindows.GetCount() > 0)
return wxTopLevelWindows.GetFirst()->GetData();
else
return NULL;
}
// Create an application context
bool wxApp::OnInitGui()
{
@@ -631,6 +629,37 @@ bool wxApp::CheckForAccelerator(WXEvent* event)
return FALSE;
}
bool wxApp::CheckForKeyDown(WXEvent* event)
{
XEvent* xEvent = (XEvent*) event;
// VZ: this code doesn't work for me because it never finds the correct
// window. Also, if we go this way, we should generate KEY_UP and
// CHAR events as well, not only KEY_DOWN.
#if 0
if (xEvent->xany.type == KeyPress)
{
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
xEvent->xany.window);
wxWindow* win = NULL;
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
widget = XtParent(widget);
if (!widget || !win)
return FALSE;
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
win->ProcessEvent( keyEvent );
return (keyEvent.GetSkipped() != TRUE);
}
#endif // 0
return FALSE;
}
void wxExit()
{
int retValue = 0;
@@ -659,3 +688,32 @@ bool wxYield()
return TRUE;
}
// TODO use XmGetPixmap (?) to get the really standard icons!
#include "wx/generic/info.xpm"
#include "wx/generic/error.xpm"
#include "wx/generic/question.xpm"
#include "wx/generic/warning.xpm"
wxIcon
wxApp::GetStdIcon(int which) const
{
switch(which)
{
case wxICON_INFORMATION:
return wxIcon(info_xpm);
case wxICON_QUESTION:
return wxIcon(question_xpm);
case wxICON_EXCLAMATION:
return wxIcon(warning_xpm);
default:
wxFAIL_MSG("requested non existent standard icon");
// still fall through
case wxICON_HAND:
return wxIcon(error_xpm);
}
}

View File

@@ -58,7 +58,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
// Menus
// Construct a menu with optional title (then use append)
wxMenu::wxMenu(const wxString& title, const wxFunction func)
void wxMenu::Init(const wxString& title,
long style
#ifdef WXWIN_COMPATIBILITY
, const wxFunction func
#endif
)
{
m_title = title;
m_parent = (wxEvtHandler*) NULL;
@@ -66,6 +71,7 @@ wxMenu::wxMenu(const wxString& title, const wxFunction func)
m_noItems = 0;
m_menuBar = NULL;
m_pInvokingWindow = NULL;
m_style = style;
//// Motif-specific members
m_numColumns = 1;
@@ -87,7 +93,9 @@ wxMenu::wxMenu(const wxString& title, const wxFunction func)
m_foregroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT);
m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
#ifdef WXWIN_COMPATIBILITY
Callback(func);
#endif
}
// The wxWindow destructor will take care of deleting the submenus.
@@ -426,72 +434,6 @@ void wxMenu::UpdateUI(wxEvtHandler* source)
}
}
bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
{
Widget widget = (Widget) GetMainWidget();
/* The menuId field seems to be usused, so we'll use it to
indicate whether a menu is popped up or not:
0: Not currently created as a popup
-1: Created as a popup, but not active
1: Active popup.
*/
if (menu->GetParent() && (menu->GetId() != -1))
return FALSE;
if (menu->GetMainWidget()) {
menu->DestroyMenu(TRUE);
}
menu->SetId(1); /* Mark as popped-up */
menu->CreateMenu(NULL, widget, menu);
menu->SetInvokingWindow(this);
menu->UpdateUI();
// menu->SetParent(parent);
// parent->children->Append(menu); // Store menu for later deletion
Widget menuWidget = (Widget) menu->GetMainWidget();
int rootX = 0;
int rootY = 0;
int deviceX = x;
int deviceY = y;
/*
if (this->IsKindOf(CLASSINFO(wxCanvas)))
{
wxCanvas *canvas = (wxCanvas *) this;
deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
}
*/
Display *display = XtDisplay (widget);
Window rootWindow = RootWindowOfScreen (XtScreen((Widget)widget));
Window thisWindow = XtWindow (widget);
Window childWindow;
XTranslateCoordinates (display, thisWindow, rootWindow, (int) deviceX, (int) deviceY,
&rootX, &rootY, &childWindow);
XButtonPressedEvent event;
event.type = ButtonPress;
event.button = 1;
event.x = deviceX;
event.y = deviceY;
event.x_root = rootX;
event.y_root = rootY;
XmMenuPosition (menuWidget, &event);
XtManageChild (menuWidget);
return TRUE;
}
// Menu Bar
wxMenuBar::wxMenuBar()
{
@@ -836,13 +778,20 @@ bool wxMenuBar::CreateMenuBar(wxFrame* parent)
wxString title(m_titles[i]);
menu->SetButtonWidget(menu->CreateMenu (this, menuBarW, menu, title, TRUE));
/*
* COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
*/
wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
if (strcmp (wxBuffer, "Help") == 0)
XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
// tear off menu support
#if (XmVersion >= 1002)
if ( menu->IsTearOff() )
{
XtVaSetValues(GetWidget(menu),
XmNtearOffModel, XmTEAR_OFF_ENABLED,
NULL);
#endif
}
}
SetBackgroundColour(m_backgroundColour);

View File

@@ -6,21 +6,87 @@
// Created: 04/01/98
// RCS-ID: $$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
#ifdef __GNUG__
#pragma implementation "msgdlg.h"
#pragma implementation "msgdlg.h"
#endif
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include <X11/Xlib.h>
#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include "wx/app.h"
#include "wx/intl.h"
#include "wx/motif/msgdlg.h"
#include "wx/motif/private.h"
// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------
#if !USE_SHARED_LIBRARY
IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
#endif
wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption,
long style, const wxPoint& pos)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// the callbacks for message box buttons
// ----------------------------------------------------------------------------
// the common part
static void msgboxCallBack(Widget w, int client_data, int id)
{
// close the dialog
XtUnmanageChild(w);
wxMessageDialog *dlg = (wxMessageDialog *)client_data;
dlg->SetResult(id);
}
static void msgboxCallBackOk(Widget w,
int client_data,
XmAnyCallbackStruct *call_data)
{
msgboxCallBack(w, client_data, wxID_OK);
}
static void msgboxCallBackCancel(Widget w,
int client_data,
XmAnyCallbackStruct *call_data)
{
msgboxCallBack(w, client_data, wxID_CANCEL);
}
static void msgboxCallBackClose(Widget w,
int client_data,
XmAnyCallbackStruct *call_data)
{
msgboxCallBack(w, client_data, wxID_CANCEL);
}
// ----------------------------------------------------------------------------
// wxMessageDialog
// ----------------------------------------------------------------------------
wxMessageDialog::wxMessageDialog(wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
const wxPoint& pos)
{
m_caption = caption;
m_message = message;
@@ -30,7 +96,119 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, cons
int wxMessageDialog::ShowModal()
{
// TODO
return wxID_CANCEL;
Widget (*dialogCreateFunction)(Widget, String, ArgList, Cardinal) = NULL;
if ( m_dialogStyle & wxYES_NO )
{
// if we have [Yes], it must be a question
dialogCreateFunction = XmCreateQuestionDialog;
// TODO we could support this by using the help button...
wxASSERT_MSG( !(m_dialogStyle & wxCANCEL), "not supported" );
}
else if ( m_dialogStyle & wxICON_STOP )
{
// error dialog is the one with error icon...
dialogCreateFunction = XmCreateErrorDialog;
}
else if ( m_dialogStyle & wxICON_EXCLAMATION )
{
// ...and the warning dialog too
dialogCreateFunction = XmCreateWarningDialog;
}
else
{
// finally, use the info dialog by default
dialogCreateFunction = XmCreateInformationDialog;
}
// prepare the arg list
Arg args[2];
int ac = 0;
wxXmString text(m_message);
wxXmString title(m_caption);
XtSetArg(args[ac], XmNmessageString, text()); ac++;
XtSetArg(args[ac], XmNdialogTitle, title()); ac++;
// do create message box
Widget wParent = m_parent ? GetWidget(m_parent) : NULL;
if ( !wParent )
{
wxWindow *window = wxTheApp->GetTopWindow();
if ( !window )
{
wxFAIL_MSG("can't show message box without parent window");
return wxID_CANCEL;
}
wParent = GetWidget(window);
}
Widget wMsgBox = (*dialogCreateFunction)(wParent, "", args, ac);
wxCHECK_MSG( wMsgBox, wxID_CANCEL, "msg box creation failed" );
// remove the [Help] button which wouldn't do anything anyhow
XtUnmanageChild(XmMessageBoxGetChild(wMsgBox, XmDIALOG_HELP_BUTTON));
// and the [Cancel] button too if we were not asked for it
if ( !(m_dialogStyle & wxCANCEL) )
{
Widget wBtnCancel = XmMessageBoxGetChild(wMsgBox,
XmDIALOG_CANCEL_BUTTON);
// ... unless it's a wxYES_NO dialog in which case we just rename
// [Cancel] to [No] instead
if ( m_dialogStyle & wxYES_NO )
{
Widget wBtnOk = XmMessageBoxGetChild(wMsgBox,
XmDIALOG_OK_BUTTON);
wxXmString yes(_("Yes")), no(_("No"));
XtVaSetValues(wBtnOk, XmNlabelString, yes(), NULL);
XtVaSetValues(wBtnCancel, XmNlabelString, no(), NULL);
}
else
{
XtUnmanageChild(wBtnCancel);
}
}
// set the callbacks for the message box buttons
XtAddCallback(wMsgBox, XmNokCallback,
(XtCallbackProc)msgboxCallBackOk, (XtPointer)this);
XtAddCallback(wMsgBox, XmNcancelCallback,
(XtCallbackProc)msgboxCallBackCancel, (XtPointer)this);
XtAddCallback(wMsgBox, XmNunmapCallback,
(XtCallbackProc)msgboxCallBackClose, (XtPointer)this);
// show it as a modal dialog
XtManageChild(wMsgBox);
XtAddGrab(wMsgBox, True, False);
// the m_result will be changed when message box goes away
m_result = -1;
// local message loop
XtAppContext context = XtWidgetToApplicationContext(wParent);
XEvent event;
while ( m_result == -1 )
{
XtAppNextEvent(context, &event);
XtDispatchEvent(&event);
}
// translate the result if necessary
if ( m_dialogStyle & wxYES_NO )
{
if ( m_result == wxID_OK )
m_result = wxID_YES;
else if ( m_result == wxID_CANCEL )
m_result = wxID_NO;
}
return m_result;
}

View File

@@ -53,6 +53,7 @@
#include <Xm/ScrollBar.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/RowColumn.h> // for XmMenuPosition
#include "wx/motif/private.h"
@@ -369,6 +370,9 @@ wxWindow::~wxWindow()
ClearUpdateRects();
if ( m_parent )
m_parent->RemoveChild( this );
// If m_drawingArea, we're a fully-fledged window with drawing area,
// scrollbars etc. (what wxCanvas used to be)
if ( m_drawingArea )
@@ -1040,6 +1044,76 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
#endif // wxUSE_TOOLTIPS
// ----------------------------------------------------------------------------
// popup menus
// ----------------------------------------------------------------------------
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
{
Widget widget = (Widget) GetMainWidget();
/* The menuId field seems to be usused, so we'll use it to
indicate whether a menu is popped up or not:
0: Not currently created as a popup
-1: Created as a popup, but not active
1: Active popup.
*/
if (menu->GetParent() && (menu->GetId() != -1))
return FALSE;
if (menu->GetMainWidget()) {
menu->DestroyMenu(TRUE);
}
menu->SetId(1); /* Mark as popped-up */
menu->CreateMenu(NULL, widget, menu);
menu->SetInvokingWindow(this);
menu->UpdateUI();
// menu->SetParent(parent);
// parent->children->Append(menu); // Store menu for later deletion
Widget menuWidget = (Widget) menu->GetMainWidget();
int rootX = 0;
int rootY = 0;
int deviceX = x;
int deviceY = y;
/*
if (this->IsKindOf(CLASSINFO(wxCanvas)))
{
wxCanvas *canvas = (wxCanvas *) this;
deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
}
*/
Display *display = XtDisplay (widget);
Window rootWindow = RootWindowOfScreen (XtScreen((Widget)widget));
Window thisWindow = XtWindow (widget);
Window childWindow;
XTranslateCoordinates (display, thisWindow, rootWindow, (int) deviceX, (int) deviceY,
&rootX, &rootY, &childWindow);
XButtonPressedEvent event;
event.type = ButtonPress;
event.button = 1;
event.x = deviceX;
event.y = deviceY;
event.x_root = rootX;
event.y_root = rootY;
XmMenuPosition (menuWidget, &event);
XtManageChild (menuWidget);
return TRUE;
}
// ---------------------------------------------------------------------------
// moving and resizing
// ---------------------------------------------------------------------------