Some more wxMotif stuff: menus
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@753 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
distrib/*.*
|
distrib/msw/*.rsp
|
||||||
|
distrib/msw/*.bat
|
||||||
|
|
||||||
docs/readme.txt
|
docs/readme.txt
|
||||||
docs/install.txt
|
docs/install.txt
|
||||||
|
@@ -893,6 +893,7 @@ typedef void* WXColormap;
|
|||||||
typedef void WXDisplay;
|
typedef void WXDisplay;
|
||||||
typedef void WXEvent;
|
typedef void WXEvent;
|
||||||
typedef void* WXCursor;
|
typedef void* WXCursor;
|
||||||
|
typedef void* WXPixmap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,95 +1,19 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
#ifndef _WX_MENUITEM_H_BASE_
|
||||||
// Name: menuitem.h
|
#define _WX_MENUITEM_H_BASE_
|
||||||
// Purpose: wxMenuItem class
|
|
||||||
// Author: Vadim Zeitlin
|
|
||||||
// Modified by:
|
|
||||||
// Created: 11.11.97
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
|
||||||
// Licence: wxWindows license
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef _MENUITEM_H
|
#if defined(__WXMSW__)
|
||||||
#define _MENUITEM_H
|
#include "wx/msw/menuitem.h"
|
||||||
|
#elif defined(__WXMOTIF__)
|
||||||
#ifdef __GNUG__
|
#include "wx/motif/menuitem.h"
|
||||||
#pragma interface "menuitem.h"
|
#elif defined(__WXGTK__)
|
||||||
|
#include "wx/gtk/menuitem.h"
|
||||||
|
#elif defined(__WXQT__)
|
||||||
|
#include "wx/qt/menuitem.h"
|
||||||
|
#elif defined(__WXMAC__)
|
||||||
|
#include "wx/mac/menuitem.h"
|
||||||
|
#elif defined(__WXSTUBS__)
|
||||||
|
#include "wx/stubs/menuitem.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// headers
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "wx/setup.h"
|
|
||||||
|
|
||||||
// an exception to the general rule that a normal header doesn't include other
|
|
||||||
// headers - only because ownerdrw.h is not always included and I don't want
|
|
||||||
// to write #ifdef's everywhere...
|
|
||||||
#if USE_OWNER_DRAWN
|
|
||||||
#include "wx/ownerdrw.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
// _WX_MENUITEM_H_BASE_
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// constants
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// id for a separator line in the menu (invalid for normal item)
|
|
||||||
#define ID_SEPARATOR (-1)
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxMenuItem: an item in the menu, optionally implements owner-drawn behaviour
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
class WXDLLEXPORT wxMenuItem: public wxObject
|
|
||||||
#if USE_OWNER_DRAWN
|
|
||||||
, public wxOwnerDrawn
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenuItem)
|
|
||||||
|
|
||||||
public:
|
|
||||||
// ctor & dtor
|
|
||||||
wxMenuItem(wxMenu *pParentMenu = NULL, int id = ID_SEPARATOR,
|
|
||||||
const wxString& strName = "", const wxString& wxHelp = "",
|
|
||||||
bool bCheckable = FALSE, wxMenu *pSubMenu = NULL);
|
|
||||||
virtual ~wxMenuItem();
|
|
||||||
|
|
||||||
// accessors (some more are inherited from wxOwnerDrawn or are below)
|
|
||||||
bool IsSeparator() const { return m_idItem == ID_SEPARATOR; }
|
|
||||||
bool IsEnabled() const { return m_bEnabled; }
|
|
||||||
bool IsChecked() const { return m_bChecked; }
|
|
||||||
|
|
||||||
int GetId() const { return m_idItem; }
|
|
||||||
const wxString& GetHelp() const { return m_strHelp; }
|
|
||||||
wxMenu *GetSubMenu() const { return m_pSubMenu; }
|
|
||||||
|
|
||||||
// operations
|
|
||||||
void SetName(const wxString& strName) { m_strName = strName; }
|
|
||||||
void SetHelp(const wxString& strHelp) { m_strHelp = strHelp; }
|
|
||||||
|
|
||||||
void Enable(bool bDoEnable = TRUE);
|
|
||||||
void Check(bool bDoCheck = TRUE);
|
|
||||||
|
|
||||||
void DeleteSubMenu();
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_idItem; // numeric id of the item
|
|
||||||
wxString m_strHelp; // associated help string
|
|
||||||
wxMenu *m_pSubMenu, // may be NULL
|
|
||||||
*m_pParentMenu; // menu this item is contained in
|
|
||||||
bool m_bEnabled, // enabled or greyed?
|
|
||||||
m_bChecked; // checked? (only if checkable)
|
|
||||||
|
|
||||||
#if USE_OWNER_DRAWN
|
|
||||||
// wxOwnerDrawn base class already has these variables - nothing to do
|
|
||||||
|
|
||||||
#else //!owner drawn
|
|
||||||
bool m_bCheckable; // can be checked?
|
|
||||||
wxString m_strName; // name or label of the item
|
|
||||||
|
|
||||||
public:
|
|
||||||
const wxString& GetName() const { return m_strName; }
|
|
||||||
bool IsCheckable() const { return m_bCheckable; }
|
|
||||||
#endif //owner drawn
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_MENUITEM_H
|
|
||||||
|
@@ -147,9 +147,12 @@ public:
|
|||||||
//// Motif-specific
|
//// Motif-specific
|
||||||
|
|
||||||
WXWidget GetMenuBarWidget() const ;
|
WXWidget GetMenuBarWidget() const ;
|
||||||
WXWidget GetShellWidget() const { return m_frameShell; }
|
inline WXWidget GetShellWidget() const { return m_frameShell; }
|
||||||
WXWidget GetWorkAreaWidget() const { return m_workArea; }
|
inline WXWidget GetWorkAreaWidget() const { return m_workArea; }
|
||||||
WXWidget GetClientAreaWidget() const { return m_clientArea; }
|
inline WXWidget GetClientAreaWidget() const { return m_clientArea; }
|
||||||
|
|
||||||
|
// The widget that can have children on it
|
||||||
|
WXWidget GetClientWidget() const;
|
||||||
bool GetVisibleStatus() const { return m_visibleStatus; }
|
bool GetVisibleStatus() const { return m_visibleStatus; }
|
||||||
|
|
||||||
bool PreResize();
|
bool PreResize();
|
||||||
|
@@ -90,7 +90,27 @@ public:
|
|||||||
|
|
||||||
//// Motif-specific
|
//// Motif-specific
|
||||||
inline WXWidget GetButtonWidget() const { return m_buttonWidget; }
|
inline WXWidget GetButtonWidget() const { return m_buttonWidget; }
|
||||||
|
inline void SetButtonWidget(WXWidget buttonWidget) { m_buttonWidget = buttonWidget; }
|
||||||
inline WXWidget GetMainWidget() const { return m_menuWidget; }
|
inline WXWidget GetMainWidget() const { return m_menuWidget; }
|
||||||
|
inline wxMenu* GetParent() const { return m_menuParent; }
|
||||||
|
inline int GetId() const { return m_menuId; }
|
||||||
|
inline void SetId(int id) { m_menuId = id; }
|
||||||
|
inline void SetMenuBar(wxMenuBar* menuBar) { m_menuBar = menuBar; }
|
||||||
|
inline wxMenuBar* GetMenuBar() const { return m_menuBar; }
|
||||||
|
|
||||||
|
void CreatePopup (WXWidget logicalParent, int x, int y);
|
||||||
|
void DestroyPopup (void);
|
||||||
|
void ShowPopup (int x, int y);
|
||||||
|
void HidePopup (void);
|
||||||
|
|
||||||
|
WXWidget CreateMenu(wxMenuBar *menuBar, WXWidget parent, wxMenu *topMenu,
|
||||||
|
const wxString& title = "", bool isPulldown = FALSE);
|
||||||
|
|
||||||
|
// For popups, need to destroy, then recreate menu for a different (or
|
||||||
|
// possibly same) window, since the parent may change.
|
||||||
|
void DestroyMenu(bool full);
|
||||||
|
WXWidget FindMenuItem(int id, wxMenuItem **it = NULL) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxFunction m_callback;
|
wxFunction m_callback;
|
||||||
|
|
||||||
@@ -107,7 +127,7 @@ public:
|
|||||||
WXWidget m_popupShell; // For holding the popup shell widget
|
WXWidget m_popupShell; // For holding the popup shell widget
|
||||||
WXWidget m_buttonWidget; // The actual string, so we can grey it etc.
|
WXWidget m_buttonWidget; // The actual string, so we can grey it etc.
|
||||||
int m_menuId;
|
int m_menuId;
|
||||||
wxMenu* m_topMenu ;
|
wxMenu* m_topLevelMenu ;
|
||||||
wxMenu* m_menuParent;
|
wxMenu* m_menuParent;
|
||||||
bool m_ownedByMenuBar;
|
bool m_ownedByMenuBar;
|
||||||
};
|
};
|
||||||
@@ -157,14 +177,22 @@ class WXDLLEXPORT wxMenuBar: public wxEvtHandler
|
|||||||
inline int GetMenuCount() const { return m_menuCount; }
|
inline int GetMenuCount() const { return m_menuCount; }
|
||||||
inline wxMenu* GetMenu(int i) const { return m_menus[i]; }
|
inline wxMenu* GetMenu(int i) const { return m_menus[i]; }
|
||||||
|
|
||||||
|
//// Motif-specific
|
||||||
|
inline wxFrame* GetMenuBarFrame() const { return m_menuBarFrame; }
|
||||||
|
inline void SetMenuBarFrame(wxFrame* frame) { m_menuBarFrame = frame; }
|
||||||
|
inline WXWidget GetMainWidget() const { return m_mainWidget; }
|
||||||
|
inline void SetMainWidget(WXWidget widget) { m_mainWidget = widget; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxEvtHandler * m_eventHandler;
|
wxEvtHandler * m_eventHandler;
|
||||||
int m_menuCount;
|
int m_menuCount;
|
||||||
wxMenu ** m_menus;
|
wxMenu ** m_menus;
|
||||||
wxString * m_titles;
|
wxString * m_titles;
|
||||||
wxFrame * m_menuBarFrame;
|
wxFrame * m_menuBarFrame;
|
||||||
/* TODO: data that represents the actual menubar when created.
|
|
||||||
*/
|
//// Motif-specific
|
||||||
|
WXWidget m_mainWidget;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _WX_MENU_H_
|
#endif // _WX_MENU_H_
|
||||||
|
@@ -23,6 +23,11 @@ extern wxHashTable *wxWidgetHashTable;
|
|||||||
extern void wxDeleteWindowFromTable(Widget w);
|
extern void wxDeleteWindowFromTable(Widget w);
|
||||||
extern wxWindow *wxGetWindowFromTable(Widget w);
|
extern wxWindow *wxGetWindowFromTable(Widget w);
|
||||||
extern bool wxAddWindowToTable(Widget w, wxWindow *win);
|
extern bool wxAddWindowToTable(Widget w, wxWindow *win);
|
||||||
|
extern char wxFindMnemonic(const char* s);
|
||||||
|
extern char * wxFindAccelerator (char *s);
|
||||||
|
extern XmString wxFindAcceleratorText (char *s);
|
||||||
|
extern int wxCharCodeXToWX(KeySym keySym);
|
||||||
|
extern KeySym wxCharCodeWXToX(int id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_PRIVATE_H_
|
// _WX_PRIVATE_H_
|
||||||
|
@@ -448,7 +448,13 @@ public:
|
|||||||
// to the window via validators.
|
// to the window via validators.
|
||||||
virtual void InitDialog();
|
virtual void InitDialog();
|
||||||
|
|
||||||
/// MOTIF-specific
|
/// Motif-specific
|
||||||
|
|
||||||
|
void CanvasGetSize(int* width, int* height) const; // If have drawing area
|
||||||
|
void CanvasGetClientSize(int *width, int *height) const;
|
||||||
|
void CanvasGetPosition(int *x, int *y) const; // If have drawing area
|
||||||
|
void CanvasSetClientSize(int width, int size);
|
||||||
|
void CanvasSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
|
||||||
|
|
||||||
// Gives window a chance to do something in response to a size
|
// Gives window a chance to do something in response to a size
|
||||||
// message, e.g. arrange status bar, toolbar etc.
|
// message, e.g. arrange status bar, toolbar etc.
|
||||||
@@ -456,12 +462,18 @@ public:
|
|||||||
|
|
||||||
// Get main widget for this window
|
// Get main widget for this window
|
||||||
virtual WXWidget GetMainWidget() const;
|
virtual WXWidget GetMainWidget() const;
|
||||||
|
// Get the client widget for this window (something we can
|
||||||
|
// create other windows on)
|
||||||
|
virtual WXWidget GetClientWidget() const;
|
||||||
virtual void SetMainWidget(WXWidget w) { m_mainWidget = w; }
|
virtual void SetMainWidget(WXWidget w) { m_mainWidget = w; }
|
||||||
|
|
||||||
// Get the underlying X window and display
|
// Get the underlying X window and display
|
||||||
virtual WXWindow GetXWindow() const;
|
virtual WXWindow GetXWindow() const;
|
||||||
virtual WXDisplay *GetXDisplay() const;
|
virtual WXDisplay *GetXDisplay() const;
|
||||||
|
|
||||||
|
// Generates a paint event
|
||||||
|
virtual void DoPaint();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//// PROTECTED DATA
|
//// PROTECTED DATA
|
||||||
protected:
|
protected:
|
||||||
@@ -507,15 +519,32 @@ public:
|
|||||||
int m_returnCode;
|
int m_returnCode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// MOTIF-specific
|
/// Motif-specific
|
||||||
bool m_button1Pressed;
|
bool m_button1Pressed;
|
||||||
bool m_button2Pressed;
|
bool m_button2Pressed;
|
||||||
bool m_button3Pressed;
|
bool m_button3Pressed;
|
||||||
|
// For double-click detection
|
||||||
|
long m_lastTS; // last timestamp
|
||||||
|
int m_lastButton; // last pressed button
|
||||||
|
wxList m_updateRects; // List of wxRectangles representing damaged region
|
||||||
protected:
|
protected:
|
||||||
WXWidget m_mainWidget;
|
WXWidget m_mainWidget;
|
||||||
|
WXWidget m_hScrollBar;
|
||||||
|
WXWidget m_vScrollBar;
|
||||||
|
WXWidget m_borderWidget;
|
||||||
|
WXWidget m_scrolledWindow;
|
||||||
|
WXWidget m_drawingArea;
|
||||||
bool m_winCaptured;
|
bool m_winCaptured;
|
||||||
bool m_isShown;
|
bool m_isShown;
|
||||||
|
bool m_hScroll;
|
||||||
|
bool m_vScroll;
|
||||||
|
bool m_hScrollingEnabled;
|
||||||
|
bool m_vScrollingEnabled;
|
||||||
|
WXPixmap m_backingPixmap;
|
||||||
|
int m_pixmapWidth;
|
||||||
|
int m_pixmapHeight;
|
||||||
|
int m_pixmapOffsetX;
|
||||||
|
int m_pixmapOffsetY;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
@@ -579,6 +579,9 @@ void wxFrame::SetStatusWidths(int n, const int widths_field[])
|
|||||||
|
|
||||||
void wxFrame::PositionStatusBar()
|
void wxFrame::PositionStatusBar()
|
||||||
{
|
{
|
||||||
|
if (!m_frameStatusBar)
|
||||||
|
return;
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
GetClientSize(&w, &h);
|
GetClientSize(&w, &h);
|
||||||
int sw, sh;
|
int sw, sh;
|
||||||
@@ -586,16 +589,14 @@ void wxFrame::PositionStatusBar()
|
|||||||
|
|
||||||
// Since we wish the status bar to be directly under the client area,
|
// Since we wish the status bar to be directly under the client area,
|
||||||
// we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
|
// we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
|
||||||
m_frameStatusBar->SetSize(0, h, w, sh);
|
m_frameStatusBar->SetSize(0-sh, h, w, sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
WXWidget wxFrame::GetMenuBarWidget() const
|
WXWidget wxFrame::GetMenuBarWidget() const
|
||||||
{
|
{
|
||||||
/* TODO
|
|
||||||
if (GetMenuBar())
|
if (GetMenuBar())
|
||||||
return GetMenuBar()->GetMainWidget();
|
return GetMenuBar()->GetMainWidget();
|
||||||
else
|
else
|
||||||
*/
|
|
||||||
return (WXWidget) NULL;
|
return (WXWidget) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,8 +613,6 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar)
|
|||||||
|
|
||||||
m_frameMenuBar = menuBar;
|
m_frameMenuBar = menuBar;
|
||||||
|
|
||||||
// TODO
|
|
||||||
#if 0
|
|
||||||
Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0);
|
Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0);
|
||||||
m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW);
|
m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW);
|
||||||
|
|
||||||
@@ -621,12 +620,13 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar)
|
|||||||
for (i = 0; i < menuBar->GetMenuCount(); i++)
|
for (i = 0; i < menuBar->GetMenuCount(); i++)
|
||||||
{
|
{
|
||||||
wxMenu *menu = menuBar->GetMenu(i);
|
wxMenu *menu = menuBar->GetMenu(i);
|
||||||
menu->SetButtonWidget(menu->CreateMenu (menuBar, menuBarW, menu, menuBar->m_titles[i], TRUE);
|
wxString title(menuBar->m_titles[i]);
|
||||||
|
menu->SetButtonWidget(menu->CreateMenu (menuBar, menuBarW, menu, title, TRUE));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
|
* COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
|
||||||
*/
|
*/
|
||||||
wxStripMenuCodes (menuBar->m_titles[i], wxBuffer);
|
wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
|
||||||
|
|
||||||
if (strcmp (wxBuffer, "Help") == 0)
|
if (strcmp (wxBuffer, "Help") == 0)
|
||||||
XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
|
XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
|
||||||
@@ -635,7 +635,6 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar)
|
|||||||
XtRealizeWidget ((Widget) menuBarW);
|
XtRealizeWidget ((Widget) menuBarW);
|
||||||
XtManageChild ((Widget) menuBarW);
|
XtManageChild ((Widget) menuBarW);
|
||||||
menuBar->SetMenuBarFrame(this);
|
menuBar->SetMenuBarFrame(this);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFrame::Fit()
|
void wxFrame::Fit()
|
||||||
@@ -1016,37 +1015,15 @@ static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
|
|||||||
//// Motif-specific
|
//// Motif-specific
|
||||||
bool wxFrame::PreResize()
|
bool wxFrame::PreResize()
|
||||||
{
|
{
|
||||||
/* TODO
|
PositionStatusBar();
|
||||||
// Set status line, if any
|
|
||||||
if (status_line_exists)
|
|
||||||
{
|
|
||||||
Dimension clientW, clientH;
|
|
||||||
XtVaGetValues(clientArea, XmNwidth, &clientW, XmNheight, &clientH, NULL);
|
|
||||||
Dimension xx, yy;
|
|
||||||
XtVaGetValues(statusLineWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
|
|
||||||
|
|
||||||
XtUnmanageChild(statusLineWidget);
|
|
||||||
XtVaSetValues(statusLineWidget, XmNx, 0, XmNy, clientH - yy, XmNwidth, clientW, NULL);
|
|
||||||
|
|
||||||
if (statusLineForm)
|
|
||||||
XtVaSetValues(statusLineForm, XmNwidth, clientW, NULL);
|
|
||||||
|
|
||||||
XtManageChild(statusLineWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
int width, height;
|
|
||||||
GetSize(&width, &height);
|
|
||||||
|
|
||||||
if (width == lastWidth && height == lastHeight)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXWidget wxFrame::GetClientWidget() const
|
||||||
|
{
|
||||||
|
return m_clientArea;
|
||||||
|
}
|
||||||
|
|
||||||
void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
|
void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
|
||||||
{
|
{
|
||||||
wxFrame *frame = (wxFrame *)client_data;
|
wxFrame *frame = (wxFrame *)client_data;
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "wx/menuitem.h"
|
#include "wx/menuitem.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/frame.h"
|
||||||
|
|
||||||
#include <Xm/Label.h>
|
#include <Xm/Label.h>
|
||||||
#include <Xm/LabelG.h>
|
#include <Xm/LabelG.h>
|
||||||
@@ -37,17 +39,12 @@
|
|||||||
#include <Xm/ToggleBG.h>
|
#include <Xm/ToggleBG.h>
|
||||||
#include <Xm/RowColumn.h>
|
#include <Xm/RowColumn.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
// other standard headers
|
// other standard headers
|
||||||
// ----------------------
|
// ----------------------
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void wxMenuItemCallback (Widget w, XtPointer clientData,
|
|
||||||
XtPointer ptr);
|
|
||||||
void wxMenuItemArmCallback (Widget w, XtPointer clientData,
|
|
||||||
XtPointer ptr);
|
|
||||||
void wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
|
|
||||||
XtPointer ptr);
|
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
|
||||||
@@ -74,36 +71,46 @@ wxMenu::wxMenu(const wxString& title, const wxFunction func)
|
|||||||
m_popupShell = (WXWidget) NULL;
|
m_popupShell = (WXWidget) NULL;
|
||||||
m_buttonWidget = (WXWidget) NULL;
|
m_buttonWidget = (WXWidget) NULL;
|
||||||
m_menuId = 0;
|
m_menuId = 0;
|
||||||
m_topMenu = (wxMenu*) NULL;
|
m_topLevelMenu = (wxMenu*) NULL;
|
||||||
m_ownedByMenuBar = FALSE;
|
m_ownedByMenuBar = FALSE;
|
||||||
m_menuParent = (wxMenu*) NULL;
|
m_menuParent = (wxMenu*) NULL;
|
||||||
|
|
||||||
if (m_title != "")
|
if (m_title != "")
|
||||||
{
|
{
|
||||||
Append(-2, m_title) ;
|
Append(ID_SEPARATOR, m_title) ;
|
||||||
AppendSeparator() ;
|
AppendSeparator() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback(func);
|
Callback(func);
|
||||||
|
|
||||||
// TODO create menu
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The wxWindow destructor will take care of deleting the submenus.
|
// The wxWindow destructor will take care of deleting the submenus.
|
||||||
wxMenu::~wxMenu()
|
wxMenu::~wxMenu()
|
||||||
{
|
{
|
||||||
// TODO destroy menu and children
|
if (m_menuWidget)
|
||||||
|
{
|
||||||
|
if (m_menuParent)
|
||||||
|
DestroyMenu(TRUE);
|
||||||
|
else
|
||||||
|
DestroyMenu(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not sure if this is right
|
||||||
|
if (m_menuParent && m_menuBar)
|
||||||
|
{
|
||||||
|
m_menuParent = NULL;
|
||||||
|
// m_menuBar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wxNode *node = m_menuItems.First();
|
wxNode *node = m_menuItems.First();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
wxMenuItem *item = (wxMenuItem *)node->Data();
|
wxMenuItem *item = (wxMenuItem *)node->Data();
|
||||||
|
|
||||||
// Delete child menus.
|
/*
|
||||||
// Beware: they must not be appended to children list!!!
|
|
||||||
// (because order of delete is significant)
|
|
||||||
if (item->GetSubMenu())
|
if (item->GetSubMenu())
|
||||||
item->DeleteSubMenu();
|
item->DeleteSubMenu();
|
||||||
|
*/
|
||||||
|
|
||||||
wxNode *next = node->Next();
|
wxNode *next = node->Next();
|
||||||
delete item;
|
delete item;
|
||||||
@@ -114,40 +121,47 @@ wxMenu::~wxMenu()
|
|||||||
|
|
||||||
void wxMenu::Break()
|
void wxMenu::Break()
|
||||||
{
|
{
|
||||||
// TODO
|
m_numColumns ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function appends a new item or submenu to the menu
|
// function appends a new item or submenu to the menu
|
||||||
void wxMenu::Append(wxMenuItem *pItem)
|
void wxMenu::Append(wxMenuItem *pItem)
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
|
|
||||||
wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
|
wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
|
||||||
|
|
||||||
m_menuItems.Append(pItem);
|
m_menuItems.Append(pItem);
|
||||||
|
|
||||||
|
if (m_menuWidget)
|
||||||
|
pItem->CreateItem (m_menuWidget, m_menuBar, m_topLevelMenu); // this is a dynamic Append
|
||||||
|
|
||||||
m_noItems++;
|
m_noItems++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::AppendSeparator()
|
void wxMenu::AppendSeparator()
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
Append(new wxMenuItem(this, ID_SEPARATOR));
|
Append(new wxMenuItem(this, ID_SEPARATOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pullright item
|
// Pullright item
|
||||||
void wxMenu::Append(int Id, const wxString& label, wxMenu *SubMenu,
|
// N.B.: difference between old and new code.
|
||||||
|
// Old code stores subMenu in 'children' for later deletion,
|
||||||
|
// as well as in m_menuItems, whereas we only store it in
|
||||||
|
// m_menuItems here. What implications does this have?
|
||||||
|
|
||||||
|
void wxMenu::Append(int id, const wxString& label, wxMenu *subMenu,
|
||||||
const wxString& helpString)
|
const wxString& helpString)
|
||||||
{
|
{
|
||||||
Append(new wxMenuItem(this, Id, label, helpString, FALSE, SubMenu));
|
Append(new wxMenuItem(this, id, label, helpString, FALSE, subMenu));
|
||||||
|
|
||||||
|
subMenu->m_topLevelMenu = m_topLevelMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ordinary menu item
|
// Ordinary menu item
|
||||||
void wxMenu::Append(int Id, const wxString& label,
|
void wxMenu::Append(int id, const wxString& label,
|
||||||
const wxString& helpString, bool checkable)
|
const wxString& helpString, bool checkable)
|
||||||
{
|
{
|
||||||
// 'checkable' parameter is useless for Windows.
|
// 'checkable' parameter is useless for Windows.
|
||||||
Append(new wxMenuItem(this, Id, label, helpString, checkable));
|
Append(new wxMenuItem(this, id, label, helpString, checkable));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::Delete(int id)
|
void wxMenu::Delete(int id)
|
||||||
@@ -156,7 +170,8 @@ void wxMenu::Delete(int id)
|
|||||||
wxMenuItem *item;
|
wxMenuItem *item;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++) {
|
for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++)
|
||||||
|
{
|
||||||
item = (wxMenuItem *)node->Data();
|
item = (wxMenuItem *)node->Data();
|
||||||
if (item->GetId() == id)
|
if (item->GetId() == id)
|
||||||
break;
|
break;
|
||||||
@@ -165,18 +180,27 @@ void wxMenu::Delete(int id)
|
|||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
item->DestroyItem(TRUE);
|
||||||
|
|
||||||
|
// See also old code - don't know if this is needed (seems redundant).
|
||||||
|
/*
|
||||||
|
if (item->GetSubMenu()) {
|
||||||
|
item->subMenu->top_level_menu = item->GetSubMenu();
|
||||||
|
item->subMenu->window_parent = NULL;
|
||||||
|
children->DeleteObject(item->GetSubMenu());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
m_menuItems.DeleteNode(node);
|
m_menuItems.DeleteNode(node);
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::Enable(int Id, bool Flag)
|
void wxMenu::Enable(int id, bool flag)
|
||||||
{
|
{
|
||||||
wxMenuItem *item = FindItemForId(Id);
|
wxMenuItem *item = FindItemForId(id);
|
||||||
wxCHECK_RET( item != NULL, "can't enable non-existing menu item" );
|
wxCHECK_RET( item != NULL, "can't enable non-existing menu item" );
|
||||||
|
|
||||||
item->Enable(Flag);
|
item->Enable(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenu::Enabled(int Id) const
|
bool wxMenu::Enabled(int Id) const
|
||||||
@@ -195,9 +219,9 @@ void wxMenu::Check(int Id, bool Flag)
|
|||||||
item->Check(Flag);
|
item->Check(Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenu::Checked(int Id) const
|
bool wxMenu::Checked(int id) const
|
||||||
{
|
{
|
||||||
wxMenuItem *item = FindItemForId(Id);
|
wxMenuItem *item = FindItemForId(id);
|
||||||
wxCHECK( item != NULL, FALSE );
|
wxCHECK( item != NULL, FALSE );
|
||||||
|
|
||||||
return item->IsChecked();
|
return item->IsChecked();
|
||||||
@@ -206,7 +230,21 @@ bool wxMenu::Checked(int Id) const
|
|||||||
void wxMenu::SetTitle(const wxString& label)
|
void wxMenu::SetTitle(const wxString& label)
|
||||||
{
|
{
|
||||||
m_title = label ;
|
m_title = label ;
|
||||||
// TODO
|
|
||||||
|
wxNode *node = m_menuItems.First ();
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxMenuItem *item = (wxMenuItem *) node->Data ();
|
||||||
|
Widget widget = (Widget) item->GetButtonWidget();
|
||||||
|
if (!widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XmString title_str = XmStringCreateSimple ((char*) (const char*) label);
|
||||||
|
XtVaSetValues (widget,
|
||||||
|
XmNlabelString, title_str,
|
||||||
|
NULL);
|
||||||
|
// TODO: should we delete title_str now?
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString wxMenu::GetTitle() const
|
const wxString wxMenu::GetTitle() const
|
||||||
@@ -216,25 +254,39 @@ const wxString wxMenu::GetTitle() const
|
|||||||
|
|
||||||
void wxMenu::SetLabel(int id, const wxString& label)
|
void wxMenu::SetLabel(int id, const wxString& label)
|
||||||
{
|
{
|
||||||
wxMenuItem *item = FindItemForId(id) ;
|
wxMenuItem *item = FindItemForId(id);
|
||||||
if (item==NULL)
|
if (item == (wxMenuItem*) NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (item->GetSubMenu()==NULL)
|
item->SetLabel(label);
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
item->SetName(label);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxMenu::GetLabel(int Id) const
|
wxString wxMenu::GetLabel(int id) const
|
||||||
{
|
{
|
||||||
// TODO
|
wxMenuItem *it = NULL;
|
||||||
return wxString("") ;
|
WXWidget w = FindMenuItem (id, &it);
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
XmString text;
|
||||||
|
char *s;
|
||||||
|
XtVaGetValues ((Widget) w,
|
||||||
|
XmNlabelString, &text,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
|
||||||
|
{
|
||||||
|
wxString str(s);
|
||||||
|
XtFree (s);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XmStringFree (text);
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds the item id matching the given string, -1 if not found.
|
// Finds the item id matching the given string, -1 if not found.
|
||||||
@@ -332,8 +384,66 @@ void wxMenu::ProcessCommand(wxCommandEvent & event)
|
|||||||
|
|
||||||
bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
|
bool wxWindow::PopupMenu(wxMenu *menu, int x, int y)
|
||||||
{
|
{
|
||||||
// TODO
|
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;
|
return FALSE;
|
||||||
|
|
||||||
|
if (menu->GetMainWidget()) {
|
||||||
|
menu->DestroyMenu(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWindow *parent = this;
|
||||||
|
|
||||||
|
menu->SetId(1); /* Mark as popped-up */
|
||||||
|
menu->CreateMenu(NULL, widget, menu);
|
||||||
|
// 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
|
// Menu Bar
|
||||||
@@ -344,8 +454,6 @@ wxMenuBar::wxMenuBar()
|
|||||||
m_menus = NULL;
|
m_menus = NULL;
|
||||||
m_titles = NULL;
|
m_titles = NULL;
|
||||||
m_menuBarFrame = NULL;
|
m_menuBarFrame = NULL;
|
||||||
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
|
wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
|
||||||
@@ -358,8 +466,6 @@ wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
|
|||||||
for ( i = 0; i < n; i++ )
|
for ( i = 0; i < n; i++ )
|
||||||
m_titles[i] = titles[i];
|
m_titles[i] = titles[i];
|
||||||
m_menuBarFrame = NULL;
|
m_menuBarFrame = NULL;
|
||||||
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuBar::~wxMenuBar()
|
wxMenuBar::~wxMenuBar()
|
||||||
@@ -371,8 +477,6 @@ wxMenuBar::~wxMenuBar()
|
|||||||
}
|
}
|
||||||
delete[] m_menus;
|
delete[] m_menus;
|
||||||
delete[] m_titles;
|
delete[] m_titles;
|
||||||
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must only be used AFTER menu has been attached to frame,
|
// Must only be used AFTER menu has been attached to frame,
|
||||||
@@ -383,8 +487,7 @@ void wxMenuBar::Enable(int id, bool flag)
|
|||||||
wxMenuItem *item = FindItemForId(id, &itemMenu) ;
|
wxMenuItem *item = FindItemForId(id, &itemMenu) ;
|
||||||
if (!item)
|
if (!item)
|
||||||
return;
|
return;
|
||||||
|
item->Enable(flag);
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::EnableTop(int pos, bool flag)
|
void wxMenuBar::EnableTop(int pos, bool flag)
|
||||||
@@ -404,7 +507,7 @@ void wxMenuBar::Check(int id, bool flag)
|
|||||||
if (!item->IsCheckable())
|
if (!item->IsCheckable())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// TODO
|
item->Check(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenuBar::Checked(int id) const
|
bool wxMenuBar::Checked(int id) const
|
||||||
@@ -414,8 +517,7 @@ bool wxMenuBar::Checked(int id) const
|
|||||||
if (!item)
|
if (!item)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// TODO
|
return item->IsChecked();
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenuBar::Enabled(int id) const
|
bool wxMenuBar::Enabled(int id) const
|
||||||
@@ -425,11 +527,9 @@ bool wxMenuBar::Enabled(int id) const
|
|||||||
if (!item)
|
if (!item)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// TODO
|
return item->IsEnabled();
|
||||||
return FALSE ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wxMenuBar::SetLabel(int id, const wxString& label)
|
void wxMenuBar::SetLabel(int id, const wxString& label)
|
||||||
{
|
{
|
||||||
wxMenu *itemMenu = NULL;
|
wxMenu *itemMenu = NULL;
|
||||||
@@ -438,7 +538,7 @@ void wxMenuBar::SetLabel(int id, const wxString& label)
|
|||||||
if (!item)
|
if (!item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO
|
item->SetLabel(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxMenuBar::GetLabel(int id) const
|
wxString wxMenuBar::GetLabel(int id) const
|
||||||
@@ -449,31 +549,81 @@ wxString wxMenuBar::GetLabel(int id) const
|
|||||||
if (!item)
|
if (!item)
|
||||||
return wxString("");
|
return wxString("");
|
||||||
|
|
||||||
// TODO
|
return item->GetLabel();
|
||||||
return wxString("") ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::SetLabelTop(int pos, const wxString& label)
|
void wxMenuBar::SetLabelTop(int pos, const wxString& label)
|
||||||
{
|
{
|
||||||
// TODO
|
wxASSERT( (pos < m_menuCount) );
|
||||||
|
|
||||||
|
Widget w = (Widget) m_menus[pos]->GetButtonWidget();
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
XmString label_str = XmStringCreateSimple ((char*) (const char*) label);
|
||||||
|
XtVaSetValues (w,
|
||||||
|
XmNlabelString, label_str,
|
||||||
|
NULL);
|
||||||
|
XmStringFree (label_str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxMenuBar::GetLabelTop(int pos) const
|
wxString wxMenuBar::GetLabelTop(int pos) const
|
||||||
{
|
{
|
||||||
// TODO
|
wxASSERT( (pos < m_menuCount) );
|
||||||
return wxString("");
|
|
||||||
|
Widget w = (Widget) m_menus[pos]->GetButtonWidget();
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
XmString text;
|
||||||
|
char *s;
|
||||||
|
XtVaGetValues (w,
|
||||||
|
XmNlabelString, &text,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
|
||||||
|
{
|
||||||
|
wxString str(s);
|
||||||
|
XtFree (s);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return wxEmptyString;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos)
|
bool wxMenuBar::OnDelete(wxMenu *menu, int pos)
|
||||||
{
|
{
|
||||||
// TODO
|
// Only applies to dynamic deletion (when set in frame)
|
||||||
return FALSE;
|
if (!m_menuBarFrame)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
menu->DestroyMenu(TRUE);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title)
|
bool wxMenuBar::OnAppend(wxMenu *menu, const char *title)
|
||||||
{
|
{
|
||||||
// TODO
|
// Only applies to dynamic append (when set in frame)
|
||||||
return FALSE;
|
if (!m_menuBarFrame)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// Probably should be an assert here
|
||||||
|
if (menu->GetParent())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Has already been appended
|
||||||
|
if (menu->GetButtonWidget())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
WXWidget w = menu->CreateMenu(this, GetMainWidget(), menu, title, TRUE);
|
||||||
|
menu->SetButtonWidget(w);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::Append (wxMenu * menu, const wxString& title)
|
void wxMenuBar::Append (wxMenu * menu, const wxString& title)
|
||||||
@@ -504,7 +654,8 @@ void wxMenuBar::Append (wxMenu * menu, const wxString& title)
|
|||||||
m_menus[m_menuCount - 1] = (wxMenu *)menu;
|
m_menus[m_menuCount - 1] = (wxMenu *)menu;
|
||||||
m_titles[m_menuCount - 1] = title;
|
m_titles[m_menuCount - 1] = title;
|
||||||
|
|
||||||
// TODO
|
menu->SetMenuBar(this);
|
||||||
|
menu->SetParent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::Delete(wxMenu * menu, int i)
|
void wxMenuBar::Delete(wxMenu * menu, int i)
|
||||||
@@ -531,7 +682,7 @@ void wxMenuBar::Delete(wxMenu * menu, int i)
|
|||||||
if (!OnDelete(menu, ii))
|
if (!OnDelete(menu, ii))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu->SetParent(NULL);
|
menu->SetParent((wxEvtHandler*) NULL);
|
||||||
|
|
||||||
-- m_menuCount;
|
-- m_menuCount;
|
||||||
for (j = ii; j < m_menuCount; j++)
|
for (j = ii; j < m_menuCount; j++)
|
||||||
@@ -558,7 +709,7 @@ int wxMenuBar::FindMenuItem (const wxString& menuString, const wxString& itemStr
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const
|
wxMenuItem *wxMenuBar::FindItemForId (int id, wxMenu ** itemMenu) const
|
||||||
{
|
{
|
||||||
if (itemMenu)
|
if (itemMenu)
|
||||||
*itemMenu = NULL;
|
*itemMenu = NULL;
|
||||||
@@ -566,33 +717,199 @@ wxMenuItem *wxMenuBar::FindItemForId (int Id, wxMenu ** itemMenu) const
|
|||||||
wxMenuItem *item = NULL;
|
wxMenuItem *item = NULL;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < m_menuCount; i++)
|
for (i = 0; i < m_menuCount; i++)
|
||||||
if ((item = m_menus[i]->FindItemForId (Id, itemMenu)))
|
if ((item = m_menus[i]->FindItemForId (id, itemMenu)))
|
||||||
return item;
|
return item;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::SetHelpString (int Id, const wxString& helpString)
|
void wxMenuBar::SetHelpString (int id, const wxString& helpString)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < m_menuCount; i++)
|
for (i = 0; i < m_menuCount; i++)
|
||||||
{
|
{
|
||||||
if (m_menus[i]->FindItemForId (Id))
|
if (m_menus[i]->FindItemForId (id))
|
||||||
{
|
{
|
||||||
m_menus[i]->SetHelpString (Id, helpString);
|
m_menus[i]->SetHelpString (id, helpString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxMenuBar::GetHelpString (int Id) const
|
wxString wxMenuBar::GetHelpString (int id) const
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < m_menuCount; i++)
|
for (i = 0; i < m_menuCount; i++)
|
||||||
{
|
{
|
||||||
if (m_menus[i]->FindItemForId (Id))
|
if (m_menus[i]->FindItemForId (id))
|
||||||
return wxString(m_menus[i]->GetHelpString (Id));
|
return wxString(m_menus[i]->GetHelpString (id));
|
||||||
}
|
}
|
||||||
return wxString("");
|
return wxString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// Motif-specific
|
||||||
|
|
||||||
|
extern wxApp *wxTheApp;
|
||||||
|
static XtWorkProcId WorkProcMenuId;
|
||||||
|
|
||||||
|
/* Since PopupMenu under Motif stills grab right mouse button events
|
||||||
|
* after it was closed, we need to delete the associated widgets to
|
||||||
|
* allow next PopUpMenu to appear...
|
||||||
|
*/
|
||||||
|
|
||||||
|
int PostDeletionOfMenu( XtPointer* clientData )
|
||||||
|
{
|
||||||
|
XtRemoveWorkProc(WorkProcMenuId);
|
||||||
|
wxMenu *menu = (wxMenu *)clientData;
|
||||||
|
|
||||||
|
if (menu->GetMainWidget()) {
|
||||||
|
wxList& list = menu->GetParent()->GetItems();
|
||||||
|
list.DeleteObject(menu);
|
||||||
|
menu->DestroyMenu(TRUE);
|
||||||
|
}
|
||||||
|
/* Mark as no longer popped up */
|
||||||
|
menu->m_menuId = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wxMenuPopdownCallback(Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxMenu *menu = (wxMenu *)clientData;
|
||||||
|
|
||||||
|
// Added by JOREL Jean-Charles <jjorel@silr.ireste.fr>
|
||||||
|
/* Since Callbacks of MenuItems are not yet processed, we put a
|
||||||
|
* background job which will be done when system will be idle.
|
||||||
|
* What awful hack!! :(
|
||||||
|
*/
|
||||||
|
|
||||||
|
WorkProcMenuId = XtAppAddWorkProc(
|
||||||
|
(XtAppContext) wxTheApp->GetAppContext(),
|
||||||
|
(XtWorkProc) PostDeletionOfMenu,
|
||||||
|
(XtPointer) menu );
|
||||||
|
// Apparently not found in Motif headers
|
||||||
|
// XtVaSetValues( w, XmNpopupEnabled, XmPOPUP_DISABLED, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a popup or pulldown menu.
|
||||||
|
* Submenus of a popup will be pulldown.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
WXWidget wxMenu::CreateMenu (wxMenuBar * menuBar, WXWidget parent, wxMenu * topMenu, const wxString& title, bool pullDown)
|
||||||
|
{
|
||||||
|
Widget menu = (Widget) 0;
|
||||||
|
Widget buttonWidget = (Widget) 0;
|
||||||
|
Arg args[5];
|
||||||
|
XtSetArg (args[0], XmNnumColumns, m_numColumns);
|
||||||
|
XtSetArg (args[1], XmNpacking, XmPACK_COLUMN);
|
||||||
|
|
||||||
|
if (!pullDown)
|
||||||
|
{
|
||||||
|
menu = XmCreatePopupMenu ((Widget) parent, "popup", args, 2);
|
||||||
|
XtAddCallback(menu,
|
||||||
|
XmNunmapCallback,
|
||||||
|
(XtCallbackProc)wxMenuPopdownCallback,
|
||||||
|
(XtPointer)this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char mnem = wxFindMnemonic (title);
|
||||||
|
wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
|
||||||
|
|
||||||
|
menu = XmCreatePulldownMenu ((Widget) parent, "pulldown", args, 2);
|
||||||
|
|
||||||
|
XmString label_str = XmStringCreateSimple (wxBuffer);
|
||||||
|
buttonWidget = XtVaCreateManagedWidget (wxBuffer,
|
||||||
|
#if USE_GADGETS
|
||||||
|
xmCascadeButtonGadgetClass, (Widget) parent,
|
||||||
|
#else
|
||||||
|
xmCascadeButtonWidgetClass, (Widget) parent,
|
||||||
|
#endif
|
||||||
|
XmNlabelString, label_str,
|
||||||
|
XmNsubMenuId, menu,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (mnem != 0)
|
||||||
|
XtVaSetValues (buttonWidget, XmNmnemonic, mnem, NULL);
|
||||||
|
|
||||||
|
XmStringFree (label_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menuWidget = (WXWidget) menu;
|
||||||
|
|
||||||
|
m_menuBar = menuBar;
|
||||||
|
m_topLevelMenu = topMenu;
|
||||||
|
|
||||||
|
for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) node->Data ();
|
||||||
|
item->CreateItem (menu, menuBar, topMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttonWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroys the Motif implementation of the menu,
|
||||||
|
// but maintains the wxWindows data structures so we can
|
||||||
|
// do a CreateMenu again.
|
||||||
|
void wxMenu::DestroyMenu (bool full)
|
||||||
|
{
|
||||||
|
for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) node->Data ();
|
||||||
|
item->SetMenuBar((wxMenuBar*) NULL);
|
||||||
|
|
||||||
|
item->DestroyItem(full);
|
||||||
|
} // for()
|
||||||
|
|
||||||
|
if (m_buttonWidget)
|
||||||
|
{
|
||||||
|
if (full)
|
||||||
|
{
|
||||||
|
XtVaSetValues((Widget) m_buttonWidget, XmNsubMenuId, NULL, NULL);
|
||||||
|
XtDestroyWidget ((Widget) m_buttonWidget);
|
||||||
|
m_buttonWidget = (WXWidget) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_menuWidget && full)
|
||||||
|
{
|
||||||
|
XtDestroyWidget((Widget) m_menuWidget);
|
||||||
|
m_menuWidget = (WXWidget) NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WXWidget wxMenu::FindMenuItem (int id, wxMenuItem ** it) const
|
||||||
|
{
|
||||||
|
if (id == m_menuId)
|
||||||
|
{
|
||||||
|
if (it)
|
||||||
|
*it = (wxMenuItem*) NULL;
|
||||||
|
return m_buttonWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (wxNode * node = m_menuItems.First (); node; node = node->Next ())
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) node->Data ();
|
||||||
|
if (item->GetId() == id)
|
||||||
|
{
|
||||||
|
if (it)
|
||||||
|
*it = item;
|
||||||
|
return item->GetButtonWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->GetSubMenu())
|
||||||
|
{
|
||||||
|
WXWidget w = item->GetSubMenu()->FindMenuItem (id, it);
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for()
|
||||||
|
|
||||||
|
if (it)
|
||||||
|
*it = (wxMenuItem*) NULL;
|
||||||
|
return (WXWidget) NULL;
|
||||||
|
}
|
||||||
|
@@ -15,6 +15,27 @@
|
|||||||
|
|
||||||
#include "wx/menu.h"
|
#include "wx/menu.h"
|
||||||
#include "wx/menuitem.h"
|
#include "wx/menuitem.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
#include "wx/frame.h"
|
||||||
|
|
||||||
|
#include <Xm/Label.h>
|
||||||
|
#include <Xm/LabelG.h>
|
||||||
|
#include <Xm/CascadeBG.h>
|
||||||
|
#include <Xm/CascadeB.h>
|
||||||
|
#include <Xm/SeparatoG.h>
|
||||||
|
#include <Xm/PushBG.h>
|
||||||
|
#include <Xm/ToggleB.h>
|
||||||
|
#include <Xm/ToggleBG.h>
|
||||||
|
#include <Xm/RowColumn.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
|
void wxMenuItemCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr);
|
||||||
|
void wxMenuItemArmCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr);
|
||||||
|
void wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
@@ -39,9 +60,9 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
|
|||||||
const wxString& strName, const wxString& strHelp,
|
const wxString& strName, const wxString& strHelp,
|
||||||
bool bCheckable,
|
bool bCheckable,
|
||||||
wxMenu *pSubMenu) :
|
wxMenu *pSubMenu) :
|
||||||
|
m_strHelp(strHelp),
|
||||||
m_bCheckable(bCheckable),
|
m_bCheckable(bCheckable),
|
||||||
m_strName(strName),
|
m_strName(strName)
|
||||||
m_strHelp(strHelp)
|
|
||||||
{
|
{
|
||||||
wxASSERT( pParentMenu != NULL );
|
wxASSERT( pParentMenu != NULL );
|
||||||
|
|
||||||
@@ -49,6 +70,11 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
|
|||||||
m_pSubMenu = pSubMenu;
|
m_pSubMenu = pSubMenu;
|
||||||
m_idItem = id;
|
m_idItem = id;
|
||||||
m_bEnabled = TRUE;
|
m_bEnabled = TRUE;
|
||||||
|
|
||||||
|
//// Motif-specific
|
||||||
|
m_menuBar = NULL;
|
||||||
|
m_buttonWidget = (WXWidget) NULL;
|
||||||
|
m_topMenu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuItem::~wxMenuItem()
|
wxMenuItem::~wxMenuItem()
|
||||||
@@ -72,13 +98,19 @@ void wxMenuItem::DeleteSubMenu()
|
|||||||
|
|
||||||
void wxMenuItem::Enable(bool bDoEnable)
|
void wxMenuItem::Enable(bool bDoEnable)
|
||||||
{
|
{
|
||||||
if ( m_bEnabled != bDoEnable ) {
|
if ( m_bEnabled != bDoEnable )
|
||||||
if ( m_pSubMenu == NULL ) { // normal menu item
|
{
|
||||||
// TODO
|
if ( m_pSubMenu == NULL )
|
||||||
|
{ // normal menu item
|
||||||
|
if (m_buttonWidget)
|
||||||
|
XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
|
||||||
}
|
}
|
||||||
else // submenu
|
else // submenu
|
||||||
{
|
{
|
||||||
// TODO
|
// Maybe we should apply this to all items in the submenu?
|
||||||
|
// Or perhaps it works anyway.
|
||||||
|
if (m_buttonWidget)
|
||||||
|
XtSetSensitive( (Widget) m_buttonWidget, (Boolean) bDoEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bEnabled = bDoEnable;
|
m_bEnabled = bDoEnable;
|
||||||
@@ -89,8 +121,240 @@ void wxMenuItem::Check(bool bDoCheck)
|
|||||||
{
|
{
|
||||||
wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
|
wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
|
||||||
|
|
||||||
if ( m_bChecked != bDoCheck ) {
|
if ( m_bChecked != bDoCheck )
|
||||||
// TODO
|
{
|
||||||
|
if (m_buttonWidget && XtIsSubclass ((Widget) m_buttonWidget, xmToggleButtonGadgetClass))
|
||||||
|
{
|
||||||
|
XtVaSetValues ( (Widget) m_buttonWidget, XmNset, (Boolean) bDoCheck, NULL);
|
||||||
|
}
|
||||||
m_bChecked = bDoCheck;
|
m_bChecked = bDoCheck;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// Motif-specific
|
||||||
|
|
||||||
|
void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar, wxMenu * topMenu)
|
||||||
|
{
|
||||||
|
m_menuBar = menuBar;
|
||||||
|
m_topMenu = topMenu;
|
||||||
|
|
||||||
|
if (GetId() == -2)
|
||||||
|
{
|
||||||
|
// Id=-2 identifies a Title item.
|
||||||
|
wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
|
||||||
|
m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
|
||||||
|
xmLabelGadgetClass, (Widget) menu, NULL);
|
||||||
|
}
|
||||||
|
else if ((!m_strName.IsNull() && m_strName != "") && (!m_pSubMenu))
|
||||||
|
{
|
||||||
|
wxStripMenuCodes ((char*) (const char*) m_strName, wxBuffer);
|
||||||
|
if (IsCheckable())
|
||||||
|
{
|
||||||
|
m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
|
||||||
|
xmToggleButtonGadgetClass, (Widget) menu,
|
||||||
|
NULL);
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (wxBuffer,
|
||||||
|
xmPushButtonGadgetClass, (Widget) menu,
|
||||||
|
NULL);
|
||||||
|
char mnem = wxFindMnemonic (m_strName);
|
||||||
|
if (mnem != 0)
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
|
||||||
|
|
||||||
|
//// TODO: proper accelerator treatment. What does wxFindAccelerator
|
||||||
|
//// look for?
|
||||||
|
strcpy(wxBuffer, (char*) (const char*) m_strName);
|
||||||
|
char *accel = wxFindAccelerator (wxBuffer);
|
||||||
|
if (accel)
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
|
||||||
|
|
||||||
|
// TODO: What does this do?
|
||||||
|
strcpy(wxBuffer, (char*) (const char*) m_strName);
|
||||||
|
XmString accel_str = wxFindAcceleratorText (wxBuffer);
|
||||||
|
if (accel_str)
|
||||||
|
{
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
|
||||||
|
XmStringFree (accel_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCheckable())
|
||||||
|
XtAddCallback ((Widget) m_buttonWidget,
|
||||||
|
XmNvalueChangedCallback,
|
||||||
|
(XtCallbackProc) wxMenuItemCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
else
|
||||||
|
XtAddCallback ((Widget) m_buttonWidget,
|
||||||
|
XmNactivateCallback,
|
||||||
|
(XtCallbackProc) wxMenuItemCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
XtAddCallback ((Widget) m_buttonWidget,
|
||||||
|
XmNarmCallback,
|
||||||
|
(XtCallbackProc) wxMenuItemArmCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
XtAddCallback ((Widget) m_buttonWidget,
|
||||||
|
XmNdisarmCallback,
|
||||||
|
(XtCallbackProc) wxMenuItemDisarmCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
}
|
||||||
|
else if (GetId() == -1)
|
||||||
|
{
|
||||||
|
m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
|
||||||
|
xmSeparatorGadgetClass, (Widget) menu, NULL);
|
||||||
|
}
|
||||||
|
else if (m_pSubMenu)
|
||||||
|
{
|
||||||
|
m_buttonWidget = m_pSubMenu->CreateMenu (menuBar, menu, topMenu, m_strName, TRUE);
|
||||||
|
m_pSubMenu->SetButtonWidget(m_buttonWidget);
|
||||||
|
XtAddCallback ((Widget) m_buttonWidget,
|
||||||
|
XmNcascadingCallback,
|
||||||
|
(XtCallbackProc) wxMenuItemArmCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
}
|
||||||
|
if (m_buttonWidget)
|
||||||
|
XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuItem::DestroyItem(bool full)
|
||||||
|
{
|
||||||
|
if (GetId() == -2)
|
||||||
|
{
|
||||||
|
; // Nothing
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ((!m_strName.IsNull() && (m_strName != "")) && !m_pSubMenu)
|
||||||
|
{
|
||||||
|
if (m_buttonWidget)
|
||||||
|
{
|
||||||
|
if (IsCheckable())
|
||||||
|
XtRemoveCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback,
|
||||||
|
wxMenuItemCallback, (XtPointer) this);
|
||||||
|
else
|
||||||
|
XtRemoveCallback ((Widget) m_buttonWidget, XmNactivateCallback,
|
||||||
|
wxMenuItemCallback, (XtPointer) this);
|
||||||
|
XtRemoveCallback ((Widget) m_buttonWidget, XmNarmCallback,
|
||||||
|
wxMenuItemArmCallback, (XtPointer) this);
|
||||||
|
XtRemoveCallback ((Widget) m_buttonWidget, XmNdisarmCallback,
|
||||||
|
wxMenuItemDisarmCallback, (XtPointer) this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GetId() == -1)
|
||||||
|
{
|
||||||
|
; // Nothing
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (GetSubMenu())
|
||||||
|
{
|
||||||
|
if (m_buttonWidget)
|
||||||
|
{
|
||||||
|
XtRemoveCallback ((Widget) m_buttonWidget, XmNcascadingCallback,
|
||||||
|
wxMenuItemArmCallback, (XtPointer) this);
|
||||||
|
}
|
||||||
|
m_pSubMenu->DestroyMenu(full);
|
||||||
|
if (full)
|
||||||
|
m_buttonWidget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_buttonWidget && full)
|
||||||
|
{
|
||||||
|
XtDestroyWidget ((Widget) m_buttonWidget);
|
||||||
|
m_buttonWidget = (WXWidget) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuItem::SetLabel(const wxString& label)
|
||||||
|
{
|
||||||
|
char mnem = wxFindMnemonic (label);
|
||||||
|
wxStripMenuCodes ((char*) (const char*) label, wxBuffer);
|
||||||
|
|
||||||
|
m_strName = label;
|
||||||
|
|
||||||
|
if (m_buttonWidget)
|
||||||
|
{
|
||||||
|
XmString label_str = XmStringCreateSimple (wxBuffer);
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget,
|
||||||
|
XmNlabelString, label_str,
|
||||||
|
NULL);
|
||||||
|
XmStringFree (label_str);
|
||||||
|
if (mnem != 0)
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);
|
||||||
|
strcpy(wxBuffer, (char*) (const char*) label);
|
||||||
|
char *accel = wxFindAccelerator (wxBuffer);
|
||||||
|
if (accel)
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);
|
||||||
|
|
||||||
|
strcpy(wxBuffer, (char*) (const char*) label);
|
||||||
|
XmString accel_str = wxFindAcceleratorText (wxBuffer);
|
||||||
|
if (accel_str)
|
||||||
|
{
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
|
||||||
|
XmStringFree (accel_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuItemCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) clientData;
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->IsCheckable())
|
||||||
|
{
|
||||||
|
Boolean isChecked = FALSE;
|
||||||
|
XtVaGetValues ((Widget) item->GetButtonWidget(), XmNset, & isChecked, NULL);
|
||||||
|
item->SetChecked(isChecked);
|
||||||
|
}
|
||||||
|
if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
|
||||||
|
{
|
||||||
|
wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, item->GetId());
|
||||||
|
commandEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
|
||||||
|
|
||||||
|
item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent);
|
||||||
|
}
|
||||||
|
else if (item->GetTopMenu())
|
||||||
|
{
|
||||||
|
wxCommandEvent event (wxEVT_COMMAND_MENU_SELECTED, item->GetId());
|
||||||
|
event.SetEventObject(item->GetTopMenu());
|
||||||
|
item->GetTopMenu()->ProcessCommand (event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wxMenuItemArmCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) clientData;
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
|
||||||
|
{
|
||||||
|
wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, item->GetId());
|
||||||
|
menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
|
||||||
|
|
||||||
|
item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wxMenuItemDisarmCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *) clientData;
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->GetMenuBar() && item->GetMenuBar()->GetMenuBarFrame())
|
||||||
|
{
|
||||||
|
// TODO: not sure this is correct, since -1 means something
|
||||||
|
// special to event system
|
||||||
|
wxMenuEvent menuEvent(wxEVT_MENU_HIGHLIGHT, -1);
|
||||||
|
menuEvent.SetEventObject(item->GetMenuBar()->GetMenuBarFrame());
|
||||||
|
|
||||||
|
item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(menuEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include <Xm/Xm.h>
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
|
// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
|
||||||
bool wxGetHostName(char *buf, int maxSize)
|
bool wxGetHostName(char *buf, int maxSize)
|
||||||
{
|
{
|
||||||
@@ -322,3 +324,323 @@ wxString wxGetDisplayName()
|
|||||||
{
|
{
|
||||||
return gs_displayName;
|
return gs_displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the letter corresponding to the mnemonic, for Motif
|
||||||
|
char wxFindMnemonic (const char *s)
|
||||||
|
{
|
||||||
|
char mnem = 0;
|
||||||
|
int len = strlen (s);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (s[i] == '&')
|
||||||
|
{
|
||||||
|
// Carefully handle &&
|
||||||
|
if ((i + 1) <= len && s[i + 1] == '&')
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mnem = s[i + 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mnem;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * wxFindAccelerator (char *s)
|
||||||
|
{
|
||||||
|
// The accelerator text is after the \t char.
|
||||||
|
while (*s && *s != '\t')
|
||||||
|
s++;
|
||||||
|
if (*s == '\0')
|
||||||
|
return (NULL);
|
||||||
|
s++;
|
||||||
|
/*
|
||||||
|
Now we need to format it as X standard:
|
||||||
|
|
||||||
|
input output
|
||||||
|
|
||||||
|
F7 --> <Key>F7
|
||||||
|
Ctrl+N --> Ctrl<Key>N
|
||||||
|
Alt+k --> Meta<Key>k
|
||||||
|
Ctrl+Shift+A --> Ctrl Shift<Key>A
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxBuffer[0] = '\0';
|
||||||
|
char *tmp = copystring (s);
|
||||||
|
s = tmp;
|
||||||
|
char *p = s;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (*p && *p != '+')
|
||||||
|
p++;
|
||||||
|
if (*p)
|
||||||
|
{
|
||||||
|
*p = '\0';
|
||||||
|
if (wxBuffer[0])
|
||||||
|
strcat (wxBuffer, " ");
|
||||||
|
if (strcmp (s, "Alt"))
|
||||||
|
strcat (wxBuffer, s);
|
||||||
|
else
|
||||||
|
strcat (wxBuffer, "Meta");
|
||||||
|
s = p + 1;
|
||||||
|
p = s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcat (wxBuffer, "<Key>");
|
||||||
|
strcat (wxBuffer, s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[]tmp;
|
||||||
|
return wxBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmString wxFindAcceleratorText (char *s)
|
||||||
|
{
|
||||||
|
// The accelerator text is after the \t char.
|
||||||
|
while (*s && *s != '\t')
|
||||||
|
s++;
|
||||||
|
if (*s == '\0')
|
||||||
|
return (NULL);
|
||||||
|
s++;
|
||||||
|
XmString text = XmStringCreateSimple (s);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
|
int wxCharCodeXToWX(KeySym keySym)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
switch (keySym) {
|
||||||
|
case XK_Shift_L:
|
||||||
|
case XK_Shift_R:
|
||||||
|
id = WXK_SHIFT; break;
|
||||||
|
case XK_Control_L:
|
||||||
|
case XK_Control_R:
|
||||||
|
id = WXK_CONTROL; break;
|
||||||
|
case XK_BackSpace:
|
||||||
|
id = WXK_BACK; break;
|
||||||
|
case XK_Delete:
|
||||||
|
id = WXK_DELETE; break;
|
||||||
|
case XK_Clear:
|
||||||
|
id = WXK_CLEAR; break;
|
||||||
|
case XK_Tab:
|
||||||
|
id = WXK_TAB; break;
|
||||||
|
case XK_numbersign:
|
||||||
|
id = '#'; break;
|
||||||
|
case XK_Return:
|
||||||
|
id = WXK_RETURN; break;
|
||||||
|
case XK_Escape:
|
||||||
|
id = WXK_ESCAPE; break;
|
||||||
|
case XK_Pause:
|
||||||
|
case XK_Break:
|
||||||
|
id = WXK_PAUSE; break;
|
||||||
|
case XK_Num_Lock:
|
||||||
|
id = WXK_NUMLOCK; break;
|
||||||
|
case XK_Scroll_Lock:
|
||||||
|
id = WXK_SCROLL; break;
|
||||||
|
|
||||||
|
case XK_Home:
|
||||||
|
id = WXK_HOME; break;
|
||||||
|
case XK_End:
|
||||||
|
id = WXK_END; break;
|
||||||
|
case XK_Left:
|
||||||
|
id = WXK_LEFT; break;
|
||||||
|
case XK_Right:
|
||||||
|
id = WXK_RIGHT; break;
|
||||||
|
case XK_Up:
|
||||||
|
id = WXK_UP; break;
|
||||||
|
case XK_Down:
|
||||||
|
id = WXK_DOWN; break;
|
||||||
|
case XK_Next:
|
||||||
|
id = WXK_NEXT; break;
|
||||||
|
case XK_Prior:
|
||||||
|
id = WXK_PRIOR; break;
|
||||||
|
case XK_Menu:
|
||||||
|
id = WXK_MENU; break;
|
||||||
|
case XK_Select:
|
||||||
|
id = WXK_SELECT; break;
|
||||||
|
case XK_Cancel:
|
||||||
|
id = WXK_CANCEL; break;
|
||||||
|
case XK_Print:
|
||||||
|
id = WXK_PRINT; break;
|
||||||
|
case XK_Execute:
|
||||||
|
id = WXK_EXECUTE; break;
|
||||||
|
case XK_Insert:
|
||||||
|
id = WXK_INSERT; break;
|
||||||
|
case XK_Help:
|
||||||
|
id = WXK_HELP; break;
|
||||||
|
|
||||||
|
case XK_KP_Multiply:
|
||||||
|
id = WXK_MULTIPLY; break;
|
||||||
|
case XK_KP_Add:
|
||||||
|
id = WXK_ADD; break;
|
||||||
|
case XK_KP_Subtract:
|
||||||
|
id = WXK_SUBTRACT; break;
|
||||||
|
case XK_KP_Divide:
|
||||||
|
id = WXK_DIVIDE; break;
|
||||||
|
case XK_KP_Decimal:
|
||||||
|
id = WXK_DECIMAL; break;
|
||||||
|
case XK_KP_Equal:
|
||||||
|
id = '='; break;
|
||||||
|
case XK_KP_Space:
|
||||||
|
id = ' '; break;
|
||||||
|
case XK_KP_Tab:
|
||||||
|
id = WXK_TAB; break;
|
||||||
|
case XK_KP_Enter:
|
||||||
|
id = WXK_RETURN; break;
|
||||||
|
case XK_KP_0:
|
||||||
|
id = WXK_NUMPAD0; break;
|
||||||
|
case XK_KP_1:
|
||||||
|
id = WXK_NUMPAD1; break;
|
||||||
|
case XK_KP_2:
|
||||||
|
id = WXK_NUMPAD2; break;
|
||||||
|
case XK_KP_3:
|
||||||
|
id = WXK_NUMPAD3; break;
|
||||||
|
case XK_KP_4:
|
||||||
|
id = WXK_NUMPAD4; break;
|
||||||
|
case XK_KP_5:
|
||||||
|
id = WXK_NUMPAD5; break;
|
||||||
|
case XK_KP_6:
|
||||||
|
id = WXK_NUMPAD6; break;
|
||||||
|
case XK_KP_7:
|
||||||
|
id = WXK_NUMPAD7; break;
|
||||||
|
case XK_KP_8:
|
||||||
|
id = WXK_NUMPAD8; break;
|
||||||
|
case XK_KP_9:
|
||||||
|
id = WXK_NUMPAD9; break;
|
||||||
|
case XK_F1:
|
||||||
|
id = WXK_F1; break;
|
||||||
|
case XK_F2:
|
||||||
|
id = WXK_F2; break;
|
||||||
|
case XK_F3:
|
||||||
|
id = WXK_F3; break;
|
||||||
|
case XK_F4:
|
||||||
|
id = WXK_F4; break;
|
||||||
|
case XK_F5:
|
||||||
|
id = WXK_F5; break;
|
||||||
|
case XK_F6:
|
||||||
|
id = WXK_F6; break;
|
||||||
|
case XK_F7:
|
||||||
|
id = WXK_F7; break;
|
||||||
|
case XK_F8:
|
||||||
|
id = WXK_F8; break;
|
||||||
|
case XK_F9:
|
||||||
|
id = WXK_F9; break;
|
||||||
|
case XK_F10:
|
||||||
|
id = WXK_F10; break;
|
||||||
|
case XK_F11:
|
||||||
|
id = WXK_F11; break;
|
||||||
|
case XK_F12:
|
||||||
|
id = WXK_F12; break;
|
||||||
|
case XK_F13:
|
||||||
|
id = WXK_F13; break;
|
||||||
|
case XK_F14:
|
||||||
|
id = WXK_F14; break;
|
||||||
|
case XK_F15:
|
||||||
|
id = WXK_F15; break;
|
||||||
|
case XK_F16:
|
||||||
|
id = WXK_F16; break;
|
||||||
|
case XK_F17:
|
||||||
|
id = WXK_F17; break;
|
||||||
|
case XK_F18:
|
||||||
|
id = WXK_F18; break;
|
||||||
|
case XK_F19:
|
||||||
|
id = WXK_F19; break;
|
||||||
|
case XK_F20:
|
||||||
|
id = WXK_F20; break;
|
||||||
|
case XK_F21:
|
||||||
|
id = WXK_F21; break;
|
||||||
|
case XK_F22:
|
||||||
|
id = WXK_F22; break;
|
||||||
|
case XK_F23:
|
||||||
|
id = WXK_F23; break;
|
||||||
|
case XK_F24:
|
||||||
|
id = WXK_F24; break;
|
||||||
|
default:
|
||||||
|
id = (keySym <= 255) ? (int)keySym : -1;
|
||||||
|
} // switch
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeySym wxCharCodeWXToX(int id)
|
||||||
|
{
|
||||||
|
KeySym keySym;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case WXK_CANCEL: keySym = XK_Cancel; break;
|
||||||
|
case WXK_BACK: keySym = XK_BackSpace; break;
|
||||||
|
case WXK_TAB: keySym = XK_Tab; break;
|
||||||
|
case WXK_CLEAR: keySym = XK_Clear; break;
|
||||||
|
case WXK_RETURN: keySym = XK_Return; break;
|
||||||
|
case WXK_SHIFT: keySym = XK_Shift_L; break;
|
||||||
|
case WXK_CONTROL: keySym = XK_Control_L; break;
|
||||||
|
case WXK_MENU : keySym = XK_Menu; break;
|
||||||
|
case WXK_PAUSE: keySym = XK_Pause; break;
|
||||||
|
case WXK_ESCAPE: keySym = XK_Escape; break;
|
||||||
|
case WXK_SPACE: keySym = ' '; break;
|
||||||
|
case WXK_PRIOR: keySym = XK_Prior; break;
|
||||||
|
case WXK_NEXT : keySym = XK_Next; break;
|
||||||
|
case WXK_END: keySym = XK_End; break;
|
||||||
|
case WXK_HOME : keySym = XK_Home; break;
|
||||||
|
case WXK_LEFT : keySym = XK_Left; break;
|
||||||
|
case WXK_UP: keySym = XK_Up; break;
|
||||||
|
case WXK_RIGHT: keySym = XK_Right; break;
|
||||||
|
case WXK_DOWN : keySym = XK_Down; break;
|
||||||
|
case WXK_SELECT: keySym = XK_Select; break;
|
||||||
|
case WXK_PRINT: keySym = XK_Print; break;
|
||||||
|
case WXK_EXECUTE: keySym = XK_Execute; break;
|
||||||
|
case WXK_INSERT: keySym = XK_Insert; break;
|
||||||
|
case WXK_DELETE: keySym = XK_Delete; break;
|
||||||
|
case WXK_HELP : keySym = XK_Help; break;
|
||||||
|
case WXK_NUMPAD0: keySym = XK_KP_0; break;
|
||||||
|
case WXK_NUMPAD1: keySym = XK_KP_1; break;
|
||||||
|
case WXK_NUMPAD2: keySym = XK_KP_2; break;
|
||||||
|
case WXK_NUMPAD3: keySym = XK_KP_3; break;
|
||||||
|
case WXK_NUMPAD4: keySym = XK_KP_4; break;
|
||||||
|
case WXK_NUMPAD5: keySym = XK_KP_5; break;
|
||||||
|
case WXK_NUMPAD6: keySym = XK_KP_6; break;
|
||||||
|
case WXK_NUMPAD7: keySym = XK_KP_7; break;
|
||||||
|
case WXK_NUMPAD8: keySym = XK_KP_8; break;
|
||||||
|
case WXK_NUMPAD9: keySym = XK_KP_9; break;
|
||||||
|
case WXK_MULTIPLY: keySym = XK_KP_Multiply; break;
|
||||||
|
case WXK_ADD: keySym = XK_KP_Add; break;
|
||||||
|
case WXK_SUBTRACT: keySym = XK_KP_Subtract; break;
|
||||||
|
case WXK_DECIMAL: keySym = XK_KP_Decimal; break;
|
||||||
|
case WXK_DIVIDE: keySym = XK_KP_Divide; break;
|
||||||
|
case WXK_F1: keySym = XK_F1; break;
|
||||||
|
case WXK_F2: keySym = XK_F2; break;
|
||||||
|
case WXK_F3: keySym = XK_F3; break;
|
||||||
|
case WXK_F4: keySym = XK_F4; break;
|
||||||
|
case WXK_F5: keySym = XK_F5; break;
|
||||||
|
case WXK_F6: keySym = XK_F6; break;
|
||||||
|
case WXK_F7: keySym = XK_F7; break;
|
||||||
|
case WXK_F8: keySym = XK_F8; break;
|
||||||
|
case WXK_F9: keySym = XK_F9; break;
|
||||||
|
case WXK_F10: keySym = XK_F10; break;
|
||||||
|
case WXK_F11: keySym = XK_F11; break;
|
||||||
|
case WXK_F12: keySym = XK_F12; break;
|
||||||
|
case WXK_F13: keySym = XK_F13; break;
|
||||||
|
case WXK_F14: keySym = XK_F14; break;
|
||||||
|
case WXK_F15: keySym = XK_F15; break;
|
||||||
|
case WXK_F16: keySym = XK_F16; break;
|
||||||
|
case WXK_F17: keySym = XK_F17; break;
|
||||||
|
case WXK_F18: keySym = XK_F18; break;
|
||||||
|
case WXK_F19: keySym = XK_F19; break;
|
||||||
|
case WXK_F20: keySym = XK_F20; break;
|
||||||
|
case WXK_F21: keySym = XK_F21; break;
|
||||||
|
case WXK_F22: keySym = XK_F22; break;
|
||||||
|
case WXK_F23: keySym = XK_F23; break;
|
||||||
|
case WXK_F24: keySym = XK_F24; break;
|
||||||
|
case WXK_NUMLOCK: keySym = XK_Num_Lock; break;
|
||||||
|
case WXK_SCROLL: keySym = XK_Scroll_Lock; break;
|
||||||
|
default: keySym = id <= 255 ? (KeySym)id : 0;
|
||||||
|
} // switch
|
||||||
|
return keySym;
|
||||||
|
}
|
||||||
|
@@ -36,10 +36,27 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Xm/Xm.h>
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
|
#include <Xm/DrawingA.h>
|
||||||
|
#include <Xm/ScrolledW.h>
|
||||||
|
#include <Xm/ScrollBar.h>
|
||||||
|
#include <Xm/Frame.h>
|
||||||
|
#include <Xm/Label.h>
|
||||||
|
|
||||||
#include "wx/motif/private.h"
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SCROLL_MARGIN 4
|
||||||
|
void wxCanvasRepaintProc (Widget, XtPointer, XmDrawingAreaCallbackStruct * cbs);
|
||||||
|
void wxCanvasInputEvent (Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs);
|
||||||
|
void wxCanvasMotionEvent (Widget, XButtonEvent * event);
|
||||||
|
void wxCanvasEnterLeave (Widget drawingArea, XtPointer clientData, XCrossingEvent * event);
|
||||||
|
|
||||||
|
#define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
|
||||||
|
#define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
|
||||||
|
#define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
|
||||||
|
|
||||||
extern wxList wxPendingDelete;
|
extern wxList wxPendingDelete;
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
@@ -87,18 +104,84 @@ wxWindow::wxWindow()
|
|||||||
m_pDropTarget = NULL;
|
m_pDropTarget = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// MOTIF-specific
|
/// Motif-specific
|
||||||
m_mainWidget = (WXWidget) 0;
|
m_mainWidget = (WXWidget) 0;
|
||||||
m_button1Pressed = FALSE;
|
m_button1Pressed = FALSE;
|
||||||
m_button2Pressed = FALSE;
|
m_button2Pressed = FALSE;
|
||||||
m_button3Pressed = FALSE;
|
m_button3Pressed = FALSE;
|
||||||
m_winCaptured = FALSE;
|
m_winCaptured = FALSE;
|
||||||
m_isShown = TRUE;
|
m_isShown = TRUE;
|
||||||
|
m_hScrollBar = (WXWidget) 0;
|
||||||
|
m_vScrollBar = (WXWidget) 0;
|
||||||
|
m_borderWidget = (WXWidget) 0;
|
||||||
|
m_scrolledWindow = (WXWidget) 0;
|
||||||
|
m_drawingArea = (WXWidget) 0;
|
||||||
|
m_hScroll = FALSE;
|
||||||
|
m_vScroll = FALSE;
|
||||||
|
m_hScrollingEnabled = FALSE;
|
||||||
|
m_vScrollingEnabled = FALSE;
|
||||||
|
m_backingPixmap = (WXPixmap) 0;
|
||||||
|
m_pixmapWidth = 0;
|
||||||
|
m_pixmapHeight = 0;
|
||||||
|
m_pixmapOffsetX = 0;
|
||||||
|
m_pixmapOffsetY = 0;
|
||||||
|
m_lastTS = 0;
|
||||||
|
m_lastButton = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
wxWindow::~wxWindow()
|
wxWindow::~wxWindow()
|
||||||
{
|
{
|
||||||
|
//// Motif-specific
|
||||||
|
|
||||||
|
// If m_drawingArea, we're a fully-fledged window with drawing area, scrollbars etc. (what wxCanvas used to be)
|
||||||
|
if (m_drawingArea)
|
||||||
|
{
|
||||||
|
// Destroy children before destroying self
|
||||||
|
DestroyChildren();
|
||||||
|
|
||||||
|
if (m_backingPixmap)
|
||||||
|
XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
|
||||||
|
|
||||||
|
Widget w = (Widget) m_drawingArea;
|
||||||
|
wxDeleteWindowFromTable(w);
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
XtDestroyWidget(w);
|
||||||
|
m_mainWidget = (WXWidget) 0;
|
||||||
|
|
||||||
|
// Only if we're _really_ a canvas (not a dialog box/panel)
|
||||||
|
if (m_scrolledWindow)
|
||||||
|
{
|
||||||
|
wxDeleteWindowFromTable((Widget) m_scrolledWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hScrollBar)
|
||||||
|
{
|
||||||
|
XtUnmanageChild ((Widget) m_hScrollBar);
|
||||||
|
XtDestroyWidget ((Widget) m_hScrollBar);
|
||||||
|
}
|
||||||
|
if (m_vScrollBar)
|
||||||
|
{
|
||||||
|
XtUnmanageChild ((Widget) m_vScrollBar);
|
||||||
|
XtDestroyWidget ((Widget) m_vScrollBar);
|
||||||
|
}
|
||||||
|
if (m_scrolledWindow)
|
||||||
|
{
|
||||||
|
XtUnmanageChild ((Widget) m_scrolledWindow);
|
||||||
|
XtDestroyWidget ((Widget) m_scrolledWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_borderWidget)
|
||||||
|
{
|
||||||
|
XtDestroyWidget ((Widget) m_borderWidget);
|
||||||
|
m_borderWidget = (WXWidget) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// Generic stuff
|
||||||
|
|
||||||
// Have to delete constraints/sizer FIRST otherwise
|
// Have to delete constraints/sizer FIRST otherwise
|
||||||
// sizers may try to look at deleted windows as they
|
// sizers may try to look at deleted windows as they
|
||||||
// delete themselves.
|
// delete themselves.
|
||||||
@@ -174,11 +257,9 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
|
|||||||
m_sizerParent = NULL;
|
m_sizerParent = NULL;
|
||||||
m_autoLayout = FALSE;
|
m_autoLayout = FALSE;
|
||||||
m_windowValidator = NULL;
|
m_windowValidator = NULL;
|
||||||
|
|
||||||
#if USE_DRAG_AND_DROP
|
#if USE_DRAG_AND_DROP
|
||||||
m_pDropTarget = NULL;
|
m_pDropTarget = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_caretWidth = 0; m_caretHeight = 0;
|
m_caretWidth = 0; m_caretHeight = 0;
|
||||||
m_caretEnabled = FALSE;
|
m_caretEnabled = FALSE;
|
||||||
m_caretShown = FALSE;
|
m_caretShown = FALSE;
|
||||||
@@ -188,6 +269,29 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
|
|||||||
m_maxSizeY = -1;
|
m_maxSizeY = -1;
|
||||||
m_defaultItem = NULL;
|
m_defaultItem = NULL;
|
||||||
m_windowParent = NULL;
|
m_windowParent = NULL;
|
||||||
|
|
||||||
|
// Motif-specific
|
||||||
|
m_mainWidget = (WXWidget) 0;
|
||||||
|
m_button1Pressed = FALSE;
|
||||||
|
m_button2Pressed = FALSE;
|
||||||
|
m_button3Pressed = FALSE;
|
||||||
|
m_winCaptured = FALSE;
|
||||||
|
m_isShown = TRUE;
|
||||||
|
m_hScrollBar = (WXWidget) 0;
|
||||||
|
m_vScrollBar = (WXWidget) 0;
|
||||||
|
m_borderWidget = (WXWidget) 0;
|
||||||
|
m_scrolledWindow = (WXWidget) 0;
|
||||||
|
m_drawingArea = (WXWidget) 0;
|
||||||
|
m_hScroll = FALSE;
|
||||||
|
m_vScroll = FALSE;
|
||||||
|
m_hScrollingEnabled = FALSE;
|
||||||
|
m_vScrollingEnabled = FALSE;
|
||||||
|
m_backingPixmap = (WXPixmap) 0;
|
||||||
|
m_pixmapWidth = 0;
|
||||||
|
m_pixmapHeight = 0;
|
||||||
|
m_pixmapOffsetX = 0;
|
||||||
|
m_pixmapOffsetY = 0;
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -214,7 +318,92 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
|
|||||||
else
|
else
|
||||||
m_windowId = id;
|
m_windowId = id;
|
||||||
|
|
||||||
// TODO: create the window
|
//// TODO: we should probably optimize by only creating a
|
||||||
|
//// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
|
||||||
|
//// But for now, let's simplify things by always creating the
|
||||||
|
//// drawing area, since otherwise the translations are different.
|
||||||
|
|
||||||
|
// New translations for getting mouse motion feedback
|
||||||
|
String translations =
|
||||||
|
"<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
|
||||||
|
<Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
|
||||||
|
<Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
|
||||||
|
<BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
|
||||||
|
<Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
|
||||||
|
<Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
|
||||||
|
<Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
|
||||||
|
<Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
|
||||||
|
<Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
|
||||||
|
<Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
|
||||||
|
<Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
|
||||||
|
<EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
|
||||||
|
<LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
|
||||||
|
<Key>: DrawingAreaInput()";
|
||||||
|
|
||||||
|
XtActionsRec actions[1];
|
||||||
|
actions[0].string = "wxCanvasMotionEvent";
|
||||||
|
actions[0].proc = (XtActionProc) wxCanvasMotionEvent;
|
||||||
|
XtAppAddActions ((XtAppContext) wxTheApp->GetAppContext(), actions, 1);
|
||||||
|
|
||||||
|
Widget parentWidget = (Widget) parent->GetClientWidget();
|
||||||
|
if (style & wxBORDER)
|
||||||
|
m_borderWidget = (WXWidget) XtVaCreateManagedWidget ("canvasBorder",
|
||||||
|
xmFrameWidgetClass, parentWidget,
|
||||||
|
XmNshadowType, XmSHADOW_IN,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
m_scrolledWindow = (WXWidget) XtVaCreateManagedWidget ("scrolledWindow",
|
||||||
|
xmScrolledWindowWidgetClass, m_borderWidget ? (Widget) m_borderWidget : parentWidget,
|
||||||
|
XmNspacing, 0,
|
||||||
|
XmNscrollingPolicy, XmAPPLICATION_DEFINED,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
XtTranslations ptr;
|
||||||
|
m_drawingArea = (WXWidget) XtVaCreateWidget ((char*) (const char*) name,
|
||||||
|
xmDrawingAreaWidgetClass, (Widget) m_scrolledWindow,
|
||||||
|
XmNunitType, XmPIXELS,
|
||||||
|
// XmNresizePolicy, XmRESIZE_ANY,
|
||||||
|
XmNresizePolicy, XmRESIZE_NONE,
|
||||||
|
XmNmarginHeight, 0,
|
||||||
|
XmNmarginWidth, 0,
|
||||||
|
XmNtranslations, ptr = XtParseTranslationTable (translations),
|
||||||
|
NULL);
|
||||||
|
/*
|
||||||
|
if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS)
|
||||||
|
{
|
||||||
|
XtFree ((char *) ptr);
|
||||||
|
ptr = XtParseTranslationTable ("<Key>: DrawingAreaInput()");
|
||||||
|
XtOverrideTranslations ((Widget) m_drawingArea, ptr);
|
||||||
|
XtFree ((char *) ptr);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxAddWindowToTable((Widget) m_drawingArea, this);
|
||||||
|
wxAddWindowToTable((Widget) m_scrolledWindow, this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This order is very important in Motif 1.2.1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
XtRealizeWidget ((Widget) m_scrolledWindow);
|
||||||
|
XtRealizeWidget ((Widget) m_drawingArea);
|
||||||
|
XtManageChild ((Widget) m_drawingArea);
|
||||||
|
|
||||||
|
XtOverrideTranslations ((Widget) m_drawingArea,
|
||||||
|
ptr = XtParseTranslationTable ("<Configure>: resize()"));
|
||||||
|
XtFree ((char *) ptr);
|
||||||
|
|
||||||
|
XtAddCallback ((Widget) m_drawingArea, XmNexposeCallback, (XtCallbackProc) wxCanvasRepaintProc, (XtPointer) this);
|
||||||
|
XtAddCallback ((Widget) m_drawingArea, XmNinputCallback, (XtCallbackProc) wxCanvasInputEvent, (XtPointer) this);
|
||||||
|
|
||||||
|
/* TODO?
|
||||||
|
display = XtDisplay (scrolledWindow);
|
||||||
|
xwindow = XtWindow (drawingArea);
|
||||||
|
*/
|
||||||
|
|
||||||
|
XtAddEventHandler ((Widget) m_drawingArea, PointerMotionHintMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask,
|
||||||
|
False, (XtEventHandler) wxCanvasEnterLeave, (XtPointer) this);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -309,6 +498,12 @@ void wxWindow::DragAcceptFiles(bool accept)
|
|||||||
// Get total size
|
// Get total size
|
||||||
void wxWindow::GetSize(int *x, int *y) const
|
void wxWindow::GetSize(int *x, int *y) const
|
||||||
{
|
{
|
||||||
|
if (m_drawingArea)
|
||||||
|
{
|
||||||
|
CanvasGetSize(x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Widget widget = (Widget) GetMainWidget();
|
Widget widget = (Widget) GetMainWidget();
|
||||||
Dimension xx, yy;
|
Dimension xx, yy;
|
||||||
XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
|
XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
|
||||||
@@ -317,6 +512,11 @@ void wxWindow::GetSize(int *x, int *y) const
|
|||||||
|
|
||||||
void wxWindow::GetPosition(int *x, int *y) const
|
void wxWindow::GetPosition(int *x, int *y) const
|
||||||
{
|
{
|
||||||
|
if (m_drawingArea)
|
||||||
|
{
|
||||||
|
CanvasGetPosition(x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Widget widget = (Widget) GetMainWidget();
|
Widget widget = (Widget) GetMainWidget();
|
||||||
Position xx, yy;
|
Position xx, yy;
|
||||||
XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
|
XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
|
||||||
@@ -377,6 +577,11 @@ void wxWindow::GetClientSize(int *x, int *y) const
|
|||||||
|
|
||||||
void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
|
void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
|
||||||
{
|
{
|
||||||
|
if (m_drawingArea)
|
||||||
|
{
|
||||||
|
CanvasSetSize(x, y, width, height, sizeFlags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Widget widget = (Widget) GetMainWidget();
|
Widget widget = (Widget) GetMainWidget();
|
||||||
|
|
||||||
if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
||||||
@@ -396,6 +601,12 @@ void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
|
|||||||
|
|
||||||
void wxWindow::SetClientSize(int width, int height)
|
void wxWindow::SetClientSize(int width, int height)
|
||||||
{
|
{
|
||||||
|
if (m_drawingArea)
|
||||||
|
{
|
||||||
|
CanvasSetClientSize(width, height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Widget widget = (Widget) GetMainWidget();
|
Widget widget = (Widget) GetMainWidget();
|
||||||
|
|
||||||
if (width > -1)
|
if (width > -1)
|
||||||
@@ -429,12 +640,37 @@ void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
|
|||||||
|
|
||||||
bool wxWindow::Show(bool show)
|
bool wxWindow::Show(bool show)
|
||||||
{
|
{
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
if (m_borderWidget || m_scrolledWindow)
|
||||||
|
{
|
||||||
|
XtMapWidget(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XtMapWidget((Widget) GetMainWidget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_borderWidget || m_scrolledWindow)
|
||||||
|
{
|
||||||
|
XtUnmapWidget(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XtUnmapWidget((Widget) GetMainWidget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Window xwin = (Window) GetXWindow();
|
Window xwin = (Window) GetXWindow();
|
||||||
Display *xdisp = (Display*) GetXDisplay();
|
Display *xdisp = (Display*) GetXDisplay();
|
||||||
if (show)
|
if (show)
|
||||||
XMapWindow(xdisp, xwin);
|
XMapWindow(xdisp, xwin);
|
||||||
else
|
else
|
||||||
XUnmapWindow(xdisp, xwin);
|
XUnmapWindow(xdisp, xwin);
|
||||||
|
*/
|
||||||
|
|
||||||
m_isShown = show;
|
m_isShown = show;
|
||||||
|
|
||||||
@@ -640,9 +876,9 @@ void wxWindow::Centre(int direction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Coordinates relative to the window
|
// Coordinates relative to the window
|
||||||
void wxWindow::WarpPointer (int x_pos, int y_pos)
|
void wxWindow::WarpPointer (int x, int y)
|
||||||
{
|
{
|
||||||
// TODO
|
XWarpPointer (XtDisplay((Widget) GetClientWidget()), None, XtWindow((Widget) GetClientWidget()), 0, 0, 0, 0, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWindow::OnEraseBackground(wxEraseEvent& event)
|
void wxWindow::OnEraseBackground(wxEraseEvent& event)
|
||||||
@@ -1493,17 +1729,564 @@ void wxDeleteWindowFromTable(Widget w)
|
|||||||
// Get the underlying X window and display
|
// Get the underlying X window and display
|
||||||
WXWindow wxWindow::GetXWindow() const
|
WXWindow wxWindow::GetXWindow() const
|
||||||
{
|
{
|
||||||
return (WXWindow) XtWindow((Widget) GetMainWidget());
|
return (WXWindow) XtWindow((Widget) GetMainWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDisplay *wxWindow::GetXDisplay() const
|
WXDisplay *wxWindow::GetXDisplay() const
|
||||||
{
|
{
|
||||||
return (WXDisplay*) XtDisplay((Widget) GetMainWidget());
|
return (WXDisplay*) XtDisplay((Widget) GetMainWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
WXWidget wxWindow::GetMainWidget() const
|
WXWidget wxWindow::GetMainWidget() const
|
||||||
{
|
{
|
||||||
return m_mainWidget;
|
if (m_drawingArea)
|
||||||
|
return m_drawingArea;
|
||||||
|
else
|
||||||
|
return m_mainWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXWidget wxWindow::GetClientWidget() const
|
||||||
|
{
|
||||||
|
if (m_drawingArea != (WXWidget) 0)
|
||||||
|
return m_drawingArea;
|
||||||
|
else
|
||||||
|
return m_mainWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasRepaintProc (Widget drawingArea, XtPointer clientData,
|
||||||
|
XmDrawingAreaCallbackStruct * cbs)
|
||||||
|
{
|
||||||
|
if (!wxWidgetHashTable->Get ((long) (Widget) drawingArea))
|
||||||
|
return;
|
||||||
|
|
||||||
|
XEvent * event = cbs->event;
|
||||||
|
wxWindow * canvas = (wxWindow *) clientData;
|
||||||
|
Display * display = (Display *) canvas->GetXDisplay();
|
||||||
|
// GC gc = (GC) canvas->GetDC()->gc;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case Expose:
|
||||||
|
{
|
||||||
|
/* TODO
|
||||||
|
wxCanvasDC* canvasDC = canvas->GetDC();
|
||||||
|
if (canvasDC)
|
||||||
|
{
|
||||||
|
if (canvasDC->onpaint_reg)
|
||||||
|
XDestroyRegion(canvasDC->onpaint_reg);
|
||||||
|
canvasDC->onpaint_reg = XCreateRegion();
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int n = canvas->m_updateRects.Number();
|
||||||
|
XRectangle* xrects = new XRectangle[n];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < canvas->m_updateRects.Number(); i++)
|
||||||
|
{
|
||||||
|
wxRect* rect = (wxRect*) canvas->m_updateRects.Nth(i)->Data();
|
||||||
|
xrects[i].x = rect->x;
|
||||||
|
xrects[i].y = rect->y;
|
||||||
|
xrects[i].width = rect->width;
|
||||||
|
xrects[i].height = rect->height;
|
||||||
|
/* TODO (?) Actually ignore it I think.
|
||||||
|
if (canvasDC)
|
||||||
|
XUnionRectWithRegion(&(xrects[i]), canvasDC->onpaint_reg,
|
||||||
|
canvasDC->onpaint_reg);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/* TODO must clip the area being repainted. So we need a gc.
|
||||||
|
* Alternatively, wxPaintDC must do the clipping
|
||||||
|
* when it's created.
|
||||||
|
XSetClipRectangles(display, gc, 0, 0, xrects, n, Unsorted);
|
||||||
|
*/
|
||||||
|
|
||||||
|
canvas->DoPaint() ; // xrects, n);
|
||||||
|
delete[] xrects;
|
||||||
|
|
||||||
|
canvas->m_updateRects.Clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (canvasDC)
|
||||||
|
{
|
||||||
|
XDestroyRegion(canvasDC->onpaint_reg);
|
||||||
|
canvasDC->onpaint_reg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
XGCValues gc_val;
|
||||||
|
gc_val.clip_mask = None;
|
||||||
|
XChangeGC(display, gc, GCClipMask, &gc_val);
|
||||||
|
*/
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
cout << "\n\nNew Event ! is = " << event -> type << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
|
||||||
|
void
|
||||||
|
wxCanvasEnterLeave (Widget drawingArea, XtPointer clientData, XCrossingEvent * event)
|
||||||
|
{
|
||||||
|
XmDrawingAreaCallbackStruct cbs;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
//if (event->mode!=NotifyNormal)
|
||||||
|
// return ;
|
||||||
|
|
||||||
|
// ev = *((XEvent *) event); // Causes Purify error (copying too many bytes)
|
||||||
|
((XCrossingEvent &) ev) = *event;
|
||||||
|
|
||||||
|
cbs.reason = XmCR_INPUT;
|
||||||
|
cbs.event = &ev;
|
||||||
|
|
||||||
|
wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix to make it work under Motif 1.0 (!)
|
||||||
|
void wxCanvasMotionEvent (Widget drawingArea, XButtonEvent * event)
|
||||||
|
{
|
||||||
|
#if XmVersion<=1000
|
||||||
|
|
||||||
|
XmDrawingAreaCallbackStruct cbs;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
//ev.xbutton = *event;
|
||||||
|
ev = *((XEvent *) event);
|
||||||
|
cbs.reason = XmCR_INPUT;
|
||||||
|
cbs.event = &ev;
|
||||||
|
|
||||||
|
wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasInputEvent (Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs)
|
||||||
|
{
|
||||||
|
wxWindow *canvas = (wxWindow *) wxWidgetHashTable->Get ((long) (Widget) drawingArea);
|
||||||
|
XEvent local_event;
|
||||||
|
|
||||||
|
if (canvas==NULL)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if (cbs->reason != XmCR_INPUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
local_event = *(cbs->event); // We must keep a copy!
|
||||||
|
|
||||||
|
switch (local_event.xany.type)
|
||||||
|
{
|
||||||
|
case EnterNotify:
|
||||||
|
case LeaveNotify:
|
||||||
|
case ButtonPress:
|
||||||
|
case ButtonRelease:
|
||||||
|
case MotionNotify:
|
||||||
|
{
|
||||||
|
wxEventType eventType = wxEVT_NULL;
|
||||||
|
|
||||||
|
if (local_event.xany.type == EnterNotify)
|
||||||
|
{
|
||||||
|
//if (local_event.xcrossing.mode!=NotifyNormal)
|
||||||
|
// return ; // Ignore grab events
|
||||||
|
eventType = wxEVT_ENTER_WINDOW;
|
||||||
|
// canvas->GetEventHandler()->OnSetFocus();
|
||||||
|
}
|
||||||
|
else if (local_event.xany.type == LeaveNotify)
|
||||||
|
{
|
||||||
|
//if (local_event.xcrossing.mode!=NotifyNormal)
|
||||||
|
// return ; // Ignore grab events
|
||||||
|
eventType = wxEVT_LEAVE_WINDOW;
|
||||||
|
// canvas->GetEventHandler()->OnKillFocus();
|
||||||
|
}
|
||||||
|
else if (local_event.xany.type == MotionNotify)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_MOTION;
|
||||||
|
if (local_event.xmotion.is_hint == NotifyHint)
|
||||||
|
{
|
||||||
|
Window root, child;
|
||||||
|
Display *dpy = XtDisplay (drawingArea);
|
||||||
|
|
||||||
|
XQueryPointer (dpy, XtWindow (drawingArea),
|
||||||
|
&root, &child,
|
||||||
|
&local_event.xmotion.x_root,
|
||||||
|
&local_event.xmotion.y_root,
|
||||||
|
&local_event.xmotion.x,
|
||||||
|
&local_event.xmotion.y,
|
||||||
|
&local_event.xmotion.state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (local_event.xany.type == ButtonPress)
|
||||||
|
{
|
||||||
|
if (local_event.xbutton.button == Button1)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_LEFT_DOWN;
|
||||||
|
canvas->m_button1Pressed = TRUE;
|
||||||
|
}
|
||||||
|
else if (local_event.xbutton.button == Button2)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_MIDDLE_DOWN;
|
||||||
|
canvas->m_button2Pressed = TRUE;
|
||||||
|
}
|
||||||
|
else if (local_event.xbutton.button == Button3)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_RIGHT_DOWN;
|
||||||
|
canvas->m_button3Pressed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (local_event.xany.type == ButtonRelease)
|
||||||
|
{
|
||||||
|
if (local_event.xbutton.button == Button1)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_LEFT_UP;
|
||||||
|
canvas->m_button1Pressed = FALSE;
|
||||||
|
}
|
||||||
|
else if (local_event.xbutton.button == Button2)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_MIDDLE_UP;
|
||||||
|
canvas->m_button2Pressed = FALSE;
|
||||||
|
}
|
||||||
|
else if (local_event.xbutton.button == Button3)
|
||||||
|
{
|
||||||
|
eventType = wxEVT_RIGHT_UP;
|
||||||
|
canvas->m_button3Pressed = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMouseEvent wxevent (eventType);
|
||||||
|
wxevent.m_eventHandle = (char *) &local_event;
|
||||||
|
|
||||||
|
wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
|
||||||
|
|| (event_left_is_down (&local_event)
|
||||||
|
&& (eventType != wxEVT_LEFT_UP)));
|
||||||
|
wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
|
||||||
|
|| (event_middle_is_down (&local_event)
|
||||||
|
&& (eventType != wxEVT_MIDDLE_UP)));
|
||||||
|
wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
|
||||||
|
|| (event_right_is_down (&local_event)
|
||||||
|
&& (eventType != wxEVT_RIGHT_UP)));
|
||||||
|
|
||||||
|
wxevent.m_shiftDown = local_event.xbutton.state & ShiftMask;
|
||||||
|
wxevent.m_controlDown = local_event.xbutton.state & ControlMask;
|
||||||
|
wxevent.m_altDown = local_event.xbutton.state & Mod3Mask;
|
||||||
|
wxevent.m_metaDown = local_event.xbutton.state & Mod1Mask;
|
||||||
|
wxevent.SetTimestamp(local_event.xbutton.time);
|
||||||
|
|
||||||
|
// Now check if we need to translate this event into a double click
|
||||||
|
if (TRUE) // canvas->doubleClickAllowed)
|
||||||
|
{
|
||||||
|
if (wxevent.ButtonDown())
|
||||||
|
{
|
||||||
|
long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()) ;
|
||||||
|
|
||||||
|
// get button and time-stamp
|
||||||
|
int button = 0;
|
||||||
|
if (wxevent.LeftDown()) button = 1;
|
||||||
|
else if (wxevent.MiddleDown()) button = 2;
|
||||||
|
else if (wxevent.RightDown()) button = 3;
|
||||||
|
long ts = wxevent.GetTimestamp();
|
||||||
|
// check, if single or double click
|
||||||
|
if (canvas->m_lastButton && canvas->m_lastButton==button && (ts - canvas->m_lastTS) < dclickTime)
|
||||||
|
{
|
||||||
|
// I have a dclick
|
||||||
|
canvas->m_lastButton = 0;
|
||||||
|
switch ( eventType )
|
||||||
|
{
|
||||||
|
case wxEVT_LEFT_DOWN:
|
||||||
|
wxevent.SetEventType(wxEVT_LEFT_DCLICK);
|
||||||
|
break;
|
||||||
|
case wxEVT_MIDDLE_DOWN:
|
||||||
|
wxevent.SetEventType(wxEVT_MIDDLE_DCLICK);
|
||||||
|
break;
|
||||||
|
case wxEVT_RIGHT_DOWN:
|
||||||
|
wxevent.SetEventType(wxEVT_RIGHT_DCLICK);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not fast enough or different button
|
||||||
|
canvas->m_lastTS = ts;
|
||||||
|
canvas->m_lastButton = button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxevent.SetId(canvas->GetId());
|
||||||
|
wxevent.SetEventObject(canvas);
|
||||||
|
canvas->GetEventHandler()->ProcessEvent (wxevent);
|
||||||
|
/*
|
||||||
|
if (eventType == wxEVT_ENTER_WINDOW ||
|
||||||
|
eventType == wxEVT_LEAVE_WINDOW ||
|
||||||
|
eventType == wxEVT_MOTION
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KeyPress:
|
||||||
|
{
|
||||||
|
KeySym keySym;
|
||||||
|
// XComposeStatus compose;
|
||||||
|
// (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, &compose);
|
||||||
|
(void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL);
|
||||||
|
int id = wxCharCodeXToWX (keySym);
|
||||||
|
|
||||||
|
wxKeyEvent event (wxEVT_CHAR);
|
||||||
|
|
||||||
|
if (local_event.xkey.state & ShiftMask)
|
||||||
|
event.m_shiftDown = TRUE;
|
||||||
|
if (local_event.xkey.state & ControlMask)
|
||||||
|
event.m_controlDown = TRUE;
|
||||||
|
if (local_event.xkey.state & Mod3Mask)
|
||||||
|
event.m_altDown = TRUE;
|
||||||
|
if (local_event.xkey.state & Mod1Mask)
|
||||||
|
event.m_metaDown = TRUE;
|
||||||
|
event.SetEventObject(canvas);
|
||||||
|
event.m_keyCode = id;
|
||||||
|
event.SetTimestamp(local_event.xkey.time);
|
||||||
|
|
||||||
|
if (id > -1)
|
||||||
|
{
|
||||||
|
// Implement wxFrame::OnCharHook by checking ancestor.
|
||||||
|
wxWindow *parent = canvas->GetParent();
|
||||||
|
while (parent && !parent->IsKindOf(CLASSINFO(wxFrame)))
|
||||||
|
parent = parent->GetParent();
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
event.SetEventType(wxEVT_CHAR_HOOK);
|
||||||
|
if (parent->GetEventHandler()->ProcessEvent(event))
|
||||||
|
return;
|
||||||
|
event.SetEventType(wxEVT_CHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas->GetEventHandler()->ProcessEvent (event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FocusIn:
|
||||||
|
{
|
||||||
|
if (local_event.xfocus.detail != NotifyPointer)
|
||||||
|
{
|
||||||
|
wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId());
|
||||||
|
event.SetEventObject(canvas);
|
||||||
|
canvas->GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FocusOut:
|
||||||
|
{
|
||||||
|
if (local_event.xfocus.detail != NotifyPointer)
|
||||||
|
{
|
||||||
|
wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId());
|
||||||
|
event.SetEventObject(canvas);
|
||||||
|
canvas->GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::DoPaint()
|
||||||
|
{
|
||||||
|
//TODO : make a temporary gc so we can do the XCopyArea below
|
||||||
|
if (0) // m_backingPixmap)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Widget drawingArea = (Widget) m_drawingArea;
|
||||||
|
// int orig = GetDC()->GetLogicalFunction();
|
||||||
|
// GetDC()->SetLogicalFunction (wxCOPY);
|
||||||
|
|
||||||
|
// TODO: it may not be necessary to store m_pixmapOffsetX/Y; we
|
||||||
|
// should be able to calculate them.
|
||||||
|
XCopyArea (XtDisplay (drawingArea), m_backingPixmap, XtWindow (drawingArea), GetDC ()->gc,
|
||||||
|
m_pixmapOffsetX, m_pixmapOffsetY,
|
||||||
|
m_pixmapWidth, m_pixmapHeight,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
// GetDC()->SetLogicalFunction (orig);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxPaintEvent event(GetId());
|
||||||
|
event.SetEventObject(this);
|
||||||
|
GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSize, but as per old wxCanvas (with drawing widget etc.)
|
||||||
|
void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
|
||||||
|
{
|
||||||
|
Widget drawingArea = (Widget) m_drawingArea;
|
||||||
|
bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
|
||||||
|
XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
|
||||||
|
|
||||||
|
if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
||||||
|
{
|
||||||
|
XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
|
||||||
|
XmNx, x, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
|
||||||
|
{
|
||||||
|
XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
|
||||||
|
XmNy, y, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w > -1)
|
||||||
|
{
|
||||||
|
if (m_borderWidget)
|
||||||
|
{
|
||||||
|
XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL);
|
||||||
|
short thick, margin;
|
||||||
|
XtVaGetValues ((Widget) m_borderWidget,
|
||||||
|
XmNshadowThickness, &thick,
|
||||||
|
XmNmarginWidth, &margin,
|
||||||
|
NULL);
|
||||||
|
w -= 2 * (thick + margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL);
|
||||||
|
|
||||||
|
Dimension spacing;
|
||||||
|
Widget sbar;
|
||||||
|
XtVaGetValues ((Widget) m_scrolledWindow,
|
||||||
|
XmNspacing, &spacing,
|
||||||
|
XmNverticalScrollBar, &sbar,
|
||||||
|
NULL);
|
||||||
|
Dimension wsbar;
|
||||||
|
if (sbar)
|
||||||
|
XtVaGetValues (sbar, XmNwidth, &wsbar, NULL);
|
||||||
|
else
|
||||||
|
wsbar = 0;
|
||||||
|
|
||||||
|
w -= (spacing + wsbar);
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
|
||||||
|
}
|
||||||
|
if (h > -1)
|
||||||
|
{
|
||||||
|
if (m_borderWidget)
|
||||||
|
{
|
||||||
|
XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL);
|
||||||
|
short thick, margin;
|
||||||
|
XtVaGetValues ((Widget) m_borderWidget,
|
||||||
|
XmNshadowThickness, &thick,
|
||||||
|
XmNmarginHeight, &margin,
|
||||||
|
NULL);
|
||||||
|
h -= 2 * (thick + margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL);
|
||||||
|
|
||||||
|
Dimension spacing;
|
||||||
|
Widget sbar;
|
||||||
|
XtVaGetValues ((Widget) m_scrolledWindow,
|
||||||
|
XmNspacing, &spacing,
|
||||||
|
XmNhorizontalScrollBar, &sbar,
|
||||||
|
NULL);
|
||||||
|
Dimension wsbar;
|
||||||
|
if (sbar)
|
||||||
|
XtVaGetValues (sbar, XmNheight, &wsbar, NULL);
|
||||||
|
else
|
||||||
|
wsbar = 0;
|
||||||
|
|
||||||
|
h -= (spacing + wsbar);
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
|
||||||
|
}
|
||||||
|
if (managed)
|
||||||
|
XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
|
||||||
|
XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
|
||||||
|
|
||||||
|
int ww, hh;
|
||||||
|
GetClientSize (&ww, &hh);
|
||||||
|
wxSizeEvent sizeEvent(wxSize(ww, hh), GetId());
|
||||||
|
sizeEvent.SetEventObject(this);
|
||||||
|
|
||||||
|
GetEventHandler()->ProcessEvent(sizeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::CanvasSetClientSize (int w, int h)
|
||||||
|
{
|
||||||
|
Widget drawingArea = (Widget) m_drawingArea;
|
||||||
|
|
||||||
|
XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
|
||||||
|
|
||||||
|
if (w > -1)
|
||||||
|
XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
|
||||||
|
if (h > -1)
|
||||||
|
XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
|
||||||
|
/* TODO: is this necessary?
|
||||||
|
allowRepainting = FALSE;
|
||||||
|
|
||||||
|
XSync (XtDisplay (drawingArea), FALSE);
|
||||||
|
XEvent event;
|
||||||
|
while (XtAppPending (wxTheApp->appContext))
|
||||||
|
{
|
||||||
|
XFlush (XtDisplay (drawingArea));
|
||||||
|
XtAppNextEvent (wxTheApp->appContext, &event);
|
||||||
|
XtDispatchEvent (&event);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
allowRepainting = TRUE;
|
||||||
|
DoRefresh ();
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxSizeEvent sizeEvent(wxSize(w, h), GetId());
|
||||||
|
sizeEvent.SetEventObject(this);
|
||||||
|
|
||||||
|
GetEventHandler()->ProcessEvent(sizeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::CanvasGetClientSize (int *w, int *h) const
|
||||||
|
{
|
||||||
|
// Must return the same thing that was set via SetClientSize
|
||||||
|
Dimension xx, yy;
|
||||||
|
XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
|
||||||
|
*w = xx;
|
||||||
|
*h = yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::CanvasGetSize (int *w, int *h) const
|
||||||
|
{
|
||||||
|
Dimension xx, yy;
|
||||||
|
if ((Widget) m_borderWidget)
|
||||||
|
XtVaGetValues ((Widget) m_borderWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
|
||||||
|
else if ((Widget) m_scrolledWindow)
|
||||||
|
XtVaGetValues ((Widget) m_scrolledWindow, XmNwidth, &xx, XmNheight, &yy, NULL);
|
||||||
|
else
|
||||||
|
XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
|
||||||
|
|
||||||
|
*w = xx;
|
||||||
|
*h = yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::CanvasGetPosition (int *x, int *y) const
|
||||||
|
{
|
||||||
|
Position xx, yy;
|
||||||
|
XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
|
||||||
|
*x = xx;
|
||||||
|
*y = yy;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user