More wxMotif work, OGL enhancements, USE_ macro corrections, object.cpp delete
operator correction for VC++ 6 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@780 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -902,6 +902,9 @@ typedef void* WXFontStructPtr;
|
|||||||
typedef void* WXGC;
|
typedef void* WXGC;
|
||||||
typedef void* WXRegion;
|
typedef void* WXRegion;
|
||||||
typedef void* WXFont;
|
typedef void* WXFont;
|
||||||
|
typedef void* WXImage;
|
||||||
|
typedef void* WXCursor;
|
||||||
|
typedef void* WXFontList;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
// Standard cursors
|
// Standard cursors
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
wxCURSOR_NONE = 0,
|
||||||
wxCURSOR_ARROW = 1,
|
wxCURSOR_ARROW = 1,
|
||||||
wxCURSOR_BULLSEYE,
|
wxCURSOR_BULLSEYE,
|
||||||
wxCURSOR_CHAR,
|
wxCURSOR_CHAR,
|
||||||
@@ -57,7 +58,7 @@ typedef enum {
|
|||||||
wxCURSOR_BASED_ARROW_UP,
|
wxCURSOR_BASED_ARROW_UP,
|
||||||
wxCURSOR_BASED_ARROW_DOWN
|
wxCURSOR_BASED_ARROW_DOWN
|
||||||
#endif
|
#endif
|
||||||
} _standard_cursors_t;
|
} wxStockCursor;
|
||||||
|
|
||||||
class WXDLLEXPORT wxSize
|
class WXDLLEXPORT wxSize
|
||||||
{
|
{
|
||||||
|
@@ -55,6 +55,7 @@ public:
|
|||||||
bool Create(const wxBitmap& bitmap);
|
bool Create(const wxBitmap& bitmap);
|
||||||
|
|
||||||
inline WXPixmap GetPixmap() const { return m_pixmap; }
|
inline WXPixmap GetPixmap() const { return m_pixmap; }
|
||||||
|
inline void SetPixmap(WXPixmap pixmap) { m_pixmap = pixmap; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WXPixmap m_pixmap;
|
WXPixmap m_pixmap;
|
||||||
@@ -70,20 +71,30 @@ public:
|
|||||||
~wxBitmapRefData();
|
~wxBitmapRefData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
int m_depth;
|
int m_depth;
|
||||||
bool m_ok;
|
bool m_ok;
|
||||||
int m_numColors;
|
int m_numColors;
|
||||||
wxPalette m_bitmapPalette;
|
wxPalette m_bitmapPalette;
|
||||||
int m_quality;
|
int m_quality;
|
||||||
|
|
||||||
wxMask * m_bitmapMask; // Optional mask
|
wxMask * m_bitmapMask; // Optional mask
|
||||||
|
|
||||||
// Motif implementation
|
// Motif implementation
|
||||||
public:
|
public:
|
||||||
WXPixmap m_pixmap;
|
WXPixmap m_pixmap;
|
||||||
WXDisplay* m_display;
|
WXDisplay* m_display;
|
||||||
|
bool m_freePixmap;
|
||||||
|
unsigned long* m_freeColors;
|
||||||
|
long m_freeColorsCount;
|
||||||
|
|
||||||
|
// These 5 variables are for wxControl
|
||||||
|
WXPixmap m_insensPixmap ;
|
||||||
|
WXPixmap m_labelPixmap ;
|
||||||
|
WXPixmap m_armPixmap ;
|
||||||
|
WXImage* m_image ;
|
||||||
|
WXImage* m_insensImage ;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
|
#define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
|
||||||
@@ -127,17 +138,14 @@ public:
|
|||||||
{ Ref(bitmap); if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); }
|
{ Ref(bitmap); if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); }
|
||||||
inline wxBitmap(const wxBitmap* bitmap) { if (bitmap) Ref(*bitmap); if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); }
|
inline wxBitmap(const wxBitmap* bitmap) { if (bitmap) Ref(*bitmap); if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); }
|
||||||
|
|
||||||
// Initialize with raw data.
|
// Initialize with raw XBM data
|
||||||
wxBitmap(const char bits[], int width, int height, int depth = 1);
|
wxBitmap(const char bits[], int width, int height, int depth = 1);
|
||||||
|
|
||||||
/* TODO: maybe implement XPM reading
|
|
||||||
// Initialize with XPM data
|
// Initialize with XPM data
|
||||||
wxBitmap(const char **data);
|
wxBitmap(const char **data, wxControl* control = NULL);
|
||||||
*/
|
|
||||||
|
|
||||||
// Load a file or resource
|
// Load a file or resource
|
||||||
// TODO: make default type whatever's appropriate for the platform.
|
wxBitmap(const wxString& name, long type = wxBITMAP_TYPE_XBM);
|
||||||
wxBitmap(const wxString& name, long type = wxBITMAP_TYPE_BMP_RESOURCE);
|
|
||||||
|
|
||||||
// Constructor for generalised creation from data
|
// Constructor for generalised creation from data
|
||||||
wxBitmap(void *data, long type, int width, int height, int depth = 1);
|
wxBitmap(void *data, long type, int width, int height, int depth = 1);
|
||||||
@@ -148,7 +156,7 @@ public:
|
|||||||
|
|
||||||
virtual bool Create(int width, int height, int depth = -1);
|
virtual bool Create(int width, int height, int depth = -1);
|
||||||
virtual bool Create(void *data, long type, int width, int height, int depth = 1);
|
virtual bool Create(void *data, long type, int width, int height, int depth = 1);
|
||||||
virtual bool LoadFile(const wxString& name, long type = wxBITMAP_TYPE_BMP_RESOURCE);
|
virtual bool LoadFile(const wxString& name, long type = wxBITMAP_TYPE_XBM);
|
||||||
virtual bool SaveFile(const wxString& name, int type, const wxPalette *cmap = NULL);
|
virtual bool SaveFile(const wxString& name, int type, const wxPalette *cmap = NULL);
|
||||||
|
|
||||||
inline bool Ok() const { return (M_BITMAPDATA && M_BITMAPDATA->m_ok); }
|
inline bool Ok() const { return (M_BITMAPDATA && M_BITMAPDATA->m_ok); }
|
||||||
@@ -188,11 +196,12 @@ public:
|
|||||||
public:
|
public:
|
||||||
inline WXDisplay* GetDisplay() const { return M_BITMAPDATA->m_display; }
|
inline WXDisplay* GetDisplay() const { return M_BITMAPDATA->m_display; }
|
||||||
inline WXDisplay* GetPixmap() const { return M_BITMAPDATA->m_pixmap; }
|
inline WXDisplay* GetPixmap() const { return M_BITMAPDATA->m_pixmap; }
|
||||||
|
virtual WXPixmap GetLabelPixmap(WXWidget w) ;
|
||||||
|
virtual WXPixmap GetArmPixmap(WXWidget w) ;
|
||||||
|
virtual WXPixmap GetInsensPixmap(WXWidget w) ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static wxList sm_handlers;
|
static wxList sm_handlers;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
// _WX_BITMAP_H_
|
// _WX_BITMAP_H_
|
||||||
|
@@ -26,7 +26,8 @@ class WXDLLEXPORT wxChoice: public wxControl
|
|||||||
DECLARE_DYNAMIC_CLASS(wxChoice)
|
DECLARE_DYNAMIC_CLASS(wxChoice)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline wxChoice() { m_noStrings = 0; }
|
wxChoice();
|
||||||
|
~wxChoice();
|
||||||
|
|
||||||
inline wxChoice(wxWindow *parent, wxWindowID id,
|
inline wxChoice(wxWindow *parent, wxWindowID id,
|
||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
@@ -61,11 +62,23 @@ class WXDLLEXPORT wxChoice: public wxControl
|
|||||||
virtual inline int Number() const { return m_noStrings; }
|
virtual inline int Number() const { return m_noStrings; }
|
||||||
virtual void Command(wxCommandEvent& event);
|
virtual void Command(wxCommandEvent& event);
|
||||||
|
|
||||||
virtual inline void SetColumns(int WXUNUSED(n) = 1 ) { /* No effect */ } ;
|
virtual void SetColumns(int n = 1 );
|
||||||
virtual inline int GetColumns() const { return 1 ; };
|
virtual int GetColumns() const ;
|
||||||
|
|
||||||
|
void SetFocus();
|
||||||
|
|
||||||
|
WXWidget GetTopWidget() const { return m_formWidget; }
|
||||||
|
WXWidget GetMainWidget() const { return m_buttonWidget; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_noStrings;
|
int m_noStrings;
|
||||||
|
WXWidget m_menuWidget;
|
||||||
|
WXWidget m_buttonWidget;
|
||||||
|
WXWidget* m_widgetList ;
|
||||||
|
WXWidget m_formWidget;
|
||||||
|
wxStringList m_stringList;
|
||||||
|
public:
|
||||||
|
bool m_inSetValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -18,6 +18,18 @@
|
|||||||
|
|
||||||
#include "wx/bitmap.h"
|
#include "wx/bitmap.h"
|
||||||
|
|
||||||
|
/* Cursor for one display, so we can choose the correct one for
|
||||||
|
* the current display.
|
||||||
|
*/
|
||||||
|
class wxXCursor : public wxObject
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxXCursor)
|
||||||
|
|
||||||
|
public:
|
||||||
|
WXDisplay* m_display;
|
||||||
|
WXCursor m_cursor;
|
||||||
|
};
|
||||||
|
|
||||||
class WXDLLEXPORT wxCursorRefData: public wxBitmapRefData
|
class WXDLLEXPORT wxCursorRefData: public wxBitmapRefData
|
||||||
{
|
{
|
||||||
friend class WXDLLEXPORT wxBitmap;
|
friend class WXDLLEXPORT wxBitmap;
|
||||||
@@ -26,10 +38,8 @@ public:
|
|||||||
wxCursorRefData();
|
wxCursorRefData();
|
||||||
~wxCursorRefData();
|
~wxCursorRefData();
|
||||||
|
|
||||||
protected:
|
wxList m_cursors; // wxXCursor objects, one per display
|
||||||
/* TODO: implementation
|
wxStockCursor m_cursorId; // wxWindows standard cursor id
|
||||||
WXHCURSOR m_hCursor;
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define M_CURSORDATA ((wxCursorRefData *)m_refData)
|
#define M_CURSORDATA ((wxCursorRefData *)m_refData)
|
||||||
@@ -50,24 +60,23 @@ public:
|
|||||||
wxCursor(const char bits[], int width, int height, int hotSpotX = -1, int hotSpotY = -1,
|
wxCursor(const char bits[], int width, int height, int hotSpotX = -1, int hotSpotY = -1,
|
||||||
const char maskBits[] = NULL);
|
const char maskBits[] = NULL);
|
||||||
|
|
||||||
/* TODO: make default type suit platform */
|
wxCursor(const wxString& name, long flags = wxBITMAP_TYPE_XBM,
|
||||||
wxCursor(const wxString& name, long flags = wxBITMAP_TYPE_CUR_RESOURCE,
|
|
||||||
int hotSpotX = 0, int hotSpotY = 0);
|
int hotSpotX = 0, int hotSpotY = 0);
|
||||||
|
|
||||||
wxCursor(int cursor_type);
|
wxCursor(wxStockCursor id);
|
||||||
~wxCursor();
|
~wxCursor();
|
||||||
|
|
||||||
// TODO: also verify the internal cursor handle
|
virtual bool Ok() const { return ((m_refData != NULL) && M_CURSORDATA->m_ok); }
|
||||||
virtual bool Ok() const { return (m_refData != NULL) ; }
|
|
||||||
|
|
||||||
inline wxCursor& operator = (const wxCursor& cursor) { if (*this == cursor) return (*this); Ref(cursor); return *this; }
|
inline wxCursor& operator = (const wxCursor& cursor) { if (*this == cursor) return (*this); Ref(cursor); return *this; }
|
||||||
inline bool operator == (const wxCursor& cursor) { return m_refData == cursor.m_refData; }
|
inline bool operator == (const wxCursor& cursor) { return m_refData == cursor.m_refData; }
|
||||||
inline bool operator != (const wxCursor& cursor) { return m_refData != cursor.m_refData; }
|
inline bool operator != (const wxCursor& cursor) { return m_refData != cursor.m_refData; }
|
||||||
|
|
||||||
/* TODO: implementation
|
// Motif-specific.
|
||||||
void SetHCURSOR(WXHCURSOR cursor);
|
// Create/get a cursor for the current display
|
||||||
inline WXHCURSOR GetHCURSOR() const { return (M_CURSORDATA ? M_CURSORDATA->m_hCursor : 0); }
|
WXCursor GetXCursor(WXDisplay* display) ;
|
||||||
*/
|
// Make a cursor from standard id
|
||||||
|
WXCursor MakeCursor(WXDisplay* display, wxStockCursor id);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WXDLLEXPORT void wxSetCursor(const wxCursor& cursor);
|
extern WXDLLEXPORT void wxSetCursor(const wxCursor& cursor);
|
||||||
|
@@ -21,6 +21,20 @@
|
|||||||
|
|
||||||
class WXDLLEXPORT wxFont;
|
class WXDLLEXPORT wxFont;
|
||||||
|
|
||||||
|
// For every wxFont, there must be a font for each display and scale requested.
|
||||||
|
// So these objects are stored in wxFontRefData::m_fonts
|
||||||
|
class WXDLLEXPORT wxXFont: public wxObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxXFont();
|
||||||
|
~wxXFont();
|
||||||
|
|
||||||
|
WXFontStructPtr m_fontStruct; // XFontStruct
|
||||||
|
WXFontList m_fontList; // Motif XmFontList
|
||||||
|
WXDisplay* m_display; // XDisplay
|
||||||
|
int m_scale; // Scale * 100
|
||||||
|
};
|
||||||
|
|
||||||
class WXDLLEXPORT wxFontRefData: public wxGDIRefData
|
class WXDLLEXPORT wxFontRefData: public wxGDIRefData
|
||||||
{
|
{
|
||||||
friend class WXDLLEXPORT wxFont;
|
friend class WXDLLEXPORT wxFont;
|
||||||
@@ -36,8 +50,8 @@ protected:
|
|||||||
bool m_underlined;
|
bool m_underlined;
|
||||||
wxString m_faceName;
|
wxString m_faceName;
|
||||||
|
|
||||||
// A list of XFontStructs indexed by scale (*100)
|
// A list of wxXFonts
|
||||||
wxList m_fontsByScale;
|
wxList m_fonts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define M_FONTDATA ((wxFontRefData *)m_refData)
|
#define M_FONTDATA ((wxFontRefData *)m_refData)
|
||||||
@@ -87,16 +101,30 @@ public:
|
|||||||
// based on this wxFont and the given scale. Append the
|
// based on this wxFont and the given scale. Append the
|
||||||
// font to list in the private data for future reference.
|
// font to list in the private data for future reference.
|
||||||
|
|
||||||
// TODO This is a very basic implementation, that doesn't
|
// TODO This is a fairly basic implementation, that doesn't
|
||||||
// allow for different facenames, and also doesn't do a mapping
|
// allow for different facenames, and also doesn't do a mapping
|
||||||
// between 'standard' facenames (e.g. Arial, Helvetica, Times Roman etc.)
|
// between 'standard' facenames (e.g. Arial, Helvetica, Times Roman etc.)
|
||||||
// and the fonts that are available on a particular system.
|
// and the fonts that are available on a particular system.
|
||||||
// Maybe we need to scan the user's machine to build up a profile
|
// Maybe we need to scan the user's machine to build up a profile
|
||||||
// of the fonts and a mapping file.
|
// of the fonts and a mapping file.
|
||||||
|
|
||||||
WXFontStructPtr FindOrCreateFontStruct(double scale = 1.0);
|
// Return font struct, and optionally the Motif font list
|
||||||
|
wxXFont* GetInternalFont(double scale = 1.0, WXDisplay* display = NULL) const;
|
||||||
|
|
||||||
|
// These two are helper functions for convenient access of the above.
|
||||||
|
inline WXFontStructPtr GetFontStruct(double scale = 1.0, WXDisplay* display = NULL) const
|
||||||
|
{
|
||||||
|
wxXFont* f = GetInternalFont(scale, display);
|
||||||
|
return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
|
||||||
|
}
|
||||||
|
WXFontList GetFontList(double scale = 1.0, WXDisplay* display = NULL) const
|
||||||
|
{
|
||||||
|
wxXFont* f = GetInternalFont(scale, display);
|
||||||
|
return (f ? f->m_fontList : (WXFontList) 0);
|
||||||
|
}
|
||||||
|
|
||||||
WXFontStructPtr LoadQueryFont(int pointSize, int family, int style,
|
WXFontStructPtr LoadQueryFont(int pointSize, int family, int style,
|
||||||
int weight, bool underlined);
|
int weight, bool underlined) const;
|
||||||
protected:
|
protected:
|
||||||
bool RealizeResource();
|
bool RealizeResource();
|
||||||
void Unshare();
|
void Unshare();
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include "wx/bitmap.h"
|
#include "wx/bitmap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Same as for wxBitmap
|
||||||
class WXDLLEXPORT wxIconRefData: public wxBitmapRefData
|
class WXDLLEXPORT wxIconRefData: public wxBitmapRefData
|
||||||
{
|
{
|
||||||
friend class WXDLLEXPORT wxBitmap;
|
friend class WXDLLEXPORT wxBitmap;
|
||||||
@@ -26,9 +28,10 @@ public:
|
|||||||
wxIconRefData();
|
wxIconRefData();
|
||||||
~wxIconRefData();
|
~wxIconRefData();
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
#define M_ICONDATA ((wxIconRefData *)m_refData)
|
#define M_ICONDATA ((wxBitmapRefData *)m_refData)
|
||||||
#define M_ICONHANDLERDATA ((wxIconRefData *)bitmap->GetRefData())
|
#define M_ICONHANDLERDATA ((wxBitmapRefData *)bitmap->GetRefData())
|
||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
class WXDLLEXPORT wxIcon: public wxBitmap
|
class WXDLLEXPORT wxIcon: public wxBitmap
|
||||||
@@ -42,7 +45,12 @@ public:
|
|||||||
inline wxIcon(const wxIcon& icon) { Ref(icon); }
|
inline wxIcon(const wxIcon& icon) { Ref(icon); }
|
||||||
inline wxIcon(const wxIcon* icon) { if (icon) Ref(*icon); }
|
inline wxIcon(const wxIcon* icon) { if (icon) Ref(*icon); }
|
||||||
|
|
||||||
|
// Initialize with XBM data
|
||||||
wxIcon(const char bits[], int width, int height);
|
wxIcon(const char bits[], int width, int height);
|
||||||
|
|
||||||
|
// Initialize with XPM data
|
||||||
|
wxIcon(const char **data);
|
||||||
|
|
||||||
wxIcon(const wxString& name, long flags = wxBITMAP_TYPE_ICO_RESOURCE,
|
wxIcon(const wxString& name, long flags = wxBITMAP_TYPE_ICO_RESOURCE,
|
||||||
int desiredWidth = -1, int desiredHeight = -1);
|
int desiredWidth = -1, int desiredHeight = -1);
|
||||||
~wxIcon();
|
~wxIcon();
|
||||||
@@ -54,44 +62,8 @@ public:
|
|||||||
inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
|
inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
|
||||||
inline bool operator != (const wxIcon& icon) { return m_refData != icon.m_refData; }
|
inline bool operator != (const wxIcon& icon) { return m_refData != icon.m_refData; }
|
||||||
|
|
||||||
/* TODO */
|
virtual bool Ok() const { return ((m_refData != NULL) && (M_ICONDATA->m_ok)); }
|
||||||
virtual bool Ok() const { return (m_refData != NULL) ; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Example handlers. TODO: write your own handlers for relevant types.
|
|
||||||
|
|
||||||
class WXDLLEXPORT wxICOFileHandler: public wxBitmapHandler
|
|
||||||
{
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
|
|
||||||
public:
|
|
||||||
inline wxICOFileHandler()
|
|
||||||
{
|
|
||||||
m_name = "ICO icon file";
|
|
||||||
m_extension = "ico";
|
|
||||||
m_type = wxBITMAP_TYPE_ICO;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
|
||||||
int desiredWidth = -1, int desiredHeight = -1);
|
|
||||||
};
|
|
||||||
|
|
||||||
class WXDLLEXPORT wxICOResourceHandler: public wxBitmapHandler
|
|
||||||
{
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
|
|
||||||
public:
|
|
||||||
inline wxICOResourceHandler()
|
|
||||||
{
|
|
||||||
m_name = "ICO resource";
|
|
||||||
m_extension = "ico";
|
|
||||||
m_type = wxBITMAP_TYPE_ICO_RESOURCE;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
|
||||||
int desiredWidth = -1, int desiredHeight = -1);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_ICON_H_
|
// _WX_ICON_H_
|
||||||
|
@@ -38,7 +38,8 @@ class WXDLLEXPORT wxListBox: public wxControl
|
|||||||
int n = 0, const wxString choices[] = NULL,
|
int n = 0, const wxString choices[] = NULL,
|
||||||
long style = 0,
|
long style = 0,
|
||||||
const wxValidator& validator = wxDefaultValidator,
|
const wxValidator& validator = wxDefaultValidator,
|
||||||
const wxString& name = wxListBoxNameStr)
|
const wxString& name = wxListBoxNameStr):
|
||||||
|
m_clientDataList(wxKEY_INTEGER)
|
||||||
{
|
{
|
||||||
Create(parent, id, pos, size, n, choices, style, validator, name);
|
Create(parent, id, pos, size, n, choices, style, validator, name);
|
||||||
}
|
}
|
||||||
@@ -88,9 +89,15 @@ class WXDLLEXPORT wxListBox: public wxControl
|
|||||||
|
|
||||||
void Command(wxCommandEvent& event);
|
void Command(wxCommandEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_noItems;
|
int m_noItems;
|
||||||
int m_selected;
|
int m_selected;
|
||||||
|
|
||||||
|
// List mapping positions->client data
|
||||||
|
wxList m_clientDataList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool m_inSetValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -17,9 +17,25 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/gdiobj.h"
|
#include "wx/gdiobj.h"
|
||||||
|
#include "wx/list.h"
|
||||||
|
|
||||||
class WXDLLEXPORT wxPalette;
|
class WXDLLEXPORT wxPalette;
|
||||||
|
|
||||||
|
// Palette for one display
|
||||||
|
class wxXPalette : public wxObject
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxXPalette)
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxXPalette();
|
||||||
|
|
||||||
|
WXDisplay* m_display;
|
||||||
|
int m_pix_array_n;
|
||||||
|
unsigned long* m_pix_array;
|
||||||
|
WXColormap m_cmap;
|
||||||
|
bool m_destroyable;
|
||||||
|
};
|
||||||
|
|
||||||
class WXDLLEXPORT wxPaletteRefData: public wxGDIRefData
|
class WXDLLEXPORT wxPaletteRefData: public wxGDIRefData
|
||||||
{
|
{
|
||||||
friend class WXDLLEXPORT wxPalette;
|
friend class WXDLLEXPORT wxPalette;
|
||||||
@@ -28,7 +44,7 @@ public:
|
|||||||
~wxPaletteRefData();
|
~wxPaletteRefData();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WXColormap m_colormap;
|
wxList m_palettes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define M_PALETTEDATA ((wxPaletteRefData *)m_refData)
|
#define M_PALETTEDATA ((wxPaletteRefData *)m_refData)
|
||||||
@@ -54,7 +70,12 @@ public:
|
|||||||
inline bool operator == (const wxPalette& palette) { return m_refData == palette.m_refData; }
|
inline bool operator == (const wxPalette& palette) { return m_refData == palette.m_refData; }
|
||||||
inline bool operator != (const wxPalette& palette) { return m_refData != palette.m_refData; }
|
inline bool operator != (const wxPalette& palette) { return m_refData != palette.m_refData; }
|
||||||
|
|
||||||
WXColormap GetXColormap() const { return (M_PALETTEDATA->m_colormap); }
|
// Motif-specific
|
||||||
|
WXColormap GetXColormap(WXDisplay* display = NULL) const;
|
||||||
|
bool TransferBitmap(void *data, int depth, int size);
|
||||||
|
bool TransferBitmap8(unsigned char *data, unsigned long size, void *dest, unsigned int bpp);
|
||||||
|
unsigned long *GetXPixArray(WXDisplay* display, int *pix_array_n);
|
||||||
|
void PutXColormap(WXDisplay* display, WXColormap cmap, bool destroyable);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
typedef unsigned int size_t;
|
typedef unsigned int size_t;
|
||||||
|
|
||||||
#if !USE_OWNER_DRAWN
|
#if !wxUSE_OWNER_DRAWN
|
||||||
#error "wxCheckListBox class requires owner-drawn functionality."
|
#error "wxCheckListBox class requires owner-drawn functionality."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !USE_DRAG_AND_DROP
|
#if !wxUSE_DRAG_AND_DROP
|
||||||
#error "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
|
#error "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
|
||||||
#endif //WX_DRAG_DROP
|
#endif //WX_DRAG_DROP
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
#pragma interface "droptgt.h"
|
#pragma interface "droptgt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !USE_DRAG_AND_DROP
|
#if !wxUSE_DRAG_AND_DROP
|
||||||
#error "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
|
#error "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
|
||||||
#endif //WX_DRAG_DROP
|
#endif //WX_DRAG_DROP
|
||||||
|
|
||||||
|
@@ -1639,7 +1639,16 @@ bool wxCommandProcessor::CanUndo(void) const
|
|||||||
|
|
||||||
bool wxCommandProcessor::CanRedo(void) const
|
bool wxCommandProcessor::CanRedo(void) const
|
||||||
{
|
{
|
||||||
return ((m_currentCommand && m_currentCommand->Next()));
|
if ((m_currentCommand != (wxNode*) NULL) && (m_currentCommand->Next() == (wxNode*) NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((m_currentCommand != (wxNode*) NULL) && (m_currentCommand->Next() != (wxNode*) NULL))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if ((m_currentCommand == (wxNode*) NULL) && (m_commands.Number() > 0))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCommandProcessor::Initialize(void)
|
void wxCommandProcessor::Initialize(void)
|
||||||
|
@@ -324,7 +324,7 @@ void wxMemStruct::PrintNode ()
|
|||||||
{
|
{
|
||||||
wxObject *obj = (wxObject *)m_actualData;
|
wxObject *obj = (wxObject *)m_actualData;
|
||||||
wxClassInfo *info = obj->GetClassInfo();
|
wxClassInfo *info = obj->GetClassInfo();
|
||||||
|
/*
|
||||||
if (info && info->GetClassName())
|
if (info && info->GetClassName())
|
||||||
wxTrace("%s", info->GetClassName());
|
wxTrace("%s", info->GetClassName());
|
||||||
else
|
else
|
||||||
@@ -333,13 +333,25 @@ void wxMemStruct::PrintNode ()
|
|||||||
if (m_fileName)
|
if (m_fileName)
|
||||||
wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
|
wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
|
||||||
|
|
||||||
|
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
||||||
|
*/
|
||||||
|
// Let's put this in standard form so IDEs can load the file at the appropriate
|
||||||
|
// line
|
||||||
|
if (m_fileName)
|
||||||
|
wxTrace("%s(%d): ", m_fileName, (int)m_lineNum);
|
||||||
|
|
||||||
|
if (info && info->GetClassName())
|
||||||
|
wxTrace("%s", info->GetClassName());
|
||||||
|
else
|
||||||
|
wxTrace("object");
|
||||||
|
|
||||||
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxTrace("Non-object data");
|
|
||||||
if (m_fileName)
|
if (m_fileName)
|
||||||
wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
|
wxTrace("%s(%d): ", m_fileName, (int)m_lineNum);
|
||||||
|
wxTrace("non-object data");
|
||||||
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,23 +363,19 @@ void wxMemStruct::Dump ()
|
|||||||
if (m_isObject)
|
if (m_isObject)
|
||||||
{
|
{
|
||||||
wxObject *obj = (wxObject *)m_actualData;
|
wxObject *obj = (wxObject *)m_actualData;
|
||||||
// wxClassInfo *info = obj->GetClassInfo();
|
|
||||||
|
|
||||||
if (m_fileName)
|
if (m_fileName)
|
||||||
wxTrace("Item (%s %d)", m_fileName, (int)m_lineNum);
|
wxTrace("%s(%d): ", m_fileName, (int)m_lineNum);
|
||||||
else
|
|
||||||
wxTrace("Item");
|
|
||||||
|
|
||||||
wxTrace(" at $%lX, size %d: ", (long)GetActualData(), (int)RequestSize());
|
|
||||||
// wxTrace(info->GetClassName());
|
|
||||||
obj->Dump(wxDebugContext::GetStream());
|
obj->Dump(wxDebugContext::GetStream());
|
||||||
|
wxTrace(" at $%lX, size %d", (long)GetActualData(), (int)RequestSize());
|
||||||
wxTrace("\n");
|
wxTrace("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxTrace("Non-object data");
|
|
||||||
if (m_fileName)
|
if (m_fileName)
|
||||||
wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
|
wxTrace("%s(%d): ", m_fileName, (int)m_lineNum);
|
||||||
|
wxTrace("non-object data");
|
||||||
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -111,7 +111,7 @@ void wxObject::operator delete (void * buf)
|
|||||||
|
|
||||||
// VC++ 6.0
|
// VC++ 6.0
|
||||||
#if _MSC_VER >= 1200
|
#if _MSC_VER >= 1200
|
||||||
void operator delete(void* pData, char* /* fileName */, int /* lineNum */)
|
void operator wxObject::delete(void* pData, char* /* fileName */, int /* lineNum */)
|
||||||
{
|
{
|
||||||
::operator delete(pData);
|
::operator delete(pData);
|
||||||
}
|
}
|
||||||
|
14
src/make.env
14
src/make.env
@@ -5,17 +5,6 @@
|
|||||||
# This file is included by all the other makefiles, thus changes
|
# This file is included by all the other makefiles, thus changes
|
||||||
# made here take effect everywhere (except where overriden).
|
# made here take effect everywhere (except where overriden).
|
||||||
#
|
#
|
||||||
# An alternative to editing this file is to create a shell script
|
|
||||||
# to export specific variables, and call make with the -e switch
|
|
||||||
# to override makefile variables. See wx/install/install.txt.
|
|
||||||
# And you can override specific variables on the make command line, e.g.
|
|
||||||
#
|
|
||||||
# make -f makefile.unix DEBUG=''
|
|
||||||
#
|
|
||||||
# You may prefer to use the GNU configure script than raw makefiles -
|
|
||||||
# see contrib/wxshlib.
|
|
||||||
#
|
|
||||||
|
|
||||||
########################### Programs #################################
|
########################### Programs #################################
|
||||||
|
|
||||||
# Replace this with your own path if necessary
|
# Replace this with your own path if necessary
|
||||||
@@ -110,6 +99,9 @@ stubs:
|
|||||||
motif:
|
motif:
|
||||||
make -f makefile.unx all GUI='-D__WXMOTIF__ -D__LINUX__ -D__UNIX__' GUISUFFIX='_motif' GUILDLIBS='-lwx_motif $(COMPLIBS) -lXm -lXmu -lXt -lX11 -lm'
|
make -f makefile.unx all GUI='-D__WXMOTIF__ -D__LINUX__ -D__UNIX__' GUISUFFIX='_motif' GUILDLIBS='-lwx_motif $(COMPLIBS) -lXm -lXmu -lXt -lX11 -lm'
|
||||||
|
|
||||||
|
gtk:
|
||||||
|
make -f makefile.unx all GUI='-D__WXGTK__ -D__LINUX__ -D__UNIX__' GUISUFFIX='_gtk' GUILDLIBS='-lwx_gtk $(COMPLIBS) -lXm -lXmu -lX11 -lm'
|
||||||
|
|
||||||
cleanstubs:
|
cleanstubs:
|
||||||
make -f makefile.unx clean GUI='-D__WXSTUBS__ -D__LINUX__ -D__UNIX__' GUISUFFIX='_stubs' GUILDLIBS='-lwx_stubs $(COMPLIBS) -lXm -lXmu -lXt -lX11 -lm'
|
make -f makefile.unx clean GUI='-D__WXSTUBS__ -D__LINUX__ -D__UNIX__' GUISUFFIX='_stubs' GUILDLIBS='-lwx_stubs $(COMPLIBS) -lXm -lXmu -lXt -lX11 -lm'
|
||||||
|
|
||||||
|
@@ -296,6 +296,8 @@ int wxApp::MainLoop()
|
|||||||
report = event;
|
report = event;
|
||||||
while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
|
while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
|
||||||
}
|
}
|
||||||
|
// TODO: when implementing refresh optimization, we can use
|
||||||
|
// XtAddExposureToRegion to expand the window's paint region.
|
||||||
|
|
||||||
XtDispatchEvent(&event);
|
XtDispatchEvent(&event);
|
||||||
|
|
||||||
|
@@ -20,6 +20,15 @@
|
|||||||
#include "wx/icon.h"
|
#include "wx/icon.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
|
// TODO: correct symbol, path?
|
||||||
|
#if USE_XPM
|
||||||
|
#include <X11/xpm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARIES
|
#if !USE_SHARED_LIBRARIES
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
|
||||||
@@ -37,13 +46,54 @@ wxBitmapRefData::wxBitmapRefData()
|
|||||||
|
|
||||||
m_pixmap = (WXPixmap) 0;
|
m_pixmap = (WXPixmap) 0;
|
||||||
m_display = (WXDisplay*) 0;
|
m_display = (WXDisplay*) 0;
|
||||||
|
|
||||||
|
m_freePixmap = TRUE; //TODO: necessary?
|
||||||
|
m_freeColors = (unsigned long*) 0;
|
||||||
|
m_freeColorsCount = 0;
|
||||||
|
|
||||||
|
// These 5 variables are for wxControl
|
||||||
|
m_insensPixmap = (WXPixmap) 0;
|
||||||
|
m_labelPixmap = (WXPixmap) 0;
|
||||||
|
m_armPixmap = (WXPixmap) 0;
|
||||||
|
m_image = (WXImage*) 0;
|
||||||
|
m_insensImage = (WXImage*) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmapRefData::~wxBitmapRefData()
|
wxBitmapRefData::~wxBitmapRefData()
|
||||||
{
|
{
|
||||||
/*
|
if (m_labelPixmap)
|
||||||
* TODO: delete the bitmap data here.
|
XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_labelPixmap);
|
||||||
*/
|
|
||||||
|
if (m_armPixmap)
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_armPixmap);
|
||||||
|
|
||||||
|
if (m_insensPixmap)
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_insensPixmap);
|
||||||
|
|
||||||
|
if (m_image)
|
||||||
|
{
|
||||||
|
XmUninstallImage ((XImage*) m_image);
|
||||||
|
XtFree ((char *) (XImage*) m_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_insensImage)
|
||||||
|
{
|
||||||
|
XmUninstallImage ((XImage*) m_insensImage);
|
||||||
|
delete[] ((XImage*) m_insensImage)->data;
|
||||||
|
XtFree ((char *) (XImage*) m_insensImage);
|
||||||
|
}
|
||||||
|
if (m_pixmap && m_freePixmap)
|
||||||
|
XFreePixmap ((Display*) m_display, (Pixmap) m_pixmap);
|
||||||
|
|
||||||
|
if (m_freeColors)
|
||||||
|
{
|
||||||
|
int screen = DefaultScreen((Display*) m_display);
|
||||||
|
Colormap cmp = DefaultColormap((Display*) m_display,screen);
|
||||||
|
long llp;
|
||||||
|
for(llp = 0;llp < m_freeColorsCount;llp++)
|
||||||
|
XFreeColors((Display*) m_display, cmp, &m_freeColors[llp], 1, 0L);
|
||||||
|
delete m_freeColors;
|
||||||
|
};
|
||||||
|
|
||||||
if (m_bitmapMask)
|
if (m_bitmapMask)
|
||||||
delete m_bitmapMask;
|
delete m_bitmapMask;
|
||||||
@@ -66,16 +116,11 @@ wxBitmap::~wxBitmap()
|
|||||||
wxTheBitmapList->DeleteObject(this);
|
wxTheBitmapList->DeleteObject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
|
wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
|
||||||
{
|
{
|
||||||
m_refData = new wxBitmapRefData;
|
m_refData = new wxBitmapRefData;
|
||||||
|
|
||||||
M_BITMAPDATA->m_width = the_width ;
|
(void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, depth);
|
||||||
M_BITMAPDATA->m_height = the_height ;
|
|
||||||
M_BITMAPDATA->m_depth = no_bits ;
|
|
||||||
M_BITMAPDATA->m_numColors = 0;
|
|
||||||
|
|
||||||
/* TODO: create the bitmap from data */
|
|
||||||
|
|
||||||
if ( wxTheBitmapList )
|
if ( wxTheBitmapList )
|
||||||
wxTheBitmapList->AddBitmap(this);
|
wxTheBitmapList->AddBitmap(this);
|
||||||
@@ -105,13 +150,17 @@ wxBitmap::wxBitmap(const wxString& filename, long type)
|
|||||||
wxTheBitmapList->AddBitmap(this);
|
wxTheBitmapList->AddBitmap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: maybe allow creation from XPM
|
// Create from XPM data
|
||||||
// Create from data
|
static wxControl* sg_Control = NULL;
|
||||||
wxBitmap::wxBitmap(const char **data)
|
wxBitmap::wxBitmap(const char **data, wxControl* control)
|
||||||
{
|
{
|
||||||
|
// Pass the control to the Create function using a global
|
||||||
|
sg_Control = control;
|
||||||
|
|
||||||
(void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
|
(void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
|
||||||
|
|
||||||
|
sg_Control = (wxControl*) NULL;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
bool wxBitmap::Create(int w, int h, int d)
|
bool wxBitmap::Create(int w, int h, int d)
|
||||||
{
|
{
|
||||||
@@ -119,12 +168,22 @@ bool wxBitmap::Create(int w, int h, int d)
|
|||||||
|
|
||||||
m_refData = new wxBitmapRefData;
|
m_refData = new wxBitmapRefData;
|
||||||
|
|
||||||
|
if (d < 1)
|
||||||
|
d = wxDisplayDepth();
|
||||||
|
|
||||||
M_BITMAPDATA->m_width = w;
|
M_BITMAPDATA->m_width = w;
|
||||||
M_BITMAPDATA->m_height = h;
|
M_BITMAPDATA->m_height = h;
|
||||||
M_BITMAPDATA->m_depth = d;
|
M_BITMAPDATA->m_depth = d;
|
||||||
|
M_BITMAPDATA->m_freePixmap = TRUE;
|
||||||
|
|
||||||
/* TODO: create new bitmap */
|
Display *dpy = (Display*) wxGetDisplay();
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_display = dpy; /* MATTHEW: [4] Remember the display */
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_pixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
|
||||||
|
w, h, d);
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_pixmap != (WXPixmap) 0) ;
|
||||||
return M_BITMAPDATA->m_ok;
|
return M_BITMAPDATA->m_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +389,9 @@ wxMask::wxMask(const wxBitmap& bitmap)
|
|||||||
|
|
||||||
wxMask::~wxMask()
|
wxMask::~wxMask()
|
||||||
{
|
{
|
||||||
// TODO: delete mask bitmap
|
// TODO: this may be the wrong display
|
||||||
|
if ( m_pixmap )
|
||||||
|
XFreePixmap ((Display*) wxGetDisplay(), (Pixmap) m_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a mask from a mono bitmap (copies the bitmap).
|
// Create a mask from a mono bitmap (copies the bitmap).
|
||||||
@@ -382,23 +443,301 @@ bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type,
|
|||||||
* Standard handlers
|
* Standard handlers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: bitmap handlers, a bit like this:
|
class WXDLLEXPORT wxXBMFileHandler: public wxBitmapHandler
|
||||||
class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
|
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
|
DECLARE_DYNAMIC_CLASS(wxXBMFileHandler)
|
||||||
public:
|
public:
|
||||||
inline wxBMPResourceHandler()
|
inline wxXBMFileHandler()
|
||||||
{
|
{
|
||||||
m_name = "Windows bitmap resource";
|
m_name = "XBM file";
|
||||||
m_extension = "";
|
m_extension = "xbm";
|
||||||
m_type = wxBITMAP_TYPE_BMP_RESOURCE;
|
m_type = wxBITMAP_TYPE_XBM;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
||||||
int desiredWidth, int desiredHeight);
|
int desiredWidth, int desiredHeight);
|
||||||
};
|
};
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
|
||||||
*/
|
|
||||||
|
bool wxXBMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
||||||
|
int desiredWidth, int desiredHeight)
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
|
||||||
|
|
||||||
|
int hotX, hotY;
|
||||||
|
unsigned int w, h;
|
||||||
|
Pixmap pixmap;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) wxGetDisplay();
|
||||||
|
M_BITMAPDATA->m_display = (WXDisplay*) dpy;
|
||||||
|
|
||||||
|
int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
|
||||||
|
(char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
|
||||||
|
M_BITMAPHANDLERDATA->m_width = w;
|
||||||
|
M_BITMAPHANDLERDATA->m_height = h;
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 1;
|
||||||
|
M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
|
||||||
|
|
||||||
|
if ((value == BitmapFileInvalid) ||
|
||||||
|
(value == BitmapOpenFailed) ||
|
||||||
|
(value == BitmapNoMemory))
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = FALSE;
|
||||||
|
M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = TRUE;
|
||||||
|
|
||||||
|
return M_BITMAPHANDLERDATA->m_ok ;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
|
||||||
|
public:
|
||||||
|
inline wxXBMDataHandler()
|
||||||
|
{
|
||||||
|
m_name = "XBM data";
|
||||||
|
m_extension = "xbm";
|
||||||
|
m_type = wxBITMAP_TYPE_XBM_DATA;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
|
||||||
|
};
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
|
||||||
|
|
||||||
|
bool wxXBMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_width = width;
|
||||||
|
M_BITMAPHANDLERDATA->m_height = height;
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 1;
|
||||||
|
M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) wxGetDisplay();
|
||||||
|
M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) XCreateBitmapFromData (dpy, RootWindow (dpy, DefaultScreen (dpy)), (char*) data, width, height);
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = (M_BITMAPHANDLERDATA->m_pixmap != (WXPixmap) 0) ;
|
||||||
|
|
||||||
|
// code for wxControl. TODO: can we avoid doing this until we need it?
|
||||||
|
// E.g. have CreateButtonPixmaps which is called on demand.
|
||||||
|
XImage* image = (XImage *) XtMalloc (sizeof (XImage));
|
||||||
|
image->width = width;
|
||||||
|
image->height = height;
|
||||||
|
image->data = (char*) data;
|
||||||
|
image->depth = 1;
|
||||||
|
image->xoffset = 0;
|
||||||
|
image->format = XYBitmap;
|
||||||
|
image->byte_order = LSBFirst;
|
||||||
|
image->bitmap_unit = 8;
|
||||||
|
image->bitmap_bit_order = LSBFirst;
|
||||||
|
image->bitmap_pad = 8;
|
||||||
|
image->bytes_per_line = (width + 7) >> 3;
|
||||||
|
|
||||||
|
char tmp[128];
|
||||||
|
sprintf (tmp, "Im%x", (unsigned int) image);
|
||||||
|
XmInstallImage (image, tmp);
|
||||||
|
|
||||||
|
// Build our manually stipped pixmap.
|
||||||
|
|
||||||
|
int bpl = (width + 7) / 8;
|
||||||
|
char *data1 = new char[height * bpl];
|
||||||
|
char* bits = (char*) data;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
int mask = i % 2 ? 0x55 : 0xaa;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < bpl; j++)
|
||||||
|
data1[i * bpl + j] = bits[i * bpl + j] & mask;
|
||||||
|
}
|
||||||
|
XImage* insensImage = (XImage *) XtMalloc (sizeof (XImage));
|
||||||
|
insensImage->width = width;
|
||||||
|
insensImage->height = height;
|
||||||
|
insensImage->data = data1;
|
||||||
|
insensImage->depth = 1;
|
||||||
|
insensImage->xoffset = 0;
|
||||||
|
insensImage->format = XYBitmap;
|
||||||
|
insensImage->byte_order = LSBFirst;
|
||||||
|
insensImage->bitmap_unit = 8;
|
||||||
|
insensImage->bitmap_bit_order = LSBFirst;
|
||||||
|
insensImage->bitmap_pad = 8;
|
||||||
|
insensImage->bytes_per_line = bpl;
|
||||||
|
|
||||||
|
sprintf (tmp, "Not%x", (unsigned int)insensImage);
|
||||||
|
XmInstallImage (insensImage, tmp);
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_image = (WXImage*) image;
|
||||||
|
M_BITMAPHANDLERDATA->m_insensImage = (WXImage*) insensImage;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_XPM
|
||||||
|
class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
|
||||||
|
public:
|
||||||
|
inline wxXPMFileHandler()
|
||||||
|
{
|
||||||
|
m_name = "XPM file";
|
||||||
|
m_extension = "xpm";
|
||||||
|
m_type = wxBITMAP_TYPE_XPM;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
||||||
|
int desiredWidth, int desiredHeight);
|
||||||
|
virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
|
||||||
|
|
||||||
|
bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
|
||||||
|
int desiredWidth, int desiredHeight)
|
||||||
|
{
|
||||||
|
Display *dpy = wxGetDisplay();
|
||||||
|
M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
|
||||||
|
|
||||||
|
XpmAttributes xpmAttr;
|
||||||
|
Pixmap pixmap;
|
||||||
|
Pixmap mask = 0;
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = FALSE;
|
||||||
|
xpmAttr.valuemask = XpmReturnInfos | XpmCloseness;
|
||||||
|
xpmAttr.closeness = 40000;
|
||||||
|
int errorStatus = XpmReadFileToPixmap(dpy,
|
||||||
|
RootWindow(dpy, DefaultScreen(dpy)), (char*) (const char*) name,
|
||||||
|
&pixmap, &mask, &xpmAttr);
|
||||||
|
|
||||||
|
if (errorStatus == XpmSuccess)
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
|
||||||
|
if ( mask )
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
|
||||||
|
M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
|
||||||
|
M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
|
||||||
|
if ( xpmAttr.npixels > 2 )
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 1; // mono
|
||||||
|
}
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
|
||||||
|
|
||||||
|
XpmFreeAttributes(&xpmAttr);
|
||||||
|
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = TRUE;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// XpmDebugError(errorStatus, name);
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = FALSE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
|
||||||
|
{
|
||||||
|
if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
|
||||||
|
{
|
||||||
|
Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
|
||||||
|
int errorStatus = XpmWriteFileFromPixmap(dpy, (char*) (const char*) name,
|
||||||
|
(Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
|
||||||
|
(M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
|
||||||
|
(XpmAttributes *) NULL);
|
||||||
|
if (errorStatus == XpmSuccess)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
|
||||||
|
public:
|
||||||
|
inline wxXBMDataHandler()
|
||||||
|
{
|
||||||
|
m_name = "XPM data";
|
||||||
|
m_extension = "xpm";
|
||||||
|
m_type = wxBITMAP_TYPE_XPM_DATA;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
|
||||||
|
};
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
|
||||||
|
|
||||||
|
bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_width = width;
|
||||||
|
M_BITMAPHANDLERDATA->m_height = height;
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 1;
|
||||||
|
M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
|
||||||
|
|
||||||
|
Display *dpy = wxGetDisplay();
|
||||||
|
M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
|
||||||
|
|
||||||
|
XpmAttributes xpmAttr;
|
||||||
|
|
||||||
|
xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
|
||||||
|
|
||||||
|
XpmColorSymbol symbolicColors[4];
|
||||||
|
if (sg_Control && sg_Control->GetMainWidget())
|
||||||
|
{
|
||||||
|
symbolicColors[0].name = "foreground";
|
||||||
|
symbolicColors[0].value = NULL;
|
||||||
|
symbolicColors[1].name = "background";
|
||||||
|
symbolicColors[1].value = NULL;
|
||||||
|
XtVaGetValues((Widget) sg_Control->GetMainWidget(),
|
||||||
|
XmNforeground, &symbolicColors[0].pixel,
|
||||||
|
XmNbackground, &symbolicColors[1].pixel,NULL);
|
||||||
|
xpmAttr.numsymbols = 2;
|
||||||
|
xpmAttr.colorsymbols = symbolicColors;
|
||||||
|
xpmAttr.valuemask |= XpmColorSymbols; // add flag
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixmap pixmap;
|
||||||
|
Pixmap mask = 0;
|
||||||
|
int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
|
||||||
|
(char**) data, &pixmap, &mask, &xpmAttr);
|
||||||
|
if (ErrorStatus == XpmSuccess)
|
||||||
|
{
|
||||||
|
// Set attributes
|
||||||
|
M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
|
||||||
|
M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
|
||||||
|
if ( xpmAttr.npixels > 2 )
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_depth = 1; // mono
|
||||||
|
}
|
||||||
|
M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
|
||||||
|
XpmFreeAttributes(&xpmAttr);
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = TRUE;
|
||||||
|
M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
|
||||||
|
if ( mask )
|
||||||
|
{
|
||||||
|
M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
|
||||||
|
M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// XpmDebugError(ErrorStatus, NULL);
|
||||||
|
M_BITMAPHANDLERDATA->m_ok = FALSE;
|
||||||
|
}
|
||||||
|
return M_BITMAPHANDLERDATA->m_ok ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void wxBitmap::CleanUpHandlers()
|
void wxBitmap::CleanUpHandlers()
|
||||||
{
|
{
|
||||||
@@ -415,12 +754,213 @@ void wxBitmap::CleanUpHandlers()
|
|||||||
|
|
||||||
void wxBitmap::InitStandardHandlers()
|
void wxBitmap::InitStandardHandlers()
|
||||||
{
|
{
|
||||||
/* TODO: initialize all standard bitmap or derive class handlers here.
|
// Initialize all standard bitmap or derived class handlers here.
|
||||||
AddHandler(new wxBMPResourceHandler);
|
AddHandler(new wxXBMFileHandler);
|
||||||
AddHandler(new wxBMPFileHandler);
|
AddHandler(new wxXBMDataHandler);
|
||||||
|
|
||||||
|
// XPM is considered standard for Moif, although it can be omitted if absolutely
|
||||||
|
// necessary.
|
||||||
|
#if USE_XPM
|
||||||
AddHandler(new wxXPMFileHandler);
|
AddHandler(new wxXPMFileHandler);
|
||||||
AddHandler(new wxXPMDataHandler);
|
AddHandler(new wxXPMDataHandler);
|
||||||
AddHandler(new wxICOResourceHandler);
|
#endif
|
||||||
AddHandler(new wxICOFileHandler);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXPixmap wxBitmap::GetLabelPixmap (WXWidget w)
|
||||||
|
{
|
||||||
|
if (M_BITMAPDATA->m_image == (WXPixmap) 0)
|
||||||
|
return M_BITMAPDATA->m_pixmap;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) M_BITMAPDATA->m_display;
|
||||||
|
|
||||||
|
#ifdef FOO
|
||||||
|
/*
|
||||||
|
If we do:
|
||||||
|
if (labelPixmap) return labelPixmap;
|
||||||
|
things can be wrong, because colors can have been changed.
|
||||||
|
|
||||||
|
If we do:
|
||||||
|
if (labelPixmap)
|
||||||
|
XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
|
||||||
|
we got BadDrawable if the pixmap is referenced by multiples widgets
|
||||||
|
|
||||||
|
this is a catch22!!
|
||||||
|
|
||||||
|
So, before doing thing really clean, I just do nothing; if the pixmap is
|
||||||
|
referenced by many widgets, Motif performs caching functions.
|
||||||
|
And if pixmap is referenced with multiples colors, we just have some
|
||||||
|
memory leaks... I hope we can deal with them...
|
||||||
|
*/
|
||||||
|
// Must be destroyed, because colours can have been changed!
|
||||||
|
if (M_BITMAPDATA->m_labelPixmap)
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_labelPixmap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char tmp[128];
|
||||||
|
sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
|
||||||
|
|
||||||
|
Pixel fg, bg;
|
||||||
|
Widget widget = (Widget) w;
|
||||||
|
|
||||||
|
while (XmIsGadget ( widget ))
|
||||||
|
widget = XtParent (widget);
|
||||||
|
XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_labelPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
|
||||||
|
|
||||||
|
return M_BITMAPDATA->m_labelPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
WXPixmap wxBitmap::GetArmPixmap (WXWidget w)
|
||||||
|
{
|
||||||
|
if (M_BITMAPDATA->m_image == (WXPixmap) 0)
|
||||||
|
return M_BITMAPDATA->m_pixmap;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) M_BITMAPDATA->m_display;
|
||||||
|
#ifdef FOO
|
||||||
|
See GetLabelPixmap () comment
|
||||||
|
// Must be destroyed, because colours can have been changed!
|
||||||
|
if (M_BITMAPDATA->m_armPixmap)
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_armPixmap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char tmp[128];
|
||||||
|
sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
|
||||||
|
|
||||||
|
Pixel fg, bg;
|
||||||
|
Widget widget = (Widget) w;
|
||||||
|
|
||||||
|
XtVaGetValues (widget, XmNarmColor, &bg, NULL);
|
||||||
|
while (XmIsGadget (widget))
|
||||||
|
widget = XtParent (widget);
|
||||||
|
XtVaGetValues (widget, XmNforeground, &fg, NULL);
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_armPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
|
||||||
|
|
||||||
|
return M_BITMAPDATA->m_armPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
WXPixmap wxBitmap::GetInsensPixmap (WXWidget w)
|
||||||
|
{
|
||||||
|
Display *dpy = (Display*) M_BITMAPDATA->m_display;
|
||||||
|
|
||||||
|
if (M_BITMAPDATA->m_insensImage == (WXPixmap) 0)
|
||||||
|
return M_BITMAPDATA->m_pixmap;
|
||||||
|
|
||||||
|
#ifdef FOO
|
||||||
|
See GetLabelPixmap () comment
|
||||||
|
// Must be destroyed, because colours can have been changed!
|
||||||
|
if (M_BITMAPDATA->m_insensPixmap)
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay (dpy), (Pixmap) M_BITMAPDATA->m_insensPixmap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char tmp[128];
|
||||||
|
sprintf (tmp, "Not%x", (unsigned int) M_BITMAPDATA->m_insensImage);
|
||||||
|
|
||||||
|
Pixel fg, bg;
|
||||||
|
Widget widget = (Widget) w;
|
||||||
|
|
||||||
|
while (XmIsGadget (widget))
|
||||||
|
widget = XtParent (widget);
|
||||||
|
XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_insensPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
|
||||||
|
|
||||||
|
return M_BITMAPDATA->m_insensPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We may need this sometime...
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
NAME
|
||||||
|
XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function creates a grayed-out copy of the argument pixmap, suitable
|
||||||
|
for use as a XmLabel's XmNlabelInsensitivePixmap resource.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
The return value is the new Pixmap id or zero on error. Errors include
|
||||||
|
a NULL display argument or an invalid Pixmap argument.
|
||||||
|
|
||||||
|
ERRORS
|
||||||
|
If one of the XLib functions fail, it will produce a X error. The
|
||||||
|
default X error handler prints a diagnostic and calls exit().
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
|
||||||
|
XFillRectangle(3), exit(2)
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
John R Veregge - john@puente.jpl.nasa.gov
|
||||||
|
Advanced Engineering and Prototyping Group (AEG)
|
||||||
|
Information Systems Technology Section (395)
|
||||||
|
Jet Propulsion Lab - Calif Institute of Technology
|
||||||
|
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Pixmap
|
||||||
|
XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
|
||||||
|
|
||||||
|
{
|
||||||
|
static
|
||||||
|
char stipple_data[] =
|
||||||
|
{
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
||||||
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
|
||||||
|
};
|
||||||
|
GC gc;
|
||||||
|
Pixmap ipixmap, stipple;
|
||||||
|
unsigned width, height, depth;
|
||||||
|
|
||||||
|
Window window; /* These return values */
|
||||||
|
unsigned border; /* from XGetGeometry() */
|
||||||
|
int x, y; /* are not needed. */
|
||||||
|
|
||||||
|
ipixmap = 0;
|
||||||
|
|
||||||
|
if ( NULL == display || 0 == pixmap )
|
||||||
|
return ipixmap;
|
||||||
|
|
||||||
|
if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
|
||||||
|
&width, &height, &border, &depth )
|
||||||
|
)
|
||||||
|
return ipixmap; /* BadDrawable: probably an invalid pixmap */
|
||||||
|
|
||||||
|
/* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
|
||||||
|
*/
|
||||||
|
stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
|
||||||
|
if ( 0 != stipple )
|
||||||
|
{
|
||||||
|
gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
|
||||||
|
if ( NULL != gc )
|
||||||
|
{
|
||||||
|
/* Create an identical copy of the argument pixmap.
|
||||||
|
*/
|
||||||
|
ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
|
||||||
|
if ( 0 != ipixmap )
|
||||||
|
{
|
||||||
|
/* Copy the argument pixmap into the new pixmap.
|
||||||
|
*/
|
||||||
|
XCopyArea( display, pixmap, ipixmap,
|
||||||
|
gc, 0, 0, width, height, 0, 0 );
|
||||||
|
|
||||||
|
/* Refill the new pixmap using the stipple algorithm/pixmap.
|
||||||
|
*/
|
||||||
|
XSetStipple( display, gc, stipple );
|
||||||
|
XSetFillStyle( display, gc, FillStippled );
|
||||||
|
XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
|
||||||
|
}
|
||||||
|
XFreeGC( display, gc );
|
||||||
|
}
|
||||||
|
XFreePixmap( display, stipple );
|
||||||
|
}
|
||||||
|
return ipixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -15,11 +15,32 @@
|
|||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
#include "wx/choice.h"
|
#include "wx/choice.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <Xm/PushBG.h>
|
||||||
|
#include <Xm/PushB.h>
|
||||||
|
#include <Xm/RowColumn.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void wxChoiceCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr);
|
||||||
|
|
||||||
|
wxChoice::wxChoice()
|
||||||
|
{
|
||||||
|
m_noStrings = 0;
|
||||||
|
m_buttonWidget = (WXWidget) 0;
|
||||||
|
m_menuWidget = (WXWidget) 0;
|
||||||
|
m_widgetList = (WXWidget*) 0;
|
||||||
|
m_formWidget = (WXWidget) 0;
|
||||||
|
m_inSetValue = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxChoice::Create(wxWindow *parent, wxWindowID id,
|
bool wxChoice::Create(wxWindow *parent, wxWindowID id,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
const wxSize& size,
|
const wxSize& size,
|
||||||
@@ -32,62 +53,320 @@ bool wxChoice::Create(wxWindow *parent, wxWindowID id,
|
|||||||
SetValidator(validator);
|
SetValidator(validator);
|
||||||
m_noStrings = n;
|
m_noStrings = n;
|
||||||
m_windowStyle = style;
|
m_windowStyle = style;
|
||||||
|
m_buttonWidget = (WXWidget) 0;
|
||||||
|
m_menuWidget = (WXWidget) 0;
|
||||||
|
m_widgetList = (WXWidget*) 0;
|
||||||
|
m_formWidget = (WXWidget) 0;
|
||||||
|
m_inSetValue = FALSE;
|
||||||
|
|
||||||
if (parent) parent->AddChild(this);
|
if (parent) parent->AddChild(this);
|
||||||
|
|
||||||
if ( id == -1 )
|
if ( id == -1 )
|
||||||
m_windowId = (int)NewControlId();
|
m_windowId = (int)NewControlId();
|
||||||
else
|
else
|
||||||
m_windowId = id;
|
m_windowId = id;
|
||||||
|
|
||||||
// TODO: create choice control
|
Widget parentWidget = (Widget) parent->GetClientWidget();
|
||||||
return FALSE;
|
|
||||||
|
m_formWidget = (WXWidget) XtVaCreateManagedWidget ((char*) (const char*) name,
|
||||||
|
xmRowColumnWidgetClass, parentWidget,
|
||||||
|
XmNmarginHeight, 0,
|
||||||
|
XmNmarginWidth, 0,
|
||||||
|
XmNpacking, XmPACK_TIGHT,
|
||||||
|
XmNorientation, XmHORIZONTAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_formWidget, XmNspacing, 0, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the popup menu
|
||||||
|
*/
|
||||||
|
m_menuWidget = (WXWidget) XmCreatePulldownMenu ((Widget) m_formWidget, "choiceMenu", NULL, 0);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
Append (choices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create button
|
||||||
|
*/
|
||||||
|
Arg args[10];
|
||||||
|
Cardinal argcnt = 0;
|
||||||
|
|
||||||
|
XtSetArg (args[argcnt], XmNsubMenuId, (Widget) m_menuWidget);
|
||||||
|
argcnt++;
|
||||||
|
XtSetArg (args[argcnt], XmNmarginWidth, 0);
|
||||||
|
argcnt++;
|
||||||
|
XtSetArg (args[argcnt], XmNmarginHeight, 0);
|
||||||
|
argcnt++;
|
||||||
|
XtSetArg (args[argcnt], XmNpacking, XmPACK_TIGHT);
|
||||||
|
argcnt++;
|
||||||
|
m_buttonWidget = (WXWidget) XmCreateOptionMenu ((Widget) m_formWidget, "choiceButton", args, argcnt);
|
||||||
|
|
||||||
|
m_mainWidget = m_buttonWidget;
|
||||||
|
|
||||||
|
XtManageChild ((Widget) m_buttonWidget);
|
||||||
|
|
||||||
|
// New code from Roland Haenel (roland_haenel@ac.cybercity.de)
|
||||||
|
// Some time ago, I reported a problem with wxChoice-items under
|
||||||
|
// Linux and Motif 2.0 (they caused sporadic GPFs). Now it seems
|
||||||
|
// that I have found the code responsible for this behaviour.
|
||||||
|
#if XmVersion >= 1002
|
||||||
|
#if XmVersion < 2000
|
||||||
|
Widget optionLabel = XmOptionLabelGadget ((Widget) m_buttonWidget);
|
||||||
|
XtUnmanageChild (optionLabel);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_NONE, NULL);
|
||||||
|
|
||||||
|
AttachWidget (parent, m_buttonWidget, m_formWidget, pos.x, pos.y, size.x, size.y);
|
||||||
|
|
||||||
|
SetFont(* parent->GetFont());
|
||||||
|
ChangeColour(m_mainWidget);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxChoice::~wxChoice()
|
||||||
|
{
|
||||||
|
// For some reason destroying the menuWidget
|
||||||
|
// can cause crashes on some machines. It will
|
||||||
|
// be deleted implicitly by deleting the parent form
|
||||||
|
// anyway.
|
||||||
|
// XtDestroyWidget (menuWidget);
|
||||||
|
if (m_widgetList)
|
||||||
|
delete[] m_widgetList;
|
||||||
|
|
||||||
|
DetachWidget(GetMainWidget()); // Removes event handlers
|
||||||
|
|
||||||
|
XtDestroyWidget((Widget) m_formWidget);
|
||||||
|
m_formWidget = (WXWidget) 0;
|
||||||
|
|
||||||
|
// Presumably the other widgets have been deleted now, via the form
|
||||||
|
m_mainWidget = (WXWidget) 0;
|
||||||
|
m_buttonWidget = (WXWidget) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::Append(const wxString& item)
|
void wxChoice::Append(const wxString& item)
|
||||||
{
|
{
|
||||||
// TODO
|
wxStripMenuCodes ((char *)(const char *)item, wxBuffer);
|
||||||
m_noStrings ++;
|
Widget w = XtVaCreateManagedWidget (wxBuffer,
|
||||||
|
#if USE_GADGETS
|
||||||
|
xmPushButtonGadgetClass, (Widget) m_menuWidget,
|
||||||
|
#else
|
||||||
|
xmPushButtonWidgetClass, (Widget) m_menuWidget,
|
||||||
|
#endif
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (m_windowFont.Ok())
|
||||||
|
XtVaSetValues (w,
|
||||||
|
XmNfontList, (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay((Widget) m_formWidget)),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
WXWidget *new_widgetList = new WXWidget[m_noStrings + 1];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_noStrings; i++)
|
||||||
|
new_widgetList[i] = m_widgetList[i];
|
||||||
|
new_widgetList[m_noStrings] = (WXWidget) w;
|
||||||
|
if (m_widgetList)
|
||||||
|
delete[] m_widgetList;
|
||||||
|
m_widgetList = new_widgetList;
|
||||||
|
|
||||||
|
char mnem = wxFindMnemonic ((char*) (const char*) item);
|
||||||
|
if (mnem != 0)
|
||||||
|
XtVaSetValues (w, XmNmnemonic, mnem, NULL);
|
||||||
|
|
||||||
|
XtAddCallback (w, XmNactivateCallback, (XtCallbackProc) wxChoiceCallback, (XtPointer) this);
|
||||||
|
|
||||||
|
if (m_noStrings == 0 && m_buttonWidget)
|
||||||
|
{
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, w, NULL);
|
||||||
|
Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget);
|
||||||
|
XmString text = XmStringCreateSimple ((char*) (const char*) item);
|
||||||
|
XtVaSetValues (label,
|
||||||
|
XmNlabelString, text,
|
||||||
|
NULL);
|
||||||
|
XmStringFree (text);
|
||||||
|
}
|
||||||
|
wxNode *node = m_stringList.Add (item);
|
||||||
|
XtVaSetValues (w, XmNuserData, node->Data (), NULL);
|
||||||
|
|
||||||
|
m_noStrings ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::Delete(int n)
|
void wxChoice::Delete(int n)
|
||||||
{
|
{
|
||||||
|
wxFAIL_MSG( "Sorry, wxChoice::Delete isn't implemented yet. Maybe you'd like to volunteer? :-)" );
|
||||||
|
|
||||||
|
// What should we do -- remove the callback for this button widget,
|
||||||
|
// delete the m_stringList entry, delete the button widget, construct a new widget list
|
||||||
|
// (see Append)
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
m_noStrings --;
|
m_noStrings --;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::Clear()
|
void wxChoice::Clear()
|
||||||
{
|
{
|
||||||
// TODO
|
m_stringList.Clear ();
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_noStrings; i++)
|
||||||
|
{
|
||||||
|
XtUnmanageChild ((Widget) m_widgetList[i]);
|
||||||
|
XtDestroyWidget ((Widget) m_widgetList[i]);
|
||||||
|
}
|
||||||
|
if (m_noStrings)
|
||||||
|
delete[] m_widgetList;
|
||||||
|
m_widgetList = (WXWidget*) NULL;
|
||||||
|
if (m_buttonWidget)
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNmenuHistory, (Widget) NULL, NULL);
|
||||||
m_noStrings = 0;
|
m_noStrings = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxChoice::GetSelection() const
|
int wxChoice::GetSelection() const
|
||||||
{
|
{
|
||||||
// TODO
|
XmString text;
|
||||||
return 0;
|
char *s;
|
||||||
|
Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget);
|
||||||
|
XtVaGetValues (label,
|
||||||
|
XmNlabelString, &text,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (wxNode * node = m_stringList.First (); node; node = node->Next ())
|
||||||
|
{
|
||||||
|
char *s1 = (char *) node->Data ();
|
||||||
|
if (s1 == s || strcmp (s1, s) == 0)
|
||||||
|
{
|
||||||
|
XmStringFree(text) ;
|
||||||
|
XtFree (s);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
} // for()
|
||||||
|
|
||||||
|
XmStringFree(text) ;
|
||||||
|
XtFree (s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
XmStringFree(text) ;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::SetSelection(int n)
|
void wxChoice::SetSelection(int n)
|
||||||
{
|
{
|
||||||
// TODO
|
m_inSetValue = TRUE;
|
||||||
|
|
||||||
|
wxNode *node = m_stringList.Nth (n);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
Dimension selectionWidth, selectionHeight;
|
||||||
|
|
||||||
|
char *s = (char *) node->Data ();
|
||||||
|
XmString text = XmStringCreateSimple (s);
|
||||||
|
XtVaGetValues ((Widget) m_widgetList[n], XmNwidth, &selectionWidth, XmNheight, &selectionHeight, NULL);
|
||||||
|
Widget label = XmOptionButtonGadget ((Widget) m_buttonWidget);
|
||||||
|
XtVaSetValues (label,
|
||||||
|
XmNlabelString, text,
|
||||||
|
NULL);
|
||||||
|
XmStringFree (text);
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget,
|
||||||
|
XmNwidth, selectionWidth, XmNheight, selectionHeight,
|
||||||
|
XmNmenuHistory, (Widget) m_widgetList[n], NULL);
|
||||||
|
}
|
||||||
|
m_inSetValue = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxChoice::FindString(const wxString& s) const
|
int wxChoice::FindString(const wxString& s) const
|
||||||
{
|
{
|
||||||
// TODO
|
int i = 0;
|
||||||
return 0;
|
for (wxNode * node = m_stringList.First (); node; node = node->Next ())
|
||||||
|
{
|
||||||
|
char *s1 = (char *) node->Data ();
|
||||||
|
if (s == s1)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxChoice::GetString(int n) const
|
wxString wxChoice::GetString(int n) const
|
||||||
{
|
{
|
||||||
// TODO
|
wxNode *node = m_stringList.Nth (n);
|
||||||
return wxString("");
|
if (node)
|
||||||
|
return wxString((char *) node->Data ());
|
||||||
|
else
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxChoice::SetColumns(int n)
|
||||||
|
{
|
||||||
|
if (n<1) n = 1 ;
|
||||||
|
|
||||||
|
short numColumns = n ;
|
||||||
|
Arg args[3];
|
||||||
|
|
||||||
|
XtSetArg(args[0], XmNnumColumns, numColumns);
|
||||||
|
XtSetArg(args[1], XmNpacking, XmPACK_COLUMN);
|
||||||
|
XtSetValues((Widget) m_menuWidget,args,2) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxChoice::GetColumns(void) const
|
||||||
|
{
|
||||||
|
short numColumns ;
|
||||||
|
|
||||||
|
XtVaGetValues((Widget) m_menuWidget,XmNnumColumns,&numColumns,NULL) ;
|
||||||
|
return numColumns ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxChoice::SetFocus()
|
||||||
|
{
|
||||||
|
XmProcessTraversal(XtParent((Widget)m_mainWidget), XmTRAVERSE_CURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxChoice::SetSize(int x, int y, int width, int height, int sizeFlags)
|
void wxChoice::SetSize(int x, int y, int width, int height, int sizeFlags)
|
||||||
{
|
{
|
||||||
// TODO
|
XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_ANY, NULL);
|
||||||
|
bool managed = XtIsManaged((Widget) m_formWidget);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild ((Widget) m_formWidget);
|
||||||
|
|
||||||
|
int actualWidth = width, actualHeight = height;
|
||||||
|
|
||||||
|
if (width > -1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_noStrings; i++)
|
||||||
|
XtVaSetValues ((Widget) m_widgetList[i], XmNwidth, actualWidth, NULL);
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNwidth, actualWidth,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (height > -1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_noStrings; i++)
|
||||||
|
XtVaSetValues ((Widget) m_widgetList[i], XmNheight, actualHeight, NULL);
|
||||||
|
XtVaSetValues ((Widget) m_buttonWidget, XmNheight, actualHeight,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild ((Widget) m_formWidget);
|
||||||
|
XtVaSetValues((Widget) m_formWidget, XmNresizePolicy, XmRESIZE_NONE, NULL);
|
||||||
|
|
||||||
|
wxControl::SetSize (x, y, width, height, sizeFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxChoice::GetStringSelection () const
|
wxString wxChoice::GetStringSelection () const
|
||||||
@@ -96,7 +375,7 @@ wxString wxChoice::GetStringSelection () const
|
|||||||
if (sel > -1)
|
if (sel > -1)
|
||||||
return wxString(this->GetString (sel));
|
return wxString(this->GetString (sel));
|
||||||
else
|
else
|
||||||
return wxString("");
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxChoice::SetStringSelection (const wxString& s)
|
bool wxChoice::SetStringSelection (const wxString& s)
|
||||||
@@ -117,3 +396,24 @@ void wxChoice::Command(wxCommandEvent & event)
|
|||||||
ProcessCommand (event);
|
ProcessCommand (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxChoiceCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxChoice *item = (wxChoice *) clientData;
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->m_inSetValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *s = NULL;
|
||||||
|
XtVaGetValues (w, XmNuserData, &s, NULL);
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
wxCommandEvent event (wxEVT_COMMAND_CHOICE_SELECTED);
|
||||||
|
event.m_commandInt = item->FindString (s);
|
||||||
|
// event.m_commandString = s;
|
||||||
|
item->ProcessCommand (event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -14,174 +14,418 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/cursor.h"
|
#include "wx/cursor.h"
|
||||||
|
#include "wx/gdicmn.h"
|
||||||
#include "wx/icon.h"
|
#include "wx/icon.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARIES
|
#if !USE_SHARED_LIBRARIES
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
|
IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxXCursor, wxObject)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxCursorRefData::wxCursorRefData()
|
wxCursorRefData::wxCursorRefData()
|
||||||
{
|
{
|
||||||
m_width = 32; m_height = 32;
|
m_width = 32; m_height = 32;
|
||||||
|
m_cursorId = wxCURSOR_NONE;
|
||||||
/* TODO
|
|
||||||
m_hCursor = 0 ;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCursorRefData::~wxCursorRefData()
|
wxCursorRefData::~wxCursorRefData()
|
||||||
{
|
{
|
||||||
// TODO: destroy cursor
|
wxNode* node = m_cursors.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxXCursor* c = (wxXCursor*) node->Data();
|
||||||
|
// TODO: how to delete cursor?
|
||||||
|
// XDestroyCursor((Display*) c->m_display, (Cursor) c->m_cursor); // ??
|
||||||
|
delete c;
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursors
|
|
||||||
wxCursor::wxCursor()
|
wxCursor::wxCursor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCursor::wxCursor(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSED(height),
|
wxCursor::wxCursor(const char bits[], int width, int height,
|
||||||
int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY), const char WXUNUSED(maskBits)[])
|
int hotSpotX, int hotSpotY, const char maskBits[])
|
||||||
{
|
{
|
||||||
|
m_refData = new wxCursorRefData;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) wxGetDisplay();
|
||||||
|
int screen_num = DefaultScreen (dpy);
|
||||||
|
|
||||||
|
Pixmap pixmap = XCreatePixmapFromBitmapData (dpy,
|
||||||
|
RootWindow (dpy, DefaultScreen(dpy)),
|
||||||
|
(char*) bits, width, height,
|
||||||
|
1 , 0 , 1);
|
||||||
|
|
||||||
|
Pixmap mask_pixmap = None;
|
||||||
|
if (maskBits != NULL)
|
||||||
|
{
|
||||||
|
mask_pixmap = XCreatePixmapFromBitmapData (dpy,
|
||||||
|
RootWindow (dpy, DefaultScreen(dpy)),
|
||||||
|
(char*) maskBits, width, height,
|
||||||
|
1 , 0 , 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XColor foreground_color;
|
||||||
|
XColor background_color;
|
||||||
|
foreground_color.pixel = BlackPixel(dpy, screen_num);
|
||||||
|
background_color.pixel = WhitePixel(dpy, screen_num);
|
||||||
|
Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
|
||||||
|
XQueryColor(dpy, cmap, &foreground_color);
|
||||||
|
XQueryColor(dpy, cmap, &background_color);
|
||||||
|
|
||||||
|
Cursor cursor = XCreatePixmapCursor (dpy,
|
||||||
|
pixmap,
|
||||||
|
mask_pixmap,
|
||||||
|
&foreground_color,
|
||||||
|
&background_color,
|
||||||
|
hotSpotX ,
|
||||||
|
hotSpotY);
|
||||||
|
|
||||||
|
XFreePixmap( dpy, pixmap );
|
||||||
|
if (mask_pixmap != None)
|
||||||
|
{
|
||||||
|
XFreePixmap( dpy, mask_pixmap );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor)
|
||||||
|
{
|
||||||
|
wxXCursor *c = new wxXCursor;
|
||||||
|
|
||||||
|
c->m_cursor = (WXCursor) cursor;
|
||||||
|
c->m_display = (WXDisplay*) dpy;
|
||||||
|
M_CURSORDATA->m_cursors.Append(c);
|
||||||
|
M_CURSORDATA->m_ok = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
M_CURSORDATA->m_ok = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
|
wxCursor::wxCursor(const wxString& name, long flags, int hotSpotX, int hotSpotY)
|
||||||
{
|
{
|
||||||
m_refData = new wxIconRefData;
|
// Must be an XBM file
|
||||||
|
if (flags != wxBITMAP_TYPE_XBM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_refData = new wxCursorRefData;
|
||||||
|
|
||||||
|
int hotX = -1, hotY = -1;
|
||||||
|
unsigned int w, h;
|
||||||
|
Pixmap pixmap;
|
||||||
|
|
||||||
|
Display *dpy = (Display*) wxGetDisplay();
|
||||||
|
int screen_num = DefaultScreen (dpy);
|
||||||
|
|
||||||
|
int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
|
||||||
|
(char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
|
||||||
|
|
||||||
|
M_BITMAPDATA->m_width = w;
|
||||||
|
M_BITMAPDATA->m_height = h;
|
||||||
|
M_BITMAPDATA->m_depth = 1;
|
||||||
|
|
||||||
|
if ((value == BitmapFileInvalid) ||
|
||||||
|
(value == BitmapOpenFailed) ||
|
||||||
|
(value == BitmapNoMemory))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XColor foreground_color;
|
||||||
|
XColor background_color;
|
||||||
|
foreground_color.pixel = BlackPixel(dpy, screen_num);
|
||||||
|
background_color.pixel = WhitePixel(dpy, screen_num);
|
||||||
|
Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
|
||||||
|
XQueryColor(dpy, cmap, &foreground_color);
|
||||||
|
XQueryColor(dpy, cmap, &background_color);
|
||||||
|
|
||||||
|
// TODO: how do we determine whether hotX, hotY were read correctly?
|
||||||
|
if (hotX < 0 || hotY < 0)
|
||||||
|
{
|
||||||
|
hotX = hotSpotX;
|
||||||
|
hotY = hotSpotY;
|
||||||
|
}
|
||||||
|
if (hotX < 0 || hotY < 0)
|
||||||
|
{
|
||||||
|
hotX = 0;
|
||||||
|
hotY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixmap mask_pixmap = None;
|
||||||
|
Cursor cursor = XCreatePixmapCursor (dpy,
|
||||||
|
pixmap,
|
||||||
|
mask_pixmap,
|
||||||
|
&foreground_color,
|
||||||
|
&background_color,
|
||||||
|
hotX,
|
||||||
|
hotY);
|
||||||
|
|
||||||
|
XFreePixmap( dpy, pixmap );
|
||||||
|
if (cursor)
|
||||||
|
{
|
||||||
|
wxXCursor *c = new wxXCursor;
|
||||||
|
|
||||||
|
c->m_cursor = (WXCursor) cursor;
|
||||||
|
c->m_display = (WXDisplay*) dpy;
|
||||||
|
M_CURSORDATA->m_cursors.Append(c);
|
||||||
|
M_CURSORDATA->m_ok = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: create cursor from a file
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursors by stock number
|
// Cursors by stock number
|
||||||
wxCursor::wxCursor(int cursor_type)
|
wxCursor::wxCursor(wxStockCursor id)
|
||||||
{
|
{
|
||||||
m_refData = new wxIconRefData;
|
m_refData = new wxCursorRefData;
|
||||||
|
M_CURSORDATA->m_cursorId = id;
|
||||||
|
|
||||||
/* TODO
|
WXCursor cursor = GetXCursor(wxGetDisplay());
|
||||||
switch (cursor_type)
|
if (cursor)
|
||||||
{
|
|
||||||
case wxCURSOR_WAIT:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_WAIT);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_IBEAM:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_IBEAM);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_CROSS:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_CROSS);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_SIZENWSE:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_SIZENWSE);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_SIZENESW:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_SIZENESW);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_SIZEWE:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_SIZEWE);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_SIZENS:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_SIZENS);
|
|
||||||
break;
|
|
||||||
case wxCURSOR_CHAR:
|
|
||||||
{
|
{
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_ARROW);
|
wxXCursor* c = new wxXCursor;
|
||||||
break;
|
c->m_cursor = cursor;
|
||||||
|
c->m_display = wxGetDisplay();
|
||||||
|
M_CURSORDATA->m_cursors.Append(c);
|
||||||
|
M_CURSORDATA->m_ok = TRUE;
|
||||||
}
|
}
|
||||||
case wxCURSOR_HAND:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_HAND");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_BULLSEYE:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_BULLSEYE");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_PENCIL:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_PENCIL");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_MAGNIFIER:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_MAGNIFIER");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_NO_ENTRY:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_NO_ENTRY");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_LEFT_BUTTON:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_ARROW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_RIGHT_BUTTON:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_ARROW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_MIDDLE_BUTTON:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_ARROW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_SIZING:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_SIZING");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_WATCH:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_WATCH");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_SPRAYCAN:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_ROLLER");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_PAINT_BRUSH:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_PBRUSH");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_POINT_LEFT:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_PLEFT");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_POINT_RIGHT:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_PRIGHT");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_QUESTION_ARROW:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_QARROW");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case wxCURSOR_BLANK:
|
|
||||||
{
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), "wxCURSOR_BLANK");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
case wxCURSOR_ARROW:
|
|
||||||
M_CURSORDATA->m_hCursor = (WXHCURSOR) LoadCursor(NULL, IDC_ARROW);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCursor::~wxCursor()
|
wxCursor::~wxCursor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Motif-specific: create/get a cursor for the current display
|
||||||
|
WXCursor wxCursor::GetXCursor(WXDisplay* display)
|
||||||
|
{
|
||||||
|
if (!M_CURSORDATA)
|
||||||
|
return (WXCursor) 0;
|
||||||
|
wxNode* node = M_CURSORDATA->m_cursors.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxXCursor* c = (wxXCursor*) node->Data();
|
||||||
|
if (c->m_display == display)
|
||||||
|
return c->m_cursor;
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// No cursor for this display, so let's see if we're an id-type cursor.
|
||||||
|
|
||||||
|
if (M_CURSORDATA->m_cursorId != wxCURSOR_NONE)
|
||||||
|
{
|
||||||
|
WXCursor cursor = MakeCursor(display, M_CURSORDATA->m_cursorId);
|
||||||
|
if (cursor)
|
||||||
|
{
|
||||||
|
wxXCursor* c = new wxXCursor;
|
||||||
|
c->m_cursor = cursor;
|
||||||
|
c->m_display = display;
|
||||||
|
M_CURSORDATA->m_cursors.Append(c);
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (WXCursor) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not an id-type cursor, so we don't know how to create it.
|
||||||
|
return (WXCursor) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a cursor from standard id
|
||||||
|
WXCursor wxCursor::MakeCursor(WXDisplay* display, wxStockCursor id)
|
||||||
|
{
|
||||||
|
Display* dpy = (Display*) display;
|
||||||
|
Cursor cursor = (Cursor) 0;
|
||||||
|
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case wxCURSOR_WAIT:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_watch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_CROSS:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_crosshair);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_CHAR:
|
||||||
|
{
|
||||||
|
// Nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_HAND:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_hand1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_BULLSEYE:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_PENCIL:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_pencil);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_MAGNIFIER:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sizing);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_IBEAM:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_xterm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_NO_ENTRY:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_pirate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_LEFT_BUTTON:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_leftbutton);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_RIGHT_BUTTON:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_rightbutton);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_MIDDLE_BUTTON:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_middlebutton);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_QUESTION_ARROW:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_question_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_SIZING:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sizing);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_WATCH:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_watch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_SPRAYCAN:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_spraycan);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_PAINT_BRUSH:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_spraycan);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_SIZENWSE:
|
||||||
|
case wxCURSOR_SIZENESW:
|
||||||
|
{
|
||||||
|
// Not available in X
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_crosshair);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_SIZEWE:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_SIZENS:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_POINT_LEFT:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sb_left_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_POINT_RIGHT:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_sb_right_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// (JD Huggins) added more stock cursors for X
|
||||||
|
// X-only cursors BEGIN
|
||||||
|
case wxCURSOR_CROSS_REVERSE:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor(dpy, XC_cross_reverse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_DOUBLE_ARROW:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor(dpy, XC_double_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_BASED_ARROW_UP:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor(dpy, XC_based_arrow_up);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_BASED_ARROW_DOWN:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor(dpy, XC_based_arrow_down);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
case wxCURSOR_ARROW:
|
||||||
|
{
|
||||||
|
cursor = XCreateFontCursor (dpy, XC_top_left_arrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case wxCURSOR_BLANK:
|
||||||
|
{
|
||||||
|
GC gc;
|
||||||
|
XGCValues gcv;
|
||||||
|
Pixmap empty_pixmap;
|
||||||
|
XColor blank_color;
|
||||||
|
|
||||||
|
empty_pixmap = XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
|
||||||
|
16, 16, 1);
|
||||||
|
gcv.function = GXxor;
|
||||||
|
gc = XCreateGC (dpy,
|
||||||
|
empty_pixmap,
|
||||||
|
GCFunction,
|
||||||
|
&gcv);
|
||||||
|
XCopyArea (dpy,
|
||||||
|
empty_pixmap,
|
||||||
|
empty_pixmap,
|
||||||
|
gc,
|
||||||
|
0, 0,
|
||||||
|
16, 16,
|
||||||
|
0, 0);
|
||||||
|
XFreeGC (dpy, gc);
|
||||||
|
cursor = XCreatePixmapCursor (dpy,
|
||||||
|
empty_pixmap,
|
||||||
|
empty_pixmap,
|
||||||
|
&blank_color,
|
||||||
|
&blank_color,
|
||||||
|
8, 8);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (WXCursor) cursor;
|
||||||
|
}
|
||||||
|
|
||||||
// Global cursor setting
|
// Global cursor setting
|
||||||
void wxSetCursor(const wxCursor& cursor)
|
void wxSetCursor(const wxCursor& cursor)
|
||||||
{
|
{
|
||||||
// TODO (optional on platforms with no global cursor)
|
// Nothing to do for Motif (no global cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1081,7 +1081,7 @@ void wxWindowDC::DrawText( const wxString &text, long x, long y, bool use16 )
|
|||||||
|
|
||||||
if (m_font.Ok())
|
if (m_font.Ok())
|
||||||
{
|
{
|
||||||
WXFontStructPtr pFontStruct = m_font.FindOrCreateFontStruct(m_userScaleY*m_logicalScaleY);
|
WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
|
||||||
int direction, descent;
|
int direction, descent;
|
||||||
XCharStruct overall_return;
|
XCharStruct overall_return;
|
||||||
if (use16)
|
if (use16)
|
||||||
@@ -1235,7 +1235,7 @@ void wxWindowDC::GetTextExtent( const wxString &string, long *width, long *heigh
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXFontStructPtr pFontStruct = theFont->FindOrCreateFontStruct(m_userScaleY*m_logicalScaleY);
|
WXFontStructPtr pFontStruct = theFont->GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
|
||||||
|
|
||||||
int direction, ascent, descent2;
|
int direction, ascent, descent2;
|
||||||
XCharStruct overall;
|
XCharStruct overall;
|
||||||
@@ -1265,7 +1265,7 @@ long wxWindowDC::GetCharWidth(void)
|
|||||||
if (!m_font.Ok())
|
if (!m_font.Ok())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
WXFontStructPtr pFontStruct = m_font.FindOrCreateFontStruct(m_userScaleY * m_logicalScaleY);
|
WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY * m_logicalScaleY, m_display);
|
||||||
|
|
||||||
int direction, ascent, descent;
|
int direction, ascent, descent;
|
||||||
XCharStruct overall;
|
XCharStruct overall;
|
||||||
@@ -1281,7 +1281,7 @@ long wxWindowDC::GetCharHeight(void)
|
|||||||
if (!m_font.Ok())
|
if (!m_font.Ok())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
WXFontStructPtr pFontStruct = m_font.FindOrCreateFontStruct(m_userScaleY*m_logicalScaleY);
|
WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
|
||||||
|
|
||||||
int direction, ascent, descent;
|
int direction, ascent, descent;
|
||||||
XCharStruct overall;
|
XCharStruct overall;
|
||||||
@@ -1348,7 +1348,7 @@ void wxWindowDC::SetFont( const wxFont &font )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXFontStructPtr pFontStruct = m_font.FindOrCreateFontStruct(m_userScaleY*m_logicalScaleY);
|
WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display);
|
||||||
|
|
||||||
Font fontId = ((XFontStruct*)pFontStruct)->fid;
|
Font fontId = ((XFontStruct*)pFontStruct)->fid;
|
||||||
XSetFont ((Display*) m_display, (GC) m_gc, fontId);
|
XSetFont ((Display*) m_display, (GC) m_gc, fontId);
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
#include "wx/filedlg.h"
|
#include "wx/filedlg.h"
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
IMPLEMENT_CLASS(wxFileDialog, wxDialog)
|
IMPLEMENT_CLASS(wxFileDialog, wxDialog)
|
||||||
#endif
|
#endif
|
||||||
@@ -84,6 +86,176 @@ char *wxFileSelectorEx(const char *title,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Motif file selector code
|
||||||
|
#if 0
|
||||||
|
char *wxFileSelectorAnswer = NULL;
|
||||||
|
Bool wxFileSelectorReturned = FALSE;
|
||||||
|
|
||||||
|
void wxFileSelCancel(Widget fs, XtPointer client_data, XmFileSelectionBoxCallbackStruct *cbs)
|
||||||
|
{
|
||||||
|
wxFileSelectorAnswer = NULL;
|
||||||
|
wxFileSelectorReturned = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxFileSelOk(Widget fs, XtPointer client_data, XmFileSelectionBoxCallbackStruct *cbs)
|
||||||
|
{
|
||||||
|
char *filename = NULL;
|
||||||
|
if (!XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &filename)) {
|
||||||
|
wxFileSelectorAnswer = NULL;
|
||||||
|
wxFileSelectorReturned = TRUE;
|
||||||
|
} else {
|
||||||
|
if (filename) {
|
||||||
|
if (wxFileSelectorAnswer) delete[] wxFileSelectorAnswer;
|
||||||
|
wxFileSelectorAnswer = copystring(filename);
|
||||||
|
XtFree(filename);
|
||||||
|
}
|
||||||
|
wxFileSelectorReturned = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *wxMotifFileSelector(char *message,
|
||||||
|
char *default_path, char *default_filename,
|
||||||
|
char *default_extension, char *wildcard, int flags,
|
||||||
|
wxWindow *parent, int x, int y)
|
||||||
|
{
|
||||||
|
wxBeginBusyCursor();
|
||||||
|
static char fileBuf[512];
|
||||||
|
Widget parentWidget = 0;
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (parent->IsKindOf(CLASSINFO(wxFrame)))
|
||||||
|
parentWidget = ((wxFrame *)parent)->frameShell;
|
||||||
|
else if (parent->IsKindOf(CLASSINFO(wxDialogBox)))
|
||||||
|
parentWidget = ((wxDialogBox *)parent)->dialogShell;
|
||||||
|
else
|
||||||
|
parentWidget = (Widget)parent->handle;
|
||||||
|
}
|
||||||
|
else if (wxTheApp->wx_frame)
|
||||||
|
parentWidget = wxTheApp->wx_frame->frameShell;
|
||||||
|
|
||||||
|
Widget fileSel = XmCreateFileSelectionDialog(parentWidget, "file_selector", NULL, 0);
|
||||||
|
XtUnmanageChild(XmFileSelectionBoxGetChild(fileSel, XmDIALOG_HELP_BUTTON));
|
||||||
|
|
||||||
|
Widget shell = XtParent(fileSel);
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
XtVaSetValues(shell, XmNtitle, message, NULL);
|
||||||
|
|
||||||
|
char *entirePath = NULL;
|
||||||
|
|
||||||
|
if (default_path && default_filename)
|
||||||
|
{
|
||||||
|
sprintf(wxBuffer, "%s/%s", default_path, default_filename);
|
||||||
|
entirePath = copystring(wxBuffer);
|
||||||
|
}
|
||||||
|
else if (default_path && !default_filename)
|
||||||
|
{
|
||||||
|
sprintf(wxBuffer, "%s/", default_path);
|
||||||
|
entirePath = copystring(wxBuffer);
|
||||||
|
}
|
||||||
|
else if ((!default_path) && default_filename)
|
||||||
|
{
|
||||||
|
sprintf(wxBuffer, "%s", default_filename);
|
||||||
|
entirePath = copystring(wxBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entirePath)
|
||||||
|
{
|
||||||
|
Widget selectionWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_TEXT);
|
||||||
|
XmTextSetString(selectionWidget, entirePath);
|
||||||
|
delete[] entirePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wildcard)
|
||||||
|
{
|
||||||
|
if (default_path)
|
||||||
|
sprintf(wxBuffer, "%s/%s", default_path, wildcard);
|
||||||
|
else
|
||||||
|
sprintf(wxBuffer, "%s", wildcard);
|
||||||
|
|
||||||
|
Widget filterWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_FILTER_TEXT);
|
||||||
|
XmTextSetString(filterWidget, wxBuffer);
|
||||||
|
XmFileSelectionDoSearch(fileSel, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suggested by Terry Gitnick, 16/9/97, because of change in Motif
|
||||||
|
// file selector on Solaris 1.5.1.
|
||||||
|
if ( default_path )
|
||||||
|
{
|
||||||
|
XmString thePath = XmStringCreateLtoR (default_path,
|
||||||
|
XmSTRING_DEFAULT_CHARSET);
|
||||||
|
|
||||||
|
XtVaSetValues (fileSel,
|
||||||
|
XmNdirectory, thePath,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
XmStringFree(thePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
XtAddCallback(fileSel, XmNcancelCallback, (XtCallbackProc)wxFileSelCancel, (XtPointer)NULL);
|
||||||
|
XtAddCallback(fileSel, XmNokCallback, (XtCallbackProc)wxFileSelOk, (XtPointer)NULL);
|
||||||
|
|
||||||
|
//#if XmVersion > 1000
|
||||||
|
// I'm not sure about what you mean with XmVersion.
|
||||||
|
// If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
|
||||||
|
// (Motif1.1.4 ==> XmVersion 1100 )
|
||||||
|
// Nevertheless, I put here a #define, so anyone can choose in (I)makefile...
|
||||||
|
//
|
||||||
|
#if !DEFAULT_FILE_SELECTOR_SIZE
|
||||||
|
int width = wxFSB_WIDTH;
|
||||||
|
int height = wxFSB_HEIGHT;
|
||||||
|
XtVaSetValues(fileSel,
|
||||||
|
XmNwidth, width,
|
||||||
|
XmNheight, height,
|
||||||
|
XmNresizePolicy, XmRESIZE_NONE,
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XtManageChild(fileSel);
|
||||||
|
|
||||||
|
if (wxFileSelectorAnswer)
|
||||||
|
delete[] wxFileSelectorAnswer;
|
||||||
|
|
||||||
|
wxFileSelectorAnswer = NULL;
|
||||||
|
wxFileSelectorReturned = FALSE;
|
||||||
|
|
||||||
|
wxEndBusyCursor();
|
||||||
|
|
||||||
|
XtAddGrab(XtParent(fileSel), TRUE, FALSE);
|
||||||
|
XEvent event;
|
||||||
|
while (!wxFileSelectorReturned)
|
||||||
|
{
|
||||||
|
XtAppNextEvent(wxTheApp->appContext, &event);
|
||||||
|
XtDispatchEvent(&event);
|
||||||
|
}
|
||||||
|
XtRemoveGrab(XtParent(fileSel));
|
||||||
|
|
||||||
|
XmUpdateDisplay(wxTheApp->topLevel); // Experimental
|
||||||
|
|
||||||
|
// XtDestroyWidget(fileSel);
|
||||||
|
XtUnmapWidget(XtParent(fileSel));
|
||||||
|
XtDestroyWidget(XtParent(fileSel));
|
||||||
|
|
||||||
|
// Now process all events, because otherwise
|
||||||
|
// this might remain on the screen
|
||||||
|
XSync(XtDisplay(wxTheApp->topLevel), FALSE);
|
||||||
|
while (XtAppPending(wxTheApp->appContext))
|
||||||
|
{
|
||||||
|
XFlush(XtDisplay(wxTheApp->topLevel));
|
||||||
|
XtAppNextEvent(wxTheApp->appContext, &event);
|
||||||
|
XtDispatchEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wxFileSelectorAnswer)
|
||||||
|
{
|
||||||
|
strcpy(fileBuf, wxFileSelectorAnswer);
|
||||||
|
return fileBuf;
|
||||||
|
}
|
||||||
|
else return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
|
wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
|
||||||
const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
|
const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
|
||||||
long style, const wxPoint& pos)
|
long style, const wxPoint& pos)
|
||||||
|
@@ -19,13 +19,33 @@
|
|||||||
#include "wx/gdicmn.h"
|
#include "wx/gdicmn.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <Xm/Xm.h>
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARIES
|
#if !USE_SHARED_LIBRARIES
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxFontRefData::wxFontRefData(): m_fontsByScale(wxKEY_INTEGER)
|
wxXFont::wxXFont()
|
||||||
|
{
|
||||||
|
m_fontStruct = (WXFontStructPtr) 0;
|
||||||
|
m_fontList = (WXFontList) 0;
|
||||||
|
m_display = (WXDisplay*) 0;
|
||||||
|
m_scale = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxXFont::~wxXFont()
|
||||||
|
{
|
||||||
|
XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
|
||||||
|
XmFontList fontList = (XmFontList) m_fontList;
|
||||||
|
|
||||||
|
XmFontListFree (fontList);
|
||||||
|
|
||||||
|
// TODO: why does freeing the font produce a segv???
|
||||||
|
// Note that XFreeFont wasn't called in wxWin 1.68 either.
|
||||||
|
// XFreeFont((Display*) m_display, fontStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFontRefData::wxFontRefData()
|
||||||
{
|
{
|
||||||
m_style = 0;
|
m_style = 0;
|
||||||
m_pointSize = 0;
|
m_pointSize = 0;
|
||||||
@@ -36,7 +56,7 @@ wxFontRefData::wxFontRefData(): m_fontsByScale(wxKEY_INTEGER)
|
|||||||
m_faceName = "";
|
m_faceName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFontRefData::wxFontRefData(const wxFontRefData& data): m_fontsByScale(wxKEY_INTEGER)
|
wxFontRefData::wxFontRefData(const wxFontRefData& data)
|
||||||
{
|
{
|
||||||
m_style = data.m_style;
|
m_style = data.m_style;
|
||||||
m_pointSize = data.m_pointSize;
|
m_pointSize = data.m_pointSize;
|
||||||
@@ -52,17 +72,14 @@ wxFontRefData::wxFontRefData(const wxFontRefData& data): m_fontsByScale(wxKEY_IN
|
|||||||
|
|
||||||
wxFontRefData::~wxFontRefData()
|
wxFontRefData::~wxFontRefData()
|
||||||
{
|
{
|
||||||
wxNode* node = m_fontsByScale.First();
|
wxNode* node = m_fonts.First();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
XFontStruct* fontStruct = (XFontStruct*) node->Data();
|
wxXFont* f = (wxXFont*) node->Data();
|
||||||
// TODO: why does freeing the font produce a segv???
|
delete f;
|
||||||
// Commenting it out will result in memory leaks, and
|
|
||||||
// maybe X resource problems, who knows...
|
|
||||||
// XFreeFont((Display*) wxGetDisplay, fontStruct);
|
|
||||||
node = node->Next();
|
node = node->Next();
|
||||||
}
|
}
|
||||||
m_fontsByScale.Clear();
|
m_fonts.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFont::wxFont()
|
wxFont::wxFont()
|
||||||
@@ -255,18 +272,21 @@ wxString wxFont::GetWeightString() const
|
|||||||
// Find an existing, or create a new, XFontStruct
|
// Find an existing, or create a new, XFontStruct
|
||||||
// based on this wxFont and the given scale. Append the
|
// based on this wxFont and the given scale. Append the
|
||||||
// font to list in the private data for future reference.
|
// font to list in the private data for future reference.
|
||||||
WXFontStructPtr wxFont::FindOrCreateFontStruct(double scale)
|
wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
|
||||||
{
|
{
|
||||||
if (!Ok())
|
if (!Ok())
|
||||||
return NULL;
|
return (wxXFont*) NULL;
|
||||||
|
|
||||||
long intScale = long(scale * 100.0 + 0.5); // key for fontlist
|
long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
|
||||||
int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
|
int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
|
||||||
|
|
||||||
wxNode* node = M_FONTDATA->m_fontsByScale.Find(intScale);
|
wxNode* node = M_FONTDATA->m_fonts.First();
|
||||||
if (node)
|
while (node)
|
||||||
{
|
{
|
||||||
return (WXFontStructPtr) node->Data();
|
wxXFont* f = (wxXFont*) node->Data();
|
||||||
|
if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
|
||||||
|
return f;
|
||||||
|
node = node->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family,
|
WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family,
|
||||||
@@ -297,14 +317,19 @@ WXFontStructPtr wxFont::FindOrCreateFontStruct(double scale)
|
|||||||
}
|
}
|
||||||
if (font)
|
if (font)
|
||||||
{
|
{
|
||||||
M_FONTDATA->m_fontsByScale.Append(intScale, (wxObject*) font);
|
wxXFont* f = new wxXFont;
|
||||||
return (WXFontStructPtr) font;
|
f->m_fontStruct = font;
|
||||||
|
f->m_display = ( display ? display : wxGetDisplay() );
|
||||||
|
f->m_scale = intScale;
|
||||||
|
f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET);
|
||||||
|
M_FONTDATA->m_fonts.Append(f);
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
return font;
|
return (wxXFont*) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXFontStructPtr wxFont::LoadQueryFont(int pointSize, int family, int style,
|
WXFontStructPtr wxFont::LoadQueryFont(int pointSize, int family, int style,
|
||||||
int weight, bool underlined)
|
int weight, bool underlined) const
|
||||||
{
|
{
|
||||||
char *xfamily;
|
char *xfamily;
|
||||||
char *xstyle;
|
char *xstyle;
|
||||||
|
@@ -14,6 +14,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/icon.h"
|
#include "wx/icon.h"
|
||||||
|
#include "wx/window.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARIES
|
#if !USE_SHARED_LIBRARIES
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
|
IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
|
||||||
@@ -23,23 +29,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
|
|||||||
* Icons
|
* Icons
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
wxIconRefData::wxIconRefData()
|
|
||||||
{
|
|
||||||
// TODO: init icon handle
|
|
||||||
}
|
|
||||||
|
|
||||||
wxIconRefData::~wxIconRefData()
|
|
||||||
{
|
|
||||||
// TODO: destroy icon handle
|
|
||||||
}
|
|
||||||
|
|
||||||
wxIcon::wxIcon()
|
wxIcon::wxIcon()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
wxIcon::wxIcon(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSED(height))
|
// Create from XBM data
|
||||||
|
wxIcon::wxIcon(const char bits[], int width, int height)
|
||||||
{
|
{
|
||||||
|
(void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create from XPM data
|
||||||
|
wxIcon::wxIcon(const char **data)
|
||||||
|
{
|
||||||
|
(void) Create((void*) data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxIcon::wxIcon(const wxString& icon_file, long flags,
|
wxIcon::wxIcon(const wxString& icon_file, long flags,
|
||||||
@@ -58,7 +61,7 @@ bool wxIcon::LoadFile(const wxString& filename, long type,
|
|||||||
{
|
{
|
||||||
UnRef();
|
UnRef();
|
||||||
|
|
||||||
m_refData = new wxIconRefData;
|
m_refData = new wxBitmapRefData;
|
||||||
|
|
||||||
wxBitmapHandler *handler = FindHandler(type);
|
wxBitmapHandler *handler = FindHandler(type);
|
||||||
|
|
||||||
|
@@ -17,20 +17,30 @@
|
|||||||
#include "wx/settings.h"
|
#include "wx/settings.h"
|
||||||
#include "wx/dynarray.h"
|
#include "wx/dynarray.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
|
||||||
|
#include <Xm/List.h>
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void wxListBoxCallback (Widget w, XtPointer clientData,
|
||||||
|
XmListCallbackStruct * cbs);
|
||||||
|
|
||||||
|
void wxListBoxDefaultActionProc (Widget list_w, XtPointer client_data, XmListCallbackStruct * cbs);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// list box control implementation
|
// list box control implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Listbox item
|
// Listbox item
|
||||||
wxListBox::wxListBox()
|
wxListBox::wxListBox(): m_clientDataList(wxKEY_INTEGER)
|
||||||
{
|
{
|
||||||
m_noItems = 0;
|
m_noItems = 0;
|
||||||
m_selected = 0;
|
m_selected = 0;
|
||||||
|
m_inSetValue = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxListBox::Create(wxWindow *parent, wxWindowID id,
|
bool wxListBox::Create(wxWindow *parent, wxWindowID id,
|
||||||
@@ -41,22 +51,69 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id,
|
|||||||
const wxValidator& validator,
|
const wxValidator& validator,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
m_noItems = n;
|
m_inSetValue = FALSE;
|
||||||
m_selected = 0;
|
m_windowStyle = style;
|
||||||
|
m_noItems = n;
|
||||||
|
m_selected = 0;
|
||||||
|
|
||||||
SetName(name);
|
SetName(name);
|
||||||
SetValidator(validator);
|
SetValidator(validator);
|
||||||
|
|
||||||
if (parent) parent->AddChild(this);
|
if (parent) parent->AddChild(this);
|
||||||
|
|
||||||
wxSystemSettings settings;
|
m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
|
||||||
SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
|
|
||||||
|
|
||||||
m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
|
Widget parentWidget = (Widget) parent->GetClientWidget();
|
||||||
|
|
||||||
// TODO create listbox
|
Arg args[3];
|
||||||
|
int count;
|
||||||
|
XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
if (m_windowStyle & wxLB_ALWAYS_SB)
|
||||||
|
{
|
||||||
|
XtSetArg (args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
|
||||||
|
count = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
count = 2;
|
||||||
|
|
||||||
return FALSE;
|
Widget listWidget = XmCreateScrolledList (parentWidget, (char*) (const char*) name, args, count);
|
||||||
|
|
||||||
|
m_mainWidget = (WXWidget) listWidget;
|
||||||
|
|
||||||
|
XtManageChild (listWidget);
|
||||||
|
|
||||||
|
long width = size.x;
|
||||||
|
long height = size.y;
|
||||||
|
if (width == -1)
|
||||||
|
width = 150;
|
||||||
|
if (height == -1)
|
||||||
|
height = 80;
|
||||||
|
|
||||||
|
XtAddCallback (listWidget, XmNbrowseSelectionCallback, (XtCallbackProc) wxListBoxCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
XtAddCallback (listWidget, XmNextendedSelectionCallback, (XtCallbackProc) wxListBoxCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
XtAddCallback (listWidget, XmNmultipleSelectionCallback, (XtCallbackProc) wxListBoxCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
|
||||||
|
XtAddCallback (listWidget, XmNdefaultActionCallback, (XtCallbackProc) wxListBoxDefaultActionProc,
|
||||||
|
(XtPointer) this);
|
||||||
|
|
||||||
|
AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, width, height);
|
||||||
|
|
||||||
|
wxSystemSettings settings;
|
||||||
|
SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
|
||||||
|
|
||||||
|
SetFont(* parent->GetFont());
|
||||||
|
ChangeColour(m_mainWidget);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxListBox::~wxListBox()
|
wxListBox::~wxListBox()
|
||||||
@@ -65,171 +122,608 @@ wxListBox::~wxListBox()
|
|||||||
|
|
||||||
void wxListBox::SetFirstItem(int N)
|
void wxListBox::SetFirstItem(int N)
|
||||||
{
|
{
|
||||||
// TODO
|
int count, length;
|
||||||
|
|
||||||
|
if (N < 0)
|
||||||
|
return;
|
||||||
|
XtVaGetValues ((Widget) m_mainWidget,
|
||||||
|
XmNvisibleItemCount, &count,
|
||||||
|
XmNitemCount, &length,
|
||||||
|
NULL);
|
||||||
|
if ((N + count) >= length)
|
||||||
|
N = length - count;
|
||||||
|
XmListSetPos ((Widget) m_mainWidget, N + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::SetFirstItem(const wxString& s)
|
void wxListBox::SetFirstItem(const wxString& s)
|
||||||
{
|
{
|
||||||
// TODO
|
int N = FindString (s);
|
||||||
|
|
||||||
|
if (N >= 0)
|
||||||
|
SetFirstItem (N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Delete(int N)
|
void wxListBox::Delete(int N)
|
||||||
{
|
{
|
||||||
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
|
||||||
|
bool managed = XtIsManaged(listBox);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild (listBox);
|
||||||
|
|
||||||
|
XmListDeletePos (listBox, N + 1);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild (listBox);
|
||||||
|
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
|
|
||||||
|
// (JDH) need to add code here to take care of clientDataList
|
||||||
|
wxNode *node = m_clientDataList.Find((long)N); // get item from list
|
||||||
|
if (node) m_clientDataList.DeleteNode(node); // if existed then delete from list
|
||||||
|
node = m_clientDataList.First(); // we now have to adjust all keys that
|
||||||
|
while (node) // are >=N+1
|
||||||
|
{ if (node->key.integer >= (long)(N+1)) // very ugly C++ wise but no other way
|
||||||
|
node->key.integer--; // to look at or change key value
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
|
||||||
m_noItems --;
|
m_noItems --;
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Append(const wxString& item)
|
void wxListBox::Append(const wxString& item)
|
||||||
{
|
{
|
||||||
m_noItems ++;
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
|
||||||
|
bool managed = XtIsManaged(listBox);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild (listBox);
|
||||||
|
int n;
|
||||||
|
XtVaGetValues (listBox, XmNitemCount, &n, NULL);
|
||||||
|
XmString text = XmStringCreateSimple ((char*) (const char*) item);
|
||||||
|
// XmListAddItem(listBox, text, n + 1);
|
||||||
|
XmListAddItemUnselected (listBox, text, 0);
|
||||||
|
XmStringFree (text);
|
||||||
|
|
||||||
|
// It seems that if the list is cleared, we must re-ask for
|
||||||
|
// selection policy!!
|
||||||
|
Arg args[3];
|
||||||
|
XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
XtSetValues (listBox, args, 2);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild (listBox);
|
||||||
|
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
|
m_noItems ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Append(const wxString& item, char *Client_data)
|
void wxListBox::Append(const wxString& item, char *clientData)
|
||||||
{
|
{
|
||||||
m_noItems ++;
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
Bool managed = XtIsManaged(listBox);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild (listBox);
|
||||||
|
|
||||||
|
int n;
|
||||||
|
XtVaGetValues (listBox, XmNitemCount, &n, NULL);
|
||||||
|
XmString text = XmStringCreateSimple ((char*) (const char*) item);
|
||||||
|
// XmListAddItem(listBox, text, n + 1);
|
||||||
|
XmListAddItemUnselected (listBox, text, 0);
|
||||||
|
XmStringFree (text);
|
||||||
|
|
||||||
|
// It seems that if the list is cleared, we must re-ask for
|
||||||
|
// selection policy!!
|
||||||
|
Arg args[3];
|
||||||
|
XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
XtSetValues (listBox, args, 2);
|
||||||
|
|
||||||
|
m_clientDataList.Append ((long) n, (wxObject *) clientData);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild (listBox);
|
||||||
|
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
|
|
||||||
|
m_noItems ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Set(int n, const wxString *choices, char** clientData)
|
void wxListBox::Set(int n, const wxString *choices, char** clientData)
|
||||||
{
|
{
|
||||||
m_noItems = n;
|
m_clientDataList.Clear();
|
||||||
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
|
||||||
|
bool managed = XtIsManaged(listBox);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild (listBox);
|
||||||
|
/***
|
||||||
|
for (int i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
XmString text = XmStringCreateSimple(choices[i]);
|
||||||
|
XmListAddItemUnselected(listBox, text, 0);
|
||||||
|
XmStringFree(text);
|
||||||
|
}
|
||||||
|
***/
|
||||||
|
XmString *text = new XmString[n];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
text[i] = XmStringCreateSimple ((char*) (const char*) choices[i]);
|
||||||
|
|
||||||
|
if ( clientData )
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
m_clientDataList.Append ((long) i, (wxObject *) clientData[i]);
|
||||||
|
|
||||||
|
XmListAddItems (listBox, text, n, 0);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
XmStringFree (text[i]);
|
||||||
|
delete[]text;
|
||||||
|
|
||||||
|
// It seems that if the list is cleared, we must re-ask for
|
||||||
|
// selection policy!!
|
||||||
|
Arg args[3];
|
||||||
|
XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
XtSetValues (listBox, args, 2);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild (listBox);
|
||||||
|
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
|
|
||||||
|
m_noItems = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxListBox::FindString(const wxString& s) const
|
int wxListBox::FindString(const wxString& s) const
|
||||||
{
|
{
|
||||||
// TODO
|
XmString str = XmStringCreateSimple ((char*) (const char*) s);
|
||||||
|
int *positions = NULL;
|
||||||
|
int no_positions = 0;
|
||||||
|
bool success = XmListGetMatchPos ((Widget) m_mainWidget, str, &positions, &no_positions);
|
||||||
|
XmStringFree (str);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
int pos = positions[0];
|
||||||
|
if (positions)
|
||||||
|
XtFree ((char *) positions);
|
||||||
|
return pos - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Clear()
|
void wxListBox::Clear()
|
||||||
{
|
{
|
||||||
|
if (m_noItems <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
|
||||||
|
XmListDeleteAllItems (listBox);
|
||||||
|
m_clientDataList.Clear ();
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
|
|
||||||
m_noItems = 0;
|
m_noItems = 0;
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::SetSelection(int N, bool select)
|
void wxListBox::SetSelection(int N, bool select)
|
||||||
{
|
{
|
||||||
// TODO
|
m_inSetValue = TRUE;
|
||||||
|
if (select)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
{
|
||||||
|
int *selections = NULL;
|
||||||
|
int n = GetSelections (&selections);
|
||||||
|
|
||||||
|
// This hack is supposed to work, to make it possible to select more
|
||||||
|
// than one item, but it DOESN'T under Motif 1.1.
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_mainWidget, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
XmListSelectPos ((Widget) m_mainWidget, selections[i] + 1, FALSE);
|
||||||
|
|
||||||
|
XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
|
||||||
|
|
||||||
|
XtVaSetValues ((Widget) m_mainWidget, XmNselectionPolicy, XmEXTENDED_SELECT, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
XmListDeselectPos ((Widget) m_mainWidget, N + 1);
|
||||||
|
|
||||||
|
m_inSetValue = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxListBox::Selected(int N) const
|
bool wxListBox::Selected(int N) const
|
||||||
{
|
{
|
||||||
// TODO
|
// In Motif, no simple way to determine if the item is selected.
|
||||||
|
wxArrayInt theSelections;
|
||||||
|
int count = GetSelections (theSelections);
|
||||||
|
if (count == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < count; j++)
|
||||||
|
if (theSelections[j] == N)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Deselect(int N)
|
void wxListBox::Deselect(int N)
|
||||||
{
|
{
|
||||||
// TODO
|
XmListDeselectPos ((Widget) m_mainWidget, N + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *wxListBox::GetClientData(int N) const
|
char *wxListBox::GetClientData(int N) const
|
||||||
{
|
{
|
||||||
// TODO
|
wxNode *node = m_clientDataList.Find ((long) N);
|
||||||
return (char *)NULL;
|
if (node)
|
||||||
|
return (char *) node->Data ();
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::SetClientData(int N, char *Client_data)
|
void wxListBox::SetClientData(int N, char *Client_data)
|
||||||
{
|
{
|
||||||
// TODO
|
wxNode *node = m_clientDataList.Find ((long) N);
|
||||||
|
if (node)
|
||||||
|
node->SetData ((wxObject *)Client_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return number of selections and an array of selected integers
|
// Return number of selections and an array of selected integers
|
||||||
int wxListBox::GetSelections(wxArrayInt& aSelections) const
|
int wxListBox::GetSelections(wxArrayInt& aSelections) const
|
||||||
{
|
{
|
||||||
aSelections.Empty();
|
aSelections.Empty();
|
||||||
|
|
||||||
/* TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
|
int *posList = NULL;
|
||||||
{
|
int posCnt = 0;
|
||||||
int no_sel = ??
|
bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
|
||||||
for ( int n = 0; n < no_sel; n++ )
|
if (flag)
|
||||||
aSelections.Add(??);
|
{
|
||||||
|
if (posCnt > 0)
|
||||||
|
{
|
||||||
|
aSelections.Alloc(posCnt);
|
||||||
|
|
||||||
return no_sel;
|
int i;
|
||||||
|
for (i = 0; i < posCnt; i++)
|
||||||
|
aSelections.Add(posList[i] - 1);
|
||||||
|
|
||||||
|
XtFree ((char *) posList);
|
||||||
|
return posCnt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else // single-selection listbox
|
else
|
||||||
{
|
|
||||||
aSelections.Add(??);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get single selection, for single choice list items
|
// Get single selection, for single choice list items
|
||||||
int wxListBox::GetSelection() const
|
int wxListBox::GetSelection() const
|
||||||
{
|
{
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
return -1;
|
int *posList = NULL;
|
||||||
|
int posCnt = 0;
|
||||||
|
bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
int id = -1;
|
||||||
|
if (posCnt > 0)
|
||||||
|
id = posList[0] - 1;
|
||||||
|
XtFree ((char *) posList);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find string for position
|
// Find string for position
|
||||||
wxString wxListBox::GetString(int N) const
|
wxString wxListBox::GetString(int N) const
|
||||||
{
|
{
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
return wxString("");
|
XmString *strlist;
|
||||||
|
int n;
|
||||||
|
XtVaGetValues (listBox, XmNitemCount, &n, XmNitems, &strlist, NULL);
|
||||||
|
if (N <= n && N >= 0)
|
||||||
|
{
|
||||||
|
char *txt;
|
||||||
|
if (XmStringGetLtoR (strlist[N], XmSTRING_DEFAULT_CHARSET, &txt))
|
||||||
|
{
|
||||||
|
wxString str(txt);
|
||||||
|
XtFree (txt);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::SetSize(int x, int y, int width, int height, int sizeFlags)
|
void wxListBox::SetSize(int x, int y, int width, int height, int sizeFlags)
|
||||||
{
|
{
|
||||||
// TODO
|
wxWindow::SetSize(x, y, width, height, sizeFlags);
|
||||||
|
|
||||||
|
// Check resulting size is correct
|
||||||
|
int tempW, tempH;
|
||||||
|
GetSize (&tempW, &tempH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
|
void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
|
||||||
{
|
{
|
||||||
m_noItems += nItems;
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
// TODO
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
|
||||||
|
GetSize(&width1, &height1);
|
||||||
|
|
||||||
|
bool managed = XtIsManaged(listBox);
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtUnmanageChild(listBox);
|
||||||
|
|
||||||
|
XmString *text = new XmString[nItems];
|
||||||
|
int i;
|
||||||
|
// Steve Hammes: Motif 1.1 compatibility
|
||||||
|
// #if XmVersion > 1100
|
||||||
|
// Corrected by Sergey Krasnov from Steve Hammes' code
|
||||||
|
#if XmVersion > 1001
|
||||||
|
for (i = 0; i < nItems; i++)
|
||||||
|
text[i] = XmStringCreateSimple((char*) (const char*) items[i]);
|
||||||
|
XmListAddItemsUnselected(listBox, text, nItems, pos+1);
|
||||||
|
#else
|
||||||
|
for (i = 0; i < nItems; i++)
|
||||||
|
{
|
||||||
|
text[i] = XmStringCreateSimple((char*) (const char*) items[i]);
|
||||||
|
// XmListAddItemUnselected(listBox, text[i], i);
|
||||||
|
XmListAddItemUnselected(listBox, text[i], pos+i+1); // Another Sergey correction
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < nItems; i++)
|
||||||
|
XmStringFree(text[i]);
|
||||||
|
|
||||||
|
delete[] text;
|
||||||
|
|
||||||
|
// It seems that if the list is cleared, we must re-ask for
|
||||||
|
// selection policy!!
|
||||||
|
Arg args[3];
|
||||||
|
XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg(args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg(args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else XtSetArg(args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
XtSetValues(listBox,args,2) ;
|
||||||
|
|
||||||
|
if (managed)
|
||||||
|
XtManageChild(listBox);
|
||||||
|
|
||||||
|
GetSize(&width2, &height2);
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 /*|| height1 != height2*/)
|
||||||
|
SetSize(-1, -1, width1, height1);
|
||||||
|
|
||||||
|
m_noItems += nItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::SetString(int N, const wxString& s)
|
void wxListBox::SetString(int N, const wxString& s)
|
||||||
{
|
{
|
||||||
// TODO
|
int width1, height1;
|
||||||
|
int width2, height2;
|
||||||
|
|
||||||
|
Widget listBox = (Widget) m_mainWidget;
|
||||||
|
GetSize (&width1, &height1);
|
||||||
|
|
||||||
|
XmString text = XmStringCreateSimple ((char*) (const char*) s);
|
||||||
|
|
||||||
|
// WHAT'S THE MOTIF CALL TO SET THE TEXT OF AN EXISTING
|
||||||
|
// ITEM???
|
||||||
|
// There isn't one, so delete the item and add it again.
|
||||||
|
XmListDeletePos (listBox, N+1);
|
||||||
|
XmListAddItem (listBox, text, N+1);
|
||||||
|
|
||||||
|
XmStringFree(text);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// It seems that if the list is cleared, we must re-ask for
|
||||||
|
// selection policy!!
|
||||||
|
Arg args[3];
|
||||||
|
XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
|
||||||
|
if (m_windowStyle & wxLB_MULTIPLE)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
|
||||||
|
else if (m_windowStyle & wxLB_EXTENDED)
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
|
||||||
|
else
|
||||||
|
XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
|
||||||
|
XtSetValues (listBox, args, 2);
|
||||||
|
*/
|
||||||
|
|
||||||
|
GetSize (&width2, &height2);
|
||||||
|
// Correct for randomly resized listbox - bad boy, Motif!
|
||||||
|
if (width1 != width2 || height1 != height2)
|
||||||
|
SetSize (-1, -1, width1, height1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxListBox::Number () const
|
int wxListBox::Number () const
|
||||||
{
|
{
|
||||||
return m_noItems;
|
return m_noItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For single selection items only
|
// For single selection items only
|
||||||
wxString wxListBox::GetStringSelection () const
|
wxString wxListBox::GetStringSelection () const
|
||||||
{
|
{
|
||||||
int sel = GetSelection ();
|
int sel = GetSelection ();
|
||||||
if (sel > -1)
|
if (sel > -1)
|
||||||
return this->GetString (sel);
|
return this->GetString (sel);
|
||||||
else
|
else
|
||||||
return wxString("");
|
return wxString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxListBox::SetStringSelection (const wxString& s, bool flag)
|
bool wxListBox::SetStringSelection (const wxString& s, bool flag)
|
||||||
{
|
{
|
||||||
int sel = FindString (s);
|
int sel = FindString (s);
|
||||||
if (sel > -1)
|
if (sel > -1)
|
||||||
{
|
{
|
||||||
SetSelection (sel, flag);
|
SetSelection (sel, flag);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxListBox::Command (wxCommandEvent & event)
|
void wxListBox::Command (wxCommandEvent & event)
|
||||||
{
|
{
|
||||||
if (event.m_extraLong)
|
if (event.m_extraLong)
|
||||||
SetSelection (event.m_commandInt);
|
SetSelection (event.m_commandInt);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Deselect (event.m_commandInt);
|
Deselect (event.m_commandInt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProcessCommand (event);
|
ProcessCommand (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxListBoxCallback (Widget w, XtPointer clientData,
|
||||||
|
XmListCallbackStruct * cbs)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (cbs->reason == XmCR_EXTENDED_SELECT)
|
||||||
|
cout << "*** Extend select\n";
|
||||||
|
else if (cbs->reason == XmCR_SINGLE_SELECT)
|
||||||
|
cout << "*** Single select\n";
|
||||||
|
else if (cbs->reason == XmCR_MULTIPLE_SELECT)
|
||||||
|
cout << "*** Multiple select\n";
|
||||||
|
else if (cbs->reason == XmCR_BROWSE_SELECT)
|
||||||
|
cout << "*** Browse select\n";
|
||||||
|
|
||||||
|
if (cbs->selection_type == XmMODIFICATION)
|
||||||
|
cout << "*** Modification\n";
|
||||||
|
else if (cbs->selection_type == XmINITIAL)
|
||||||
|
cout << "*** Initial\n";
|
||||||
|
else if (cbs->selection_type == XmADDITION)
|
||||||
|
cout << "*** Addition\n";
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxListBox *item = (wxListBox *) clientData;
|
||||||
|
|
||||||
|
if (item->m_inSetValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxCommandEvent event (wxEVT_COMMAND_LISTBOX_SELECTED);
|
||||||
|
switch (cbs->reason)
|
||||||
|
{
|
||||||
|
case XmCR_MULTIPLE_SELECT:
|
||||||
|
case XmCR_BROWSE_SELECT:
|
||||||
|
{
|
||||||
|
event.m_clientData = item->GetClientData (cbs->item_position - 1);
|
||||||
|
//event.commandString = item->GetStringSelection();
|
||||||
|
event.m_commandInt = cbs->item_position - 1;
|
||||||
|
event.m_extraLong = TRUE;
|
||||||
|
event.SetEventObject(item);
|
||||||
|
item->ProcessCommand (event);
|
||||||
|
//delete[] event.commandString; // Let's not store the command string any more
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XmCR_EXTENDED_SELECT:
|
||||||
|
{
|
||||||
|
switch (cbs->selection_type)
|
||||||
|
{
|
||||||
|
case XmINITIAL:
|
||||||
|
case XmADDITION:
|
||||||
|
case XmMODIFICATION:
|
||||||
|
{
|
||||||
|
event.m_clientData = item->GetClientData (cbs->item_position - 1);
|
||||||
|
event.m_commandInt = cbs->item_position - 1;
|
||||||
|
event.m_extraLong = TRUE;
|
||||||
|
event.SetEventObject(item);
|
||||||
|
item->ProcessCommand (event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Respond by getting the
|
||||||
|
* designated "default button" in the action area and activate it
|
||||||
|
* as if the user had selected it.
|
||||||
|
*/
|
||||||
|
void wxListBoxDefaultActionProc (Widget list_w, XtPointer client_data, XmListCallbackStruct * cbs)
|
||||||
|
{
|
||||||
|
wxListBox *lbox = (wxListBox *) client_data;
|
||||||
|
|
||||||
|
wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, lbox->GetId());
|
||||||
|
event.SetEventObject( lbox );
|
||||||
|
lbox->GetEventHandler()->ProcessEvent(event) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,14 +9,46 @@
|
|||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Colour map
|
||||||
|
*
|
||||||
|
* When constructed with the default constructor, we start from
|
||||||
|
* the wxApp::GetMainColormap, allocating additional read-only cells
|
||||||
|
* in Create(). The cells are freed on the next call to Create()
|
||||||
|
* or when the destructor is called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Wolfram Gloger <u7y22ab@sunmail.lrz-muenchen.de>
|
||||||
|
I have implemented basic colormap support for the X11 versions of
|
||||||
|
wxWindows, notably wxPalette::Create(). The way I did it is to
|
||||||
|
allocate additional read-only color cells in the default colormap. In
|
||||||
|
general you will get arbitrary pixel values assigned to these new
|
||||||
|
cells and therefore I added a method wxColourMap::TransferBitmap()
|
||||||
|
which maps the pixel values 0..n to the real ones obtained with
|
||||||
|
Create(). This is only implemented for the popular case of 8-bit
|
||||||
|
depth.
|
||||||
|
|
||||||
|
Allocating read-write color cells would involve installing a private
|
||||||
|
X11 colormap for a particular window, and AFAIK this is not
|
||||||
|
recommended; only the window manager should do this... Also, it is
|
||||||
|
not the functionality that wxPalette::Create() aims to provide.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma implementation "palette.h"
|
#pragma implementation "palette.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/palette.h"
|
#include "wx/palette.h"
|
||||||
|
#include "wx/window.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARIES
|
#if !USE_SHARED_LIBRARIES
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxXPalette, wxObject)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -24,14 +56,54 @@ IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
wxXPalette::wxXPalette()
|
||||||
|
{
|
||||||
|
m_cmap = (WXColormap) 0;
|
||||||
|
m_pix_array_n = 0;
|
||||||
|
m_pix_array = (unsigned long*) 0;
|
||||||
|
m_display = (WXDisplay*) 0;
|
||||||
|
m_destroyable = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
wxPaletteRefData::wxPaletteRefData()
|
wxPaletteRefData::wxPaletteRefData()
|
||||||
{
|
{
|
||||||
m_colormap = (WXColormap) 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxPaletteRefData::~wxPaletteRefData()
|
wxPaletteRefData::~wxPaletteRefData()
|
||||||
{
|
{
|
||||||
// TODO
|
XColor xcol;
|
||||||
|
Display *display = (Display*) NULL;
|
||||||
|
|
||||||
|
wxNode *node, *next;
|
||||||
|
|
||||||
|
for (node = m_palettes.First(); node; node = next) {
|
||||||
|
wxXPalette *c = (wxXPalette *)node->Data();
|
||||||
|
unsigned long *pix_array = c->m_pix_array;
|
||||||
|
Colormap cmap = (Colormap) c->m_cmap;
|
||||||
|
bool destroyable = c->m_destroyable;
|
||||||
|
int pix_array_n = c->m_pix_array_n;
|
||||||
|
display = (Display*) c->m_display;
|
||||||
|
|
||||||
|
if (pix_array_n > 0)
|
||||||
|
{
|
||||||
|
// XFreeColors(display, cmap, pix_array, pix_array_n, 0);
|
||||||
|
// Be careful not to free '0' pixels...
|
||||||
|
int i, j;
|
||||||
|
for(i=j=0; i<pix_array_n; i=j) {
|
||||||
|
while(j<pix_array_n && pix_array[j]!=0) j++;
|
||||||
|
if(j > i) XFreeColors(display, cmap, &pix_array[i], j-i, 0);
|
||||||
|
while(j<pix_array_n && pix_array[j]==0) j++;
|
||||||
|
}
|
||||||
|
delete [] pix_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destroyable)
|
||||||
|
XFreeColormap(display, cmap);
|
||||||
|
|
||||||
|
next = node->Next();
|
||||||
|
m_palettes.DeleteNode(node);
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxPalette::wxPalette()
|
wxPalette::wxPalette()
|
||||||
@@ -51,17 +123,50 @@ bool wxPalette::Create(int n, const unsigned char *red, const unsigned char *gre
|
|||||||
{
|
{
|
||||||
UnRef();
|
UnRef();
|
||||||
|
|
||||||
|
if (!n) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
m_refData = new wxPaletteRefData;
|
m_refData = new wxPaletteRefData;
|
||||||
|
|
||||||
// TODO
|
XColor xcol;
|
||||||
|
Display* display = (Display*) wxGetDisplay();
|
||||||
|
|
||||||
return FALSE;
|
unsigned long *pix_array;
|
||||||
|
Colormap cmap;
|
||||||
|
int pix_array_n;
|
||||||
|
|
||||||
|
cmap = (Colormap) wxTheApp->GetMainColormap(display);
|
||||||
|
|
||||||
|
pix_array = new unsigned long[n];
|
||||||
|
if (!pix_array)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pix_array_n = n;
|
||||||
|
xcol.flags = DoRed | DoGreen | DoBlue;
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
xcol.red = (unsigned short)red[i] << 8;
|
||||||
|
xcol.green = (unsigned short)green[i] << 8;
|
||||||
|
xcol.blue = (unsigned short)blue[i] << 8;
|
||||||
|
pix_array[i] = (XAllocColor(display, cmap, &xcol) == 0) ? 0 : xcol.pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxXPalette *c = new wxXPalette;
|
||||||
|
|
||||||
|
c->m_pix_array_n = pix_array_n;
|
||||||
|
c->m_pix_array = pix_array;
|
||||||
|
c->m_cmap = (WXColormap) cmap;
|
||||||
|
c->m_display = (WXDisplay*) display;
|
||||||
|
c->m_destroyable = FALSE;
|
||||||
|
M_PALETTEDATA->m_palettes.Append(c);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxPalette::GetPixel(const unsigned char red, const unsigned char green, const unsigned char blue) const
|
int wxPalette::GetPixel(const unsigned char red, const unsigned char green, const unsigned char blue) const
|
||||||
{
|
{
|
||||||
if ( !m_refData )
|
if ( !m_refData )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -79,4 +184,170 @@ bool wxPalette::GetRGB(int index, unsigned char *red, unsigned char *green, unsi
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WXColormap wxPalette::GetXColormap(WXDisplay* display) const
|
||||||
|
{
|
||||||
|
if (!M_PALETTEDATA || (M_PALETTEDATA->m_palettes.Number() == 0))
|
||||||
|
return wxTheApp->GetMainColormap(display);
|
||||||
|
|
||||||
|
wxNode* node = M_PALETTEDATA->m_palettes.First();
|
||||||
|
if (!display && node)
|
||||||
|
{
|
||||||
|
wxXPalette* p = (wxXPalette*) node->Data();
|
||||||
|
return p->m_cmap;
|
||||||
|
}
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxXPalette* p = (wxXPalette*) node->Data();
|
||||||
|
if (p->m_display == display)
|
||||||
|
return p->m_cmap;
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make a new one: */
|
||||||
|
wxXPalette *c = new wxXPalette;
|
||||||
|
wxXPalette *first = (wxXPalette *)M_PALETTEDATA->m_palettes.First()->Data();
|
||||||
|
XColor xcol;
|
||||||
|
int pix_array_n = first->m_pix_array_n;
|
||||||
|
|
||||||
|
c->m_pix_array_n = pix_array_n;
|
||||||
|
c->m_pix_array = new unsigned long[pix_array_n];
|
||||||
|
c->m_display = display;
|
||||||
|
c->m_cmap = wxTheApp->GetMainColormap(display);
|
||||||
|
c->m_destroyable = FALSE;
|
||||||
|
|
||||||
|
xcol.flags = DoRed | DoGreen | DoBlue;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < pix_array_n; i++)
|
||||||
|
{
|
||||||
|
xcol.pixel = first->m_pix_array[i];
|
||||||
|
XQueryColor((Display*) first->m_display, (Colormap) first->m_cmap, &xcol);
|
||||||
|
c->m_pix_array[i] =
|
||||||
|
(XAllocColor((Display*) display, (Colormap) c->m_cmap, &xcol) == 0) ? 0 : xcol.pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wxPalette* nonConstThis = (wxPalette*) this;
|
||||||
|
|
||||||
|
M_PALETTEDATA->m_palettes.Append(c);
|
||||||
|
|
||||||
|
return c->m_cmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxPalette::TransferBitmap(void *data, int depth, int size)
|
||||||
|
{
|
||||||
|
switch(depth) {
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
unsigned char *uptr = (unsigned char *)data;
|
||||||
|
int pix_array_n;
|
||||||
|
unsigned long *pix_array = GetXPixArray((Display*) wxGetDisplay(), &pix_array_n);
|
||||||
|
while(size-- > 0)
|
||||||
|
{
|
||||||
|
if((int)*uptr < pix_array_n)
|
||||||
|
*uptr = (unsigned char)pix_array[*uptr];
|
||||||
|
uptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxPalette::TransferBitmap8(unsigned char *data, unsigned long sz,
|
||||||
|
void *dest, unsigned int bpp)
|
||||||
|
{
|
||||||
|
int pix_array_n;
|
||||||
|
unsigned long *pix_array = GetXPixArray((Display*) wxGetDisplay(), &pix_array_n);
|
||||||
|
switch(bpp) {
|
||||||
|
case 8: {
|
||||||
|
unsigned char *dptr = (unsigned char *)dest;
|
||||||
|
while(sz-- > 0) {
|
||||||
|
if((int)*data < pix_array_n)
|
||||||
|
*dptr = (unsigned char)pix_array[*data];
|
||||||
|
data++;
|
||||||
|
dptr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16: {
|
||||||
|
unsigned short *dptr = (unsigned short *)dest;
|
||||||
|
while(sz-- > 0) {
|
||||||
|
if((int)*data < pix_array_n)
|
||||||
|
*dptr = (unsigned short)pix_array[*data];
|
||||||
|
data++;
|
||||||
|
dptr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24: {
|
||||||
|
struct rgb24 { unsigned char r, g, b; } *dptr = (struct rgb24 *)dest;
|
||||||
|
while(sz-- > 0) {
|
||||||
|
if((int)*data < pix_array_n) {
|
||||||
|
dptr->r = pix_array[*data] & 0xFF;
|
||||||
|
dptr->g = (pix_array[*data] >> 8) & 0xFF;
|
||||||
|
dptr->b = (pix_array[*data] >> 16) & 0xFF;
|
||||||
|
}
|
||||||
|
data++;
|
||||||
|
dptr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 32: {
|
||||||
|
unsigned long *dptr = (unsigned long *)dest;
|
||||||
|
while(sz-- > 0) {
|
||||||
|
if((int)*data < pix_array_n)
|
||||||
|
*dptr = pix_array[*data];
|
||||||
|
data++;
|
||||||
|
dptr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long *wxPalette::GetXPixArray(WXDisplay *display, int *n)
|
||||||
|
{
|
||||||
|
if (!M_PALETTEDATA)
|
||||||
|
return (unsigned long*) 0;
|
||||||
|
wxNode *node;
|
||||||
|
|
||||||
|
for (node = M_PALETTEDATA->m_palettes.First(); node; node = node->Next())
|
||||||
|
{
|
||||||
|
wxXPalette *c = (wxXPalette *)node->Data();
|
||||||
|
if (c->m_display == display)
|
||||||
|
{
|
||||||
|
if (n)
|
||||||
|
*n = c->m_pix_array_n;
|
||||||
|
return c->m_pix_array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found; call GetXColormap, which will create it, then this again */
|
||||||
|
if (GetXColormap(display))
|
||||||
|
return GetXPixArray(display, n);
|
||||||
|
else
|
||||||
|
return (unsigned long*) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxPalette::PutXColormap(WXDisplay* display, WXColormap cm, bool dp)
|
||||||
|
{
|
||||||
|
UnRef();
|
||||||
|
|
||||||
|
m_refData = new wxPaletteRefData;
|
||||||
|
|
||||||
|
wxXPalette *c = new wxXPalette;
|
||||||
|
|
||||||
|
c->m_pix_array_n = 0;
|
||||||
|
c->m_pix_array = (unsigned long*) NULL;
|
||||||
|
c->m_display = display;
|
||||||
|
c->m_cmap = cm;
|
||||||
|
c->m_destroyable = dp;
|
||||||
|
|
||||||
|
M_PALETTEDATA->m_palettes.Append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// File: region.cpp
|
// File: region.cpp
|
||||||
// Purpose: Region class
|
// Purpose: Region class
|
||||||
// Author: Markus Holzem/Julian Smart/Julian Smart
|
// Author: Markus Holzem/Julian Smart
|
||||||
// Created: Fri Oct 24 10:46:34 MET 1997
|
// Created: Fri Oct 24 10:46:34 MET 1997
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 1997 Markus Holzem/Julian Smart/Julian Smart
|
// Copyright: (c) 1997 Markus Holzem/Julian Smart
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
#include "wx/region.h"
|
#include "wx/region.h"
|
||||||
#include "wx/gdicmn.h"
|
#include "wx/gdicmn.h"
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
// #include "wx/motif/private.h"
|
||||||
|
|
||||||
#if !USE_SHARED_LIBRARY
|
#if !USE_SHARED_LIBRARY
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
|
||||||
@@ -28,19 +31,23 @@ class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
|
|||||||
public:
|
public:
|
||||||
wxRegionRefData()
|
wxRegionRefData()
|
||||||
{
|
{
|
||||||
|
m_region = XCreateRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRegionRefData(const wxRegionRefData& data)
|
wxRegionRefData(const wxRegionRefData& data)
|
||||||
{
|
{
|
||||||
// TODO
|
m_region = XCreateRegion();
|
||||||
|
XUnionRegion(m_region, data.m_region, m_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
~wxRegionRefData()
|
~wxRegionRefData()
|
||||||
{
|
{
|
||||||
// TODO
|
XDestroyRegion(m_region);
|
||||||
}
|
}
|
||||||
|
Region m_region;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define M_REGION (((wxRegionRefData*)m_refData)->m_region)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxRegion
|
// wxRegion
|
||||||
@@ -51,26 +58,42 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxRegion::wxRegion()
|
wxRegion::wxRegion()
|
||||||
{
|
{
|
||||||
m_refData = new wxRegionRefData;
|
|
||||||
// TODO create empty region
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRegion::wxRegion(long x, long y, long w, long h)
|
wxRegion::wxRegion(long x, long y, long w, long h)
|
||||||
{
|
{
|
||||||
m_refData = new wxRegionRefData;
|
m_refData = new wxRegionRefData;
|
||||||
// TODO create rect region
|
|
||||||
|
XRectangle rect;
|
||||||
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = w;
|
||||||
|
rect.height = h;
|
||||||
|
XUnionRectWithRegion(&rect, M_REGION, M_REGION);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
|
wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
|
||||||
{
|
{
|
||||||
m_refData = new wxRegionRefData;
|
m_refData = new wxRegionRefData;
|
||||||
// TODO create rect region
|
|
||||||
|
XRectangle rect;
|
||||||
|
rect.x = topLeft.x;
|
||||||
|
rect.y = topLeft.y;
|
||||||
|
rect.width = bottomRight.x - topLeft.x;
|
||||||
|
rect.height = bottomRight.y - topLeft.y;
|
||||||
|
XUnionRectWithRegion(&rect, M_REGION, M_REGION);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRegion::wxRegion(const wxRect& rect)
|
wxRegion::wxRegion(const wxRect& rect)
|
||||||
{
|
{
|
||||||
m_refData = new wxRegionRefData;
|
m_refData = new wxRegionRefData;
|
||||||
// TODO create rect region
|
|
||||||
|
XRectangle rect1;
|
||||||
|
rect1.x = rect.x;
|
||||||
|
rect1.y = rect.y;
|
||||||
|
rect1.width = rect.width;
|
||||||
|
rect1.height = rect.height;
|
||||||
|
XUnionRectWithRegion(&rect1, M_REGION, M_REGION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -104,16 +127,23 @@ bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
|
|||||||
}
|
}
|
||||||
// If ref count is 1, that means it's 'ours' anyway so no action.
|
// If ref count is 1, that means it's 'ours' anyway so no action.
|
||||||
|
|
||||||
// TODO create rect region
|
Region rectRegion = XCreateRegion();
|
||||||
|
|
||||||
|
XRectangle rect;
|
||||||
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = width;
|
||||||
|
rect.height = height;
|
||||||
|
XUnionRectWithRegion(&rect, rectRegion, rectRegion);
|
||||||
|
|
||||||
int mode = 0; // TODO platform-specific code
|
int mode = 0; // TODO platform-specific code
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case wxRGN_AND:
|
case wxRGN_AND:
|
||||||
// TODO
|
XIntersectRegion(M_REGION, rectRegion, M_REGION);
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_OR:
|
case wxRGN_OR:
|
||||||
// TODO
|
XUnionRegion(M_REGION, rectRegion, M_REGION);
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_XOR:
|
case wxRGN_XOR:
|
||||||
// TODO
|
// TODO
|
||||||
@@ -121,14 +151,12 @@ bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
|
|||||||
case wxRGN_DIFF:
|
case wxRGN_DIFF:
|
||||||
// TODO
|
// TODO
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_COPY:
|
case wxRGN_COPY: // Don't have to do this one
|
||||||
default:
|
default:
|
||||||
// TODO
|
// TODO
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO do combine region
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,10 +179,12 @@ bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
|
|||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case wxRGN_AND:
|
case wxRGN_AND:
|
||||||
// TODO
|
XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
|
||||||
|
M_REGION);
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_OR:
|
case wxRGN_OR:
|
||||||
// TODO
|
XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region,
|
||||||
|
M_REGION);
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_XOR:
|
case wxRGN_XOR:
|
||||||
// TODO
|
// TODO
|
||||||
@@ -162,7 +192,7 @@ bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
|
|||||||
case wxRGN_DIFF:
|
case wxRGN_DIFF:
|
||||||
// TODO
|
// TODO
|
||||||
break ;
|
break ;
|
||||||
case wxRGN_COPY:
|
case wxRGN_COPY: // Don't have to do this one
|
||||||
default:
|
default:
|
||||||
// TODO
|
// TODO
|
||||||
break ;
|
break ;
|
||||||
@@ -186,7 +216,12 @@ bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
|
|||||||
void wxRegion::GetBox(long& x, long& y, long&w, long &h) const
|
void wxRegion::GetBox(long& x, long& y, long&w, long &h) const
|
||||||
{
|
{
|
||||||
if (m_refData) {
|
if (m_refData) {
|
||||||
// TODO get box
|
XRectangle rect;
|
||||||
|
XClipBox(M_REGION, &rect);
|
||||||
|
x = rect.x;
|
||||||
|
y = rect.y;
|
||||||
|
w = rect.width;
|
||||||
|
h = rect.height;
|
||||||
} else {
|
} else {
|
||||||
x = y = w = h = 0;
|
x = y = w = h = 0;
|
||||||
}
|
}
|
||||||
@@ -202,8 +237,7 @@ wxRect wxRegion::GetBox() const
|
|||||||
// Is region empty?
|
// Is region empty?
|
||||||
bool wxRegion::Empty() const
|
bool wxRegion::Empty() const
|
||||||
{
|
{
|
||||||
// TODO
|
return m_refData ? XEmptyRegion(M_REGION) : FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -228,11 +262,7 @@ wxRegionContain wxRegion::Contains(const wxPoint& pt) const
|
|||||||
if (!m_refData)
|
if (!m_refData)
|
||||||
return wxOutRegion;
|
return wxOutRegion;
|
||||||
|
|
||||||
// TODO. Return wxInRegion if within region.
|
return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion;
|
||||||
if (0)
|
|
||||||
return wxInRegion;
|
|
||||||
else
|
|
||||||
return wxOutRegion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the region contain the rectangle (x, y, w, h)?
|
// Does the region contain the rectangle (x, y, w, h)?
|
||||||
@@ -241,11 +271,11 @@ wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
|
|||||||
if (!m_refData)
|
if (!m_refData)
|
||||||
return wxOutRegion;
|
return wxOutRegion;
|
||||||
|
|
||||||
// TODO. Return wxInRegion if within region.
|
switch (XRectInRegion(M_REGION, x, y, w, h)) {
|
||||||
if (0)
|
case RectangleIn: return wxInRegion;
|
||||||
return wxInRegion;
|
case RectanglePart: return wxPartRegion;
|
||||||
else
|
}
|
||||||
return wxOutRegion;
|
return wxOutRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the region contain the rectangle rect
|
// Does the region contain the rectangle rect
|
||||||
|
@@ -138,61 +138,61 @@ wxWindow::wxWindow()
|
|||||||
// Destructor
|
// Destructor
|
||||||
wxWindow::~wxWindow()
|
wxWindow::~wxWindow()
|
||||||
{
|
{
|
||||||
//// Motif-specific
|
//// Motif-specific
|
||||||
|
|
||||||
if (m_paintRegion)
|
if (m_paintRegion)
|
||||||
XDestroyRegion ((Region) m_paintRegion);
|
XDestroyRegion ((Region) m_paintRegion);
|
||||||
m_paintRegion = (WXRegion) 0;
|
m_paintRegion = (WXRegion) 0;
|
||||||
|
|
||||||
if (GetMainWidget())
|
if (GetMainWidget())
|
||||||
DetachWidget(GetMainWidget()); // Removes event handlers
|
DetachWidget(GetMainWidget()); // Removes event handlers
|
||||||
|
|
||||||
// If m_drawingArea, we're a fully-fledged window with drawing area, scrollbars etc. (what wxCanvas used to be)
|
// If m_drawingArea, we're a fully-fledged window with drawing area, scrollbars etc. (what wxCanvas used to be)
|
||||||
if (m_drawingArea)
|
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);
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_hScrollBar)
|
//// Generic stuff
|
||||||
{
|
|
||||||
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
|
||||||
@@ -958,9 +958,13 @@ void wxWindow::SetFont(const wxFont& font)
|
|||||||
{
|
{
|
||||||
m_windowFont = font;
|
m_windowFont = font;
|
||||||
|
|
||||||
if (!m_windowFont.Ok())
|
Widget w = (Widget) GetMainWidget();
|
||||||
return;
|
if (w && m_windowFont.Ok())
|
||||||
// TODO
|
{
|
||||||
|
XtVaSetValues (w,
|
||||||
|
XmNfontList, (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay(w)),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWindow::OnChar(wxKeyEvent& event)
|
void wxWindow::OnChar(wxKeyEvent& event)
|
||||||
|
@@ -48,10 +48,14 @@ PERIPH_TARGET=xpm $(PERIPH_TARGET)
|
|||||||
PERIPH_CLEAN_TARGET=clean_xpm $(PERIPH_CLEAN_TARGET)
|
PERIPH_CLEAN_TARGET=clean_xpm $(PERIPH_CLEAN_TARGET)
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
GENDIR=..\generic
|
# These are absolute paths, so that the compiler
|
||||||
COMMDIR=..\common
|
# generates correct __FILE__ symbols for debugging.
|
||||||
|
# Otherwise you don't be able to double-click on a memory
|
||||||
|
# error to load that file.
|
||||||
|
GENDIR=$(WXDIR)\src\generic
|
||||||
|
COMMDIR=$(WXDIR)\src\common
|
||||||
OLEDIR=ole
|
OLEDIR=ole
|
||||||
MSWDIR=.
|
MSWDIR=$(WXDIR)\src\msw
|
||||||
|
|
||||||
DOCDIR = $(WXDIR)\docs
|
DOCDIR = $(WXDIR)\docs
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
/////// Non-Windows 95 implementation
|
/////// Non-Windows 95 implementation
|
||||||
|
|
||||||
#if !USE_IMAGE_LOADING_IN_MSW
|
#if !wxUSE_IMAGE_LOADING_IN_MSW
|
||||||
#error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too.
|
#error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if USE_SPLINES
|
#if wxUSE_SPLINES
|
||||||
|
|
||||||
////#define wx_round(a) (int)((a)+.5)
|
////#define wx_round(a) (int)((a)+.5)
|
||||||
//#define wx_round(a) (a)
|
//#define wx_round(a) (a)
|
||||||
@@ -37,7 +37,7 @@ class wxSpline: public wxObject
|
|||||||
|
|
||||||
void wx_draw_open_spline(wxDC *dc, wxSpline *spline);
|
void wx_draw_open_spline(wxDC *dc, wxSpline *spline);
|
||||||
|
|
||||||
#if USE_POSTSCRIPT
|
#if wxUSE_POSTSCRIPT
|
||||||
void wx_draw_open_spline_ps(wxPostScriptDC *dc, wxSpline *s);
|
void wx_draw_open_spline_ps(wxPostScriptDC *dc, wxSpline *s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ void wx_draw_open_spline(wxDC *dc, wxSpline *spline)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_POSTSCRIPT
|
#if wxUSE_POSTSCRIPT
|
||||||
void wx_draw_open_spline_ps(wxPostScriptDC *dc, wxSpline *s)
|
void wx_draw_open_spline_ps(wxPostScriptDC *dc, wxSpline *s)
|
||||||
{
|
{
|
||||||
double a, b, c, d, x1, y1, x2, y2, x3, y3;
|
double a, b, c, d, x1, y1, x2, y2, x3, y3;
|
||||||
@@ -307,7 +307,7 @@ void wxSpline::DeletePoints(void)
|
|||||||
delete points;
|
delete points;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_POSTSCRIPT
|
#if wxUSE_POSTSCRIPT
|
||||||
|
|
||||||
// Make a 3-point spline
|
// Make a 3-point spline
|
||||||
void wxPostScriptDC::DrawSpline(long x1, long y1, long x2, long y2, long x3, long y3)
|
void wxPostScriptDC::DrawSpline(long x1, long y1, long x2, long y2, long x3, long y3)
|
||||||
@@ -349,7 +349,7 @@ void wxPostScriptDC::DrawSpline(int n, wxPoint points[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // USE_POSTSCRIPT
|
#endif // wxUSE_POSTSCRIPT
|
||||||
|
|
||||||
#endif // USE_SPLINES
|
#endif // wxUSE_SPLINES
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ wxCursor::wxCursor(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSE
|
|||||||
|
|
||||||
wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
|
wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
|
||||||
{
|
{
|
||||||
m_refData = new wxIconRefData;
|
m_refData = new wxCursorRefData;
|
||||||
|
|
||||||
// TODO: create cursor from a file
|
// TODO: create cursor from a file
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho
|
|||||||
// Cursors by stock number
|
// Cursors by stock number
|
||||||
wxCursor::wxCursor(int cursor_type)
|
wxCursor::wxCursor(int cursor_type)
|
||||||
{
|
{
|
||||||
m_refData = new wxIconRefData;
|
m_refData = new wxCursorRefData;
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
switch (cursor_type)
|
switch (cursor_type)
|
||||||
|
@@ -127,6 +127,12 @@ void wxShapeEvtHandler::OnDrawContents(wxDC& dc)
|
|||||||
m_previousHandler->OnDrawContents(dc);
|
m_previousHandler->OnDrawContents(dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxShapeEvtHandler::OnDrawBranches(wxDC& dc, bool erase)
|
||||||
|
{
|
||||||
|
if (m_previousHandler)
|
||||||
|
m_previousHandler->OnDrawBranches(dc, erase);
|
||||||
|
}
|
||||||
|
|
||||||
void wxShapeEvtHandler::OnSize(double x, double y)
|
void wxShapeEvtHandler::OnSize(double x, double y)
|
||||||
{
|
{
|
||||||
if (m_previousHandler)
|
if (m_previousHandler)
|
||||||
@@ -276,7 +282,7 @@ wxShape::wxShape(wxShapeCanvas *can)
|
|||||||
m_visible = FALSE;
|
m_visible = FALSE;
|
||||||
m_clientData = NULL;
|
m_clientData = NULL;
|
||||||
m_selected = FALSE;
|
m_selected = FALSE;
|
||||||
m_attachmentMode = FALSE;
|
m_attachmentMode = ATTACHMENT_MODE_NONE;
|
||||||
m_spaceAttachments = TRUE;
|
m_spaceAttachments = TRUE;
|
||||||
m_disableLabel = FALSE;
|
m_disableLabel = FALSE;
|
||||||
m_fixedWidth = FALSE;
|
m_fixedWidth = FALSE;
|
||||||
@@ -297,6 +303,10 @@ wxShape::wxShape(wxShapeCanvas *can)
|
|||||||
m_maintainAspectRatio = FALSE;
|
m_maintainAspectRatio = FALSE;
|
||||||
m_highlighted = FALSE;
|
m_highlighted = FALSE;
|
||||||
m_rotation = 0.0;
|
m_rotation = 0.0;
|
||||||
|
m_branchNeckLength = 10;
|
||||||
|
m_branchStemLength = 10;
|
||||||
|
m_branchSpacing = 10;
|
||||||
|
m_branchStyle = BRANCHING_ATTACHMENT_NORMAL;
|
||||||
|
|
||||||
// Set up a default region. Much of the above will be put into
|
// Set up a default region. Much of the above will be put into
|
||||||
// the region eventually (the duplication is for compatibility)
|
// the region eventually (the duplication is for compatibility)
|
||||||
@@ -541,7 +551,6 @@ bool wxShape::HitTest(double x, double y, int *attachment, double *distance)
|
|||||||
|
|
||||||
int nearest_attachment = 0;
|
int nearest_attachment = 0;
|
||||||
|
|
||||||
|
|
||||||
// If within the bounding box, check the attachment points
|
// If within the bounding box, check the attachment points
|
||||||
// within the object.
|
// within the object.
|
||||||
|
|
||||||
@@ -550,10 +559,13 @@ bool wxShape::HitTest(double x, double y, int *attachment, double *distance)
|
|||||||
int n = GetNumberOfAttachments();
|
int n = GetNumberOfAttachments();
|
||||||
double nearest = 999999.0;
|
double nearest = 999999.0;
|
||||||
|
|
||||||
|
// GetAttachmentPosition[Edge] takes a logical attachment position,
|
||||||
|
// i.e. if it's rotated through 90%, position 0 is East-facing.
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
double xp, yp;
|
double xp, yp;
|
||||||
if (GetAttachmentPosition(i, &xp, &yp))
|
if (GetAttachmentPositionEdge(i, &xp, &yp))
|
||||||
{
|
{
|
||||||
double l = (double)sqrt(((xp - x) * (xp - x)) +
|
double l = (double)sqrt(((xp - x) * (xp - x)) +
|
||||||
((yp - y) * (yp - y)));
|
((yp - y) * (yp - y)));
|
||||||
@@ -1038,7 +1050,8 @@ void wxShape::DrawLinks(wxDC& dc, int attachment, bool recurse)
|
|||||||
// This is the default, rectangular implementation.
|
// This is the default, rectangular implementation.
|
||||||
bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint& pt1, const wxRealPoint& pt2)
|
bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint& pt1, const wxRealPoint& pt2)
|
||||||
{
|
{
|
||||||
switch (attachmentPoint)
|
int physicalAttachment = LogicalToPhysicalAttachment(attachmentPoint);
|
||||||
|
switch (physicalAttachment)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
@@ -1060,7 +1073,7 @@ bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint& pt1, co
|
|||||||
bool wxShape::MoveLineToNewAttachment(wxDC& dc, wxLineShape *to_move,
|
bool wxShape::MoveLineToNewAttachment(wxDC& dc, wxLineShape *to_move,
|
||||||
double x, double y)
|
double x, double y)
|
||||||
{
|
{
|
||||||
if (!GetAttachmentMode())
|
if (GetAttachmentMode() == ATTACHMENT_MODE_NONE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
int newAttachment, oldAttachment;
|
int newAttachment, oldAttachment;
|
||||||
@@ -1502,6 +1515,7 @@ void wxShape::Draw(wxDC& dc)
|
|||||||
GetEventHandler()->OnDraw(dc);
|
GetEventHandler()->OnDraw(dc);
|
||||||
GetEventHandler()->OnDrawContents(dc);
|
GetEventHandler()->OnDrawContents(dc);
|
||||||
GetEventHandler()->OnDrawControlPoints(dc);
|
GetEventHandler()->OnDrawControlPoints(dc);
|
||||||
|
GetEventHandler()->OnDrawBranches(dc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1535,6 +1549,7 @@ void wxShape::Erase(wxDC& dc)
|
|||||||
{
|
{
|
||||||
GetEventHandler()->OnErase(dc);
|
GetEventHandler()->OnErase(dc);
|
||||||
GetEventHandler()->OnEraseControlPoints(dc);
|
GetEventHandler()->OnEraseControlPoints(dc);
|
||||||
|
GetEventHandler()->OnDrawBranches(dc, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxShape::EraseContents(wxDC& dc)
|
void wxShape::EraseContents(wxDC& dc)
|
||||||
@@ -1758,6 +1773,14 @@ void wxShape::WriteAttributes(wxExpr *clause)
|
|||||||
if (m_rotation != 0.0)
|
if (m_rotation != 0.0)
|
||||||
clause->AddAttributeValue("rotation", m_rotation);
|
clause->AddAttributeValue("rotation", m_rotation);
|
||||||
|
|
||||||
|
if (!this->IsKindOf(CLASSINFO(wxLineShape)))
|
||||||
|
{
|
||||||
|
clause->AddAttributeValue("neck_length", (long) m_branchNeckLength);
|
||||||
|
clause->AddAttributeValue("stem_length", (long) m_branchStemLength);
|
||||||
|
clause->AddAttributeValue("branch_spacing", (long) m_branchSpacing);
|
||||||
|
clause->AddAttributeValue("branch_style", (long) m_branchStyle);
|
||||||
|
}
|
||||||
|
|
||||||
// Write user-defined attachment points, if any
|
// Write user-defined attachment points, if any
|
||||||
if (m_attachmentPoints.Number() > 0)
|
if (m_attachmentPoints.Number() > 0)
|
||||||
{
|
{
|
||||||
@@ -1912,7 +1935,7 @@ void wxShape::ReadAttributes(wxExpr *clause)
|
|||||||
int pen_width = 1;
|
int pen_width = 1;
|
||||||
int pen_style = wxSOLID;
|
int pen_style = wxSOLID;
|
||||||
int brush_style = wxSOLID;
|
int brush_style = wxSOLID;
|
||||||
m_attachmentMode = FALSE;
|
m_attachmentMode = ATTACHMENT_MODE_NONE;
|
||||||
|
|
||||||
clause->GetAttributeValue("pen_colour", pen_string);
|
clause->GetAttributeValue("pen_colour", pen_string);
|
||||||
clause->GetAttributeValue("text_colour", m_textColourName);
|
clause->GetAttributeValue("text_colour", m_textColourName);
|
||||||
@@ -1928,7 +1951,7 @@ void wxShape::ReadAttributes(wxExpr *clause)
|
|||||||
|
|
||||||
int iVal = (int) m_attachmentMode;
|
int iVal = (int) m_attachmentMode;
|
||||||
clause->GetAttributeValue("use_attachments", iVal);
|
clause->GetAttributeValue("use_attachments", iVal);
|
||||||
m_attachmentMode = (iVal != 0);
|
m_attachmentMode = iVal;
|
||||||
|
|
||||||
clause->GetAttributeValue("sensitivity", m_sensitivity);
|
clause->GetAttributeValue("sensitivity", m_sensitivity);
|
||||||
|
|
||||||
@@ -1947,6 +1970,20 @@ void wxShape::ReadAttributes(wxExpr *clause)
|
|||||||
clause->GetAttributeValue("format_mode", m_formatMode);
|
clause->GetAttributeValue("format_mode", m_formatMode);
|
||||||
clause->GetAttributeValue("shadow_mode", m_shadowMode);
|
clause->GetAttributeValue("shadow_mode", m_shadowMode);
|
||||||
|
|
||||||
|
iVal = m_branchNeckLength;
|
||||||
|
clause->GetAttributeValue("neck_length", iVal);
|
||||||
|
m_branchNeckLength = iVal;
|
||||||
|
|
||||||
|
iVal = m_branchStemLength;
|
||||||
|
clause->GetAttributeValue("stem_length", iVal);
|
||||||
|
m_branchStemLength = iVal;
|
||||||
|
|
||||||
|
iVal = m_branchSpacing;
|
||||||
|
clause->GetAttributeValue("branch_spacing", iVal);
|
||||||
|
m_branchSpacing = iVal;
|
||||||
|
|
||||||
|
clause->GetAttributeValue("branch_style", m_branchStyle);
|
||||||
|
|
||||||
iVal = (int) m_centreResize;
|
iVal = (int) m_centreResize;
|
||||||
clause->GetAttributeValue("centre_resize", iVal);
|
clause->GetAttributeValue("centre_resize", iVal);
|
||||||
m_centreResize = (iVal != 0);
|
m_centreResize = (iVal != 0);
|
||||||
@@ -2251,6 +2288,10 @@ void wxShape::Copy(wxShape& copy)
|
|||||||
copy.m_shadowOffsetY = m_shadowOffsetY;
|
copy.m_shadowOffsetY = m_shadowOffsetY;
|
||||||
copy.m_shadowBrush = m_shadowBrush;
|
copy.m_shadowBrush = m_shadowBrush;
|
||||||
|
|
||||||
|
copy.m_branchNeckLength = m_branchNeckLength;
|
||||||
|
copy.m_branchStemLength = m_branchStemLength;
|
||||||
|
copy.m_branchSpacing = m_branchSpacing;
|
||||||
|
|
||||||
// Copy text regions
|
// Copy text regions
|
||||||
copy.ClearRegions();
|
copy.ClearRegions();
|
||||||
wxNode *node = m_regions.First();
|
wxNode *node = m_regions.First();
|
||||||
@@ -2631,12 +2672,20 @@ bool wxShape::AttachmentIsValid(int attachment) const
|
|||||||
bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
||||||
int nth, int no_arcs, wxLineShape *line)
|
int nth, int no_arcs, wxLineShape *line)
|
||||||
{
|
{
|
||||||
if (!m_attachmentMode)
|
if (m_attachmentMode == ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
*x = m_xpos; *y = m_ypos;
|
*x = m_xpos; *y = m_ypos;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
|
||||||
|
{
|
||||||
|
wxRealPoint pt, stemPt;
|
||||||
|
GetBranchingAttachmentPoint(attachment, nth, pt, stemPt);
|
||||||
|
*x = pt.x;
|
||||||
|
*y = pt.y;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (m_attachmentMode == ATTACHMENT_MODE_EDGE)
|
||||||
{
|
{
|
||||||
if (m_attachmentPoints.Number() > 0)
|
if (m_attachmentPoints.Number() > 0)
|
||||||
{
|
{
|
||||||
@@ -2667,8 +2716,10 @@ bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
|||||||
|
|
||||||
bool isEnd = (line && line->IsEnd(this));
|
bool isEnd = (line && line->IsEnd(this));
|
||||||
|
|
||||||
|
int physicalAttachment = LogicalToPhysicalAttachment(attachment);
|
||||||
|
|
||||||
// Simplified code
|
// Simplified code
|
||||||
switch (attachment)
|
switch (physicalAttachment)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
@@ -2704,7 +2755,7 @@ bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2855,3 +2906,365 @@ int wxShape::GetLinePosition(wxLineShape* line)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// |________|
|
||||||
|
// | <- root
|
||||||
|
// | <- neck
|
||||||
|
// shoulder1 ->---------<- shoulder2
|
||||||
|
// | | | | |
|
||||||
|
// <- branching attachment point N-1
|
||||||
|
|
||||||
|
// This function gets information about where branching connections go.
|
||||||
|
// Returns FALSE if there are no lines at this attachment.
|
||||||
|
bool wxShape::GetBranchingAttachmentInfo(int attachment, wxRealPoint& root, wxRealPoint& neck,
|
||||||
|
wxRealPoint& shoulder1, wxRealPoint& shoulder2)
|
||||||
|
{
|
||||||
|
int physicalAttachment = LogicalToPhysicalAttachment(attachment);
|
||||||
|
|
||||||
|
// Number of lines at this attachment.
|
||||||
|
int lineCount = GetAttachmentLineCount(attachment);
|
||||||
|
|
||||||
|
if (lineCount == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
int totalBranchLength = m_branchSpacing * (lineCount - 1);
|
||||||
|
|
||||||
|
root = GetBranchingAttachmentRoot(attachment);
|
||||||
|
|
||||||
|
// Assume that we have attachment points 0 to 3: top, right, bottom, left.
|
||||||
|
switch (physicalAttachment)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
neck.x = GetX();
|
||||||
|
neck.y = root.y - m_branchNeckLength;
|
||||||
|
|
||||||
|
shoulder1.x = root.x - (totalBranchLength/2.0) ;
|
||||||
|
shoulder2.x = root.x + (totalBranchLength/2.0) ;
|
||||||
|
|
||||||
|
shoulder1.y = neck.y;
|
||||||
|
shoulder2.y = neck.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
neck.x = root.x + m_branchNeckLength;
|
||||||
|
neck.y = root.y;
|
||||||
|
|
||||||
|
shoulder1.x = neck.x ;
|
||||||
|
shoulder2.x = neck.x ;
|
||||||
|
|
||||||
|
shoulder1.y = neck.y - (totalBranchLength/2.0) ;
|
||||||
|
shoulder2.y = neck.y + (totalBranchLength/2.0) ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
neck.x = GetX();
|
||||||
|
neck.y = root.y + m_branchNeckLength;
|
||||||
|
|
||||||
|
shoulder1.x = root.x - (totalBranchLength/2.0) ;
|
||||||
|
shoulder2.x = root.x + (totalBranchLength/2.0) ;
|
||||||
|
|
||||||
|
shoulder1.y = neck.y;
|
||||||
|
shoulder2.y = neck.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
neck.x = root.x - m_branchNeckLength;
|
||||||
|
neck.y = root.y ;
|
||||||
|
|
||||||
|
shoulder1.x = neck.x ;
|
||||||
|
shoulder2.x = neck.x ;
|
||||||
|
|
||||||
|
shoulder1.y = neck.y - (totalBranchLength/2.0) ;
|
||||||
|
shoulder2.y = neck.y + (totalBranchLength/2.0) ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentInfo." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// n is the number of the adjoining line, from 0 to N-1 where N is the number of lines
|
||||||
|
// at this attachment point.
|
||||||
|
// Get the attachment point where the arc joins the stem, and also the point where the
|
||||||
|
// the stem meets the shoulder.
|
||||||
|
bool wxShape::GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint& pt, wxRealPoint& stemPt)
|
||||||
|
{
|
||||||
|
int physicalAttachment = LogicalToPhysicalAttachment(attachment);
|
||||||
|
|
||||||
|
wxRealPoint root, neck, shoulder1, shoulder2;
|
||||||
|
GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2);
|
||||||
|
|
||||||
|
// Assume that we have attachment points 0 to 3: top, right, bottom, left.
|
||||||
|
switch (physicalAttachment)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
pt.y = neck.y - m_branchStemLength;
|
||||||
|
pt.x = shoulder1.x + n*m_branchSpacing;
|
||||||
|
|
||||||
|
stemPt.x = pt.x;
|
||||||
|
stemPt.y = neck.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
pt.y = neck.y + m_branchStemLength;
|
||||||
|
pt.x = shoulder1.x + n*m_branchSpacing;
|
||||||
|
|
||||||
|
stemPt.x = pt.x;
|
||||||
|
stemPt.y = neck.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
pt.x = neck.x + m_branchStemLength;
|
||||||
|
pt.y = shoulder1.y + n*m_branchSpacing;
|
||||||
|
|
||||||
|
stemPt.x = neck.x;
|
||||||
|
stemPt.y = pt.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
pt.x = neck.x - m_branchStemLength;
|
||||||
|
pt.y = shoulder1.y + n*m_branchSpacing;
|
||||||
|
|
||||||
|
stemPt.x = neck.x;
|
||||||
|
stemPt.y = pt.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentPoint." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of lines at this attachment position.
|
||||||
|
int wxShape::GetAttachmentLineCount(int attachment) const
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
wxNode* node = m_lines.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxLineShape* lineShape = (wxLineShape*) node->Data();
|
||||||
|
if ((lineShape->GetFrom() == this) && (lineShape->GetAttachmentFrom() == attachment))
|
||||||
|
count ++;
|
||||||
|
else if ((lineShape->GetTo() == this) && (lineShape->GetAttachmentTo() == attachment))
|
||||||
|
count ++;
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function gets the root point at the given attachment.
|
||||||
|
wxRealPoint wxShape::GetBranchingAttachmentRoot(int attachment)
|
||||||
|
{
|
||||||
|
int physicalAttachment = LogicalToPhysicalAttachment(attachment);
|
||||||
|
|
||||||
|
wxRealPoint root;
|
||||||
|
|
||||||
|
double width, height;
|
||||||
|
GetBoundingBoxMax(& width, & height);
|
||||||
|
|
||||||
|
// Assume that we have attachment points 0 to 3: top, right, bottom, left.
|
||||||
|
switch (physicalAttachment)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
root.x = GetX() ;
|
||||||
|
root.y = GetY() - height/2.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
root.x = GetX() + width/2.0;
|
||||||
|
root.y = GetY() ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
root.x = GetX() ;
|
||||||
|
root.y = GetY() + height/2.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
root.x = GetX() - width/2.0;
|
||||||
|
root.y = GetY() ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( "Unrecognised attachment point in GetBranchingAttachmentRoot." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw or erase the branches (not the actual arcs though)
|
||||||
|
void wxShape::OnDrawBranches(wxDC& dc, int attachment, bool erase)
|
||||||
|
{
|
||||||
|
int count = GetAttachmentLineCount(attachment);
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxRealPoint root, neck, shoulder1, shoulder2;
|
||||||
|
GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2);
|
||||||
|
|
||||||
|
if (erase)
|
||||||
|
{
|
||||||
|
dc.SetPen(*wxWHITE_PEN);
|
||||||
|
dc.SetBrush(*wxWHITE_BRUSH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.SetPen(*wxBLACK_PEN);
|
||||||
|
dc.SetBrush(*wxBLACK_BRUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw neck
|
||||||
|
dc.DrawLine((long) root.x, (long) root.y, (long) neck.x, (long) neck.y);
|
||||||
|
|
||||||
|
if (count > 1)
|
||||||
|
{
|
||||||
|
// Draw shoulder-to-shoulder line
|
||||||
|
dc.DrawLine((long) shoulder1.x, (long) shoulder1.y, (long) shoulder2.x, (long) shoulder2.y);
|
||||||
|
}
|
||||||
|
// Draw all the little branches
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
wxRealPoint pt, stemPt;
|
||||||
|
GetBranchingAttachmentPoint(attachment, i, pt, stemPt);
|
||||||
|
dc.DrawLine((long) stemPt.x, (long) stemPt.y, (long) pt.x, (long) pt.y);
|
||||||
|
|
||||||
|
if (GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB)
|
||||||
|
{
|
||||||
|
long blobSize=6;
|
||||||
|
// dc.DrawEllipse((long) (stemPt.x + 0.5 - (blobSize/2.0)), (long) (stemPt.y + 0.5 - (blobSize/2.0)), blobSize, blobSize);
|
||||||
|
dc.DrawEllipse((long) (stemPt.x - (blobSize/2.0)), (long) (stemPt.y - (blobSize/2.0)), blobSize, blobSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw or erase the branches (not the actual arcs though)
|
||||||
|
void wxShape::OnDrawBranches(wxDC& dc, bool erase)
|
||||||
|
{
|
||||||
|
if (m_attachmentMode != ATTACHMENT_MODE_BRANCHING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int count = GetNumberOfAttachments();
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
OnDrawBranches(dc, i, erase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only get the attachment position at the _edge_ of the shape, ignoring
|
||||||
|
// branching mode. This is used e.g. to indicate the edge of interest, not the point
|
||||||
|
// on the attachment branch.
|
||||||
|
bool wxShape::GetAttachmentPositionEdge(int attachment, double *x, double *y,
|
||||||
|
int nth, int no_arcs, wxLineShape *line)
|
||||||
|
{
|
||||||
|
int oldMode = m_attachmentMode;
|
||||||
|
|
||||||
|
// Calculate as if to edge, not branch
|
||||||
|
if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
|
||||||
|
m_attachmentMode = ATTACHMENT_MODE_EDGE;
|
||||||
|
bool success = GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
|
||||||
|
m_attachmentMode = oldMode;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate the standard attachment point from physical (0 is always North)
|
||||||
|
// to logical (0 -> 1 if rotated by 90 degrees)
|
||||||
|
int wxShape::PhysicalToLogicalAttachment(int physicalAttachment) const
|
||||||
|
{
|
||||||
|
const double pi = 3.1415926535897932384626433832795 ;
|
||||||
|
int i;
|
||||||
|
if (oglRoughlyEqual(GetRotation(), 0.0))
|
||||||
|
{
|
||||||
|
i = physicalAttachment;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), (pi/2.0)))
|
||||||
|
{
|
||||||
|
i = physicalAttachment - 1;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), pi))
|
||||||
|
{
|
||||||
|
i = physicalAttachment - 2;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), (3.0*pi/2.0)))
|
||||||
|
{
|
||||||
|
i = physicalAttachment - 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Can't handle -- assume the same.
|
||||||
|
return physicalAttachment;
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
i += 4;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate the standard attachment point from logical
|
||||||
|
// to physical (0 is always North)
|
||||||
|
int wxShape::LogicalToPhysicalAttachment(int logicalAttachment) const
|
||||||
|
{
|
||||||
|
const double pi = 3.1415926535897932384626433832795 ;
|
||||||
|
int i;
|
||||||
|
if (oglRoughlyEqual(GetRotation(), 0.0))
|
||||||
|
{
|
||||||
|
i = logicalAttachment;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), (pi/2.0)))
|
||||||
|
{
|
||||||
|
i = logicalAttachment + 1;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), pi))
|
||||||
|
{
|
||||||
|
i = logicalAttachment + 2;
|
||||||
|
}
|
||||||
|
else if (oglRoughlyEqual(GetRotation(), (3.0*pi/2.0)))
|
||||||
|
{
|
||||||
|
i = logicalAttachment + 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Can't handle -- assume the same.
|
||||||
|
return logicalAttachment;
|
||||||
|
|
||||||
|
if (i > 3)
|
||||||
|
i -= 4;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxShape::Rotate(double WXUNUSED(x), double WXUNUSED(y), double theta)
|
||||||
|
{
|
||||||
|
const double pi = 3.1415926535897932384626433832795 ;
|
||||||
|
m_rotation = theta;
|
||||||
|
if (m_rotation < 0.0)
|
||||||
|
{
|
||||||
|
m_rotation += 2*pi;
|
||||||
|
}
|
||||||
|
else if (m_rotation > 2*pi)
|
||||||
|
{
|
||||||
|
m_rotation -= 2*pi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -94,6 +94,15 @@
|
|||||||
|
|
||||||
#define OP_ALL (OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT)
|
#define OP_ALL (OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT)
|
||||||
|
|
||||||
|
// Attachment modes
|
||||||
|
#define ATTACHMENT_MODE_NONE 0
|
||||||
|
#define ATTACHMENT_MODE_EDGE 1
|
||||||
|
#define ATTACHMENT_MODE_BRANCHING 2
|
||||||
|
|
||||||
|
// Sub-modes for branching attachment mode
|
||||||
|
#define BRANCHING_ATTACHMENT_NORMAL 1
|
||||||
|
#define BRANCHING_ATTACHMENT_BLOB 2
|
||||||
|
|
||||||
class wxShapeTextLine;
|
class wxShapeTextLine;
|
||||||
class wxShapeCanvas;
|
class wxShapeCanvas;
|
||||||
class wxLineShape;
|
class wxLineShape;
|
||||||
@@ -127,6 +136,7 @@ class wxShapeEvtHandler: public wxObject
|
|||||||
virtual void OnDelete();
|
virtual void OnDelete();
|
||||||
virtual void OnDraw(wxDC& dc);
|
virtual void OnDraw(wxDC& dc);
|
||||||
virtual void OnDrawContents(wxDC& dc);
|
virtual void OnDrawContents(wxDC& dc);
|
||||||
|
virtual void OnDrawBranches(wxDC& dc, bool erase = FALSE);
|
||||||
virtual void OnMoveLinks(wxDC& dc);
|
virtual void OnMoveLinks(wxDC& dc);
|
||||||
virtual void OnErase(wxDC& dc);
|
virtual void OnErase(wxDC& dc);
|
||||||
virtual void OnEraseContents(wxDC& dc);
|
virtual void OnEraseContents(wxDC& dc);
|
||||||
@@ -274,8 +284,8 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
inline wxList& GetLines() const { return (wxList&) m_lines; }
|
inline wxList& GetLines() const { return (wxList&) m_lines; }
|
||||||
inline void SetDisableLabel(bool flag) { m_disableLabel = flag; }
|
inline void SetDisableLabel(bool flag) { m_disableLabel = flag; }
|
||||||
inline bool GetDisableLabel() const { return m_disableLabel; }
|
inline bool GetDisableLabel() const { return m_disableLabel; }
|
||||||
inline void SetAttachmentMode(bool flag) { m_attachmentMode = flag; }
|
inline void SetAttachmentMode(int mode) { m_attachmentMode = mode; }
|
||||||
inline bool GetAttachmentMode() const { return m_attachmentMode; }
|
inline int GetAttachmentMode() const { return m_attachmentMode; }
|
||||||
inline void SetId(long i) { m_id = i; }
|
inline void SetId(long i) { m_id = i; }
|
||||||
inline long GetId() const { return m_id; }
|
inline long GetId() const { return m_id; }
|
||||||
|
|
||||||
@@ -382,6 +392,12 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
virtual int GetNumberOfAttachments() const;
|
virtual int GetNumberOfAttachments() const;
|
||||||
virtual bool AttachmentIsValid(int attachment) const;
|
virtual bool AttachmentIsValid(int attachment) const;
|
||||||
|
|
||||||
|
// Only get the attachment position at the _edge_ of the shape, ignoring
|
||||||
|
// branching mode. This is used e.g. to indicate the edge of interest, not the point
|
||||||
|
// on the attachment branch.
|
||||||
|
virtual bool GetAttachmentPositionEdge(int attachment, double *x, double *y,
|
||||||
|
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
|
||||||
|
|
||||||
// Assuming the attachment lies along a vertical or horizontal line,
|
// Assuming the attachment lies along a vertical or horizontal line,
|
||||||
// calculate the position on that point.
|
// calculate the position on that point.
|
||||||
virtual wxRealPoint CalcSimpleAttachment(const wxRealPoint& pt1, const wxRealPoint& pt2,
|
virtual wxRealPoint CalcSimpleAttachment(const wxRealPoint& pt1, const wxRealPoint& pt2,
|
||||||
@@ -408,6 +424,59 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
// Can override this to prevent or intercept line reordering.
|
// Can override this to prevent or intercept line reordering.
|
||||||
virtual void OnChangeAttachment(int attachment, wxLineShape* line, wxList& ordering);
|
virtual void OnChangeAttachment(int attachment, wxLineShape* line, wxList& ordering);
|
||||||
|
|
||||||
|
//// New banching attachment code, 24/9/98
|
||||||
|
|
||||||
|
//
|
||||||
|
// |________|
|
||||||
|
// | <- root
|
||||||
|
// | <- neck
|
||||||
|
// shoulder1 ->---------<- shoulder2
|
||||||
|
// | | | | |<- stem
|
||||||
|
// <- branching attachment point N-1
|
||||||
|
|
||||||
|
// This function gets the root point at the given attachment.
|
||||||
|
virtual wxRealPoint GetBranchingAttachmentRoot(int attachment);
|
||||||
|
|
||||||
|
// This function gets information about where branching connections go (calls GetBranchingAttachmentRoot)
|
||||||
|
virtual bool GetBranchingAttachmentInfo(int attachment, wxRealPoint& root, wxRealPoint& neck,
|
||||||
|
wxRealPoint& shoulder1, wxRealPoint& shoulder2);
|
||||||
|
|
||||||
|
// n is the number of the adjoining line, from 0 to N-1 where N is the number of lines
|
||||||
|
// at this attachment point.
|
||||||
|
// attachmentPoint is where the arc meets the stem, and stemPoint is where the stem meets the
|
||||||
|
// shoulder.
|
||||||
|
virtual bool GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint& attachmentPoint,
|
||||||
|
wxRealPoint& stemPoint);
|
||||||
|
|
||||||
|
// Get the number of lines at this attachment position.
|
||||||
|
virtual int GetAttachmentLineCount(int attachment) const;
|
||||||
|
|
||||||
|
// Draw the branches (not the actual arcs though)
|
||||||
|
virtual void OnDrawBranches(wxDC& dc, int attachment, bool erase = FALSE);
|
||||||
|
virtual void OnDrawBranches(wxDC& dc, bool erase = FALSE);
|
||||||
|
|
||||||
|
// Branching attachment settings
|
||||||
|
inline void SetBranchNeckLength(int len) { m_branchNeckLength = len; }
|
||||||
|
inline int GetBranchNeckLength() const { return m_branchNeckLength; }
|
||||||
|
|
||||||
|
inline void SetBranchStemLength(int len) { m_branchStemLength = len; }
|
||||||
|
inline int GetBranchStemLength() const { return m_branchStemLength; }
|
||||||
|
|
||||||
|
inline void SetBranchSpacing(int len) { m_branchSpacing = len; }
|
||||||
|
inline int GetBranchSpacing() const { return m_branchSpacing; }
|
||||||
|
|
||||||
|
// Further detail on branching style, e.g. blobs on interconnections
|
||||||
|
inline void SetBranchStyle(long style) { m_branchStyle = style; }
|
||||||
|
inline long GetBranchStyle() const { return m_branchStyle; }
|
||||||
|
|
||||||
|
// Rotate the standard attachment point from physical (0 is always North)
|
||||||
|
// to logical (0 -> 1 if rotated by 90 degrees)
|
||||||
|
virtual int PhysicalToLogicalAttachment(int physicalAttachment) const;
|
||||||
|
|
||||||
|
// Rotate the standard attachment point from logical
|
||||||
|
// to physical (0 is always North)
|
||||||
|
virtual int LogicalToPhysicalAttachment(int logicalAttachment) const;
|
||||||
|
|
||||||
// This is really to distinguish between lines and other images.
|
// This is really to distinguish between lines and other images.
|
||||||
// For lines, want to pass drag to canvas, since lines tend to prevent
|
// For lines, want to pass drag to canvas, since lines tend to prevent
|
||||||
// dragging on a canvas (they get in the way.)
|
// dragging on a canvas (they get in the way.)
|
||||||
@@ -426,11 +495,8 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
// handler data if any. Calls the virtual Copy function.
|
// handler data if any. Calls the virtual Copy function.
|
||||||
void CopyWithHandler(wxShape& copy);
|
void CopyWithHandler(wxShape& copy);
|
||||||
|
|
||||||
// Rotate about the given axis by the given amount in radians
|
// Rotate about the given axis by the given amount in radians.
|
||||||
// (does nothing for most objects)
|
virtual void Rotate(double x, double y, double theta);
|
||||||
// But even non-rotating objects should record their notional
|
|
||||||
// rotation in case it's important (e.g. in dog-leg code).
|
|
||||||
virtual inline void Rotate(double WXUNUSED(x), double WXUNUSED(y), double theta) { m_rotation = theta; }
|
|
||||||
virtual inline double GetRotation() const { return m_rotation; }
|
virtual inline double GetRotation() const { return m_rotation; }
|
||||||
|
|
||||||
void ClearAttachments();
|
void ClearAttachments();
|
||||||
@@ -468,7 +534,8 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
double m_rotation;
|
double m_rotation;
|
||||||
int m_sensitivity;
|
int m_sensitivity;
|
||||||
bool m_draggable;
|
bool m_draggable;
|
||||||
bool m_attachmentMode; // TRUE if using attachments, FALSE otherwise
|
int m_attachmentMode; // 0 for no attachments, 1 if using normal attachments,
|
||||||
|
// 2 for branching attachments
|
||||||
bool m_spaceAttachments; // TRUE if lines at one side should be spaced
|
bool m_spaceAttachments; // TRUE if lines at one side should be spaced
|
||||||
bool m_fixedWidth;
|
bool m_fixedWidth;
|
||||||
bool m_fixedHeight;
|
bool m_fixedHeight;
|
||||||
@@ -485,6 +552,10 @@ class wxShape: public wxShapeEvtHandler
|
|||||||
int m_textMarginY;
|
int m_textMarginY;
|
||||||
wxString m_regionName;
|
wxString m_regionName;
|
||||||
bool m_maintainAspectRatio;
|
bool m_maintainAspectRatio;
|
||||||
|
int m_branchNeckLength;
|
||||||
|
int m_branchStemLength;
|
||||||
|
int m_branchSpacing;
|
||||||
|
long m_branchStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wxPolygonShape: public wxShape
|
class wxPolygonShape: public wxShape
|
||||||
|
@@ -308,7 +308,7 @@ bool wxPolygonShape::HitTest(double x, double y, int *attachment, double *distan
|
|||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
double xp, yp;
|
double xp, yp;
|
||||||
if (GetAttachmentPosition(i, &xp, &yp))
|
if (GetAttachmentPositionEdge(i, &xp, &yp))
|
||||||
{
|
{
|
||||||
double l = (double)sqrt(((xp - x) * (xp - x)) +
|
double l = (double)sqrt(((xp - x) * (xp - x)) +
|
||||||
((yp - y) * (yp - y)));
|
((yp - y) * (yp - y)));
|
||||||
@@ -439,7 +439,7 @@ bool wxPolygonShape::GetPerimeterPoint(double x1, double y1,
|
|||||||
// and we would want to connect to a point on that vertical --
|
// and we would want to connect to a point on that vertical --
|
||||||
// oglFindEndForPolyline can't cope with this (the arrow
|
// oglFindEndForPolyline can't cope with this (the arrow
|
||||||
// gets drawn to the wrong place).
|
// gets drawn to the wrong place).
|
||||||
if ((!m_attachmentMode) && (x1 == x2))
|
if ((m_attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2))
|
||||||
{
|
{
|
||||||
// Look for the point we'd be connecting to. This is
|
// Look for the point we'd be connecting to. This is
|
||||||
// a heuristic...
|
// a heuristic...
|
||||||
@@ -785,7 +785,7 @@ int wxPolygonShape::GetNumberOfAttachments() const
|
|||||||
bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
||||||
int nth, int no_arcs, wxLineShape *line)
|
int nth, int no_arcs, wxLineShape *line)
|
||||||
{
|
{
|
||||||
if (m_attachmentMode && m_points && attachment < m_points->Number())
|
if ((m_attachmentMode == ATTACHMENT_MODE_EDGE) && m_points && attachment < m_points->Number())
|
||||||
{
|
{
|
||||||
wxRealPoint *point = (wxRealPoint *)m_points->Nth(attachment)->Data();
|
wxRealPoint *point = (wxRealPoint *)m_points->Nth(attachment)->Data();
|
||||||
*x = point->x + m_xpos;
|
*x = point->x + m_xpos;
|
||||||
@@ -989,61 +989,7 @@ int wxRectangleShape::GetNumberOfAttachments() const
|
|||||||
bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
||||||
int nth, int no_arcs, wxLineShape *line)
|
int nth, int no_arcs, wxLineShape *line)
|
||||||
{
|
{
|
||||||
if (m_attachmentMode)
|
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
|
||||||
{
|
|
||||||
double top = (double)(m_ypos + m_height/2.0);
|
|
||||||
double bottom = (double)(m_ypos - m_height/2.0);
|
|
||||||
double left = (double)(m_xpos - m_width/2.0);
|
|
||||||
double right = (double)(m_xpos + m_width/2.0);
|
|
||||||
|
|
||||||
bool isEnd = (line && line->IsEnd(this));
|
|
||||||
|
|
||||||
// Simplified code
|
|
||||||
switch (attachment)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(right, bottom),
|
|
||||||
nth, no_arcs, line);
|
|
||||||
|
|
||||||
*x = pt.x; *y = pt.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(right, bottom), wxRealPoint(right, top),
|
|
||||||
nth, no_arcs, line);
|
|
||||||
|
|
||||||
*x = pt.x; *y = pt.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, top), wxRealPoint(right, top),
|
|
||||||
nth, no_arcs, line);
|
|
||||||
|
|
||||||
*x = pt.x; *y = pt.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(left, top),
|
|
||||||
nth, no_arcs, line);
|
|
||||||
|
|
||||||
*x = pt.x; *y = pt.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ *x = m_xpos; *y = m_ypos; return TRUE; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text object (no box)
|
// Text object (no box)
|
||||||
@@ -1179,13 +1125,19 @@ int wxEllipseShape::GetNumberOfAttachments() const
|
|||||||
bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
||||||
int nth, int no_arcs, wxLineShape *line)
|
int nth, int no_arcs, wxLineShape *line)
|
||||||
{
|
{
|
||||||
if (m_attachmentMode)
|
if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
|
||||||
|
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
|
||||||
|
|
||||||
|
if (m_attachmentMode != ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
double top = (double)(m_ypos + m_height/2.0);
|
double top = (double)(m_ypos + m_height/2.0);
|
||||||
double bottom = (double)(m_ypos - m_height/2.0);
|
double bottom = (double)(m_ypos - m_height/2.0);
|
||||||
double left = (double)(m_xpos - m_width/2.0);
|
double left = (double)(m_xpos - m_width/2.0);
|
||||||
double right = (double)(m_xpos + m_width/2.0);
|
double right = (double)(m_xpos + m_width/2.0);
|
||||||
switch (attachment)
|
|
||||||
|
int physicalAttachment = LogicalToPhysicalAttachment(attachment);
|
||||||
|
|
||||||
|
switch (physicalAttachment)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
@@ -186,7 +186,7 @@ bool wxDividedShape::GetAttachmentPosition(int attachment, double *x, double *y,
|
|||||||
wxLineShape *line)
|
wxLineShape *line)
|
||||||
{
|
{
|
||||||
int totalNumberAttachments = (GetRegions().Number() * 2) + 2;
|
int totalNumberAttachments = (GetRegions().Number() * 2) + 2;
|
||||||
if (!GetAttachmentMode() || (attachment >= totalNumberAttachments))
|
if ((GetAttachmentMode() == ATTACHMENT_MODE_NONE) || (attachment >= totalNumberAttachments))
|
||||||
{
|
{
|
||||||
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs);
|
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs);
|
||||||
}
|
}
|
||||||
|
@@ -1219,7 +1219,7 @@ bool wxOpPolyDraw::GetPerimeterPoint(double x1, double y1,
|
|||||||
double x2, double y2,
|
double x2, double y2,
|
||||||
double *x3, double *y3,
|
double *x3, double *y3,
|
||||||
double xOffset, double yOffset,
|
double xOffset, double yOffset,
|
||||||
bool attachmentMode)
|
int attachmentMode)
|
||||||
{
|
{
|
||||||
int n = m_noPoints;
|
int n = m_noPoints;
|
||||||
|
|
||||||
@@ -1227,7 +1227,7 @@ bool wxOpPolyDraw::GetPerimeterPoint(double x1, double y1,
|
|||||||
// and we would want to connect to a point on that vertical --
|
// and we would want to connect to a point on that vertical --
|
||||||
// oglFindEndForPolyline can't cope with this (the arrow
|
// oglFindEndForPolyline can't cope with this (the arrow
|
||||||
// gets drawn to the wrong place).
|
// gets drawn to the wrong place).
|
||||||
if ((!attachmentMode) && (x1 == x2))
|
if ((attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2))
|
||||||
{
|
{
|
||||||
// Look for the point we'd be connecting to. This is
|
// Look for the point we'd be connecting to. This is
|
||||||
// a heuristic...
|
// a heuristic...
|
||||||
|
@@ -79,7 +79,7 @@ public:
|
|||||||
double x2, double y2,
|
double x2, double y2,
|
||||||
double *x3, double *y3,
|
double *x3, double *y3,
|
||||||
double xOffset, double yOffset,
|
double xOffset, double yOffset,
|
||||||
bool attachmentMode)
|
int attachmentMode)
|
||||||
{ return FALSE; }
|
{ return FALSE; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -191,7 +191,7 @@ public:
|
|||||||
double x2, double y2,
|
double x2, double y2,
|
||||||
double *x3, double *y3,
|
double *x3, double *y3,
|
||||||
double xOffset, double yOffset,
|
double xOffset, double yOffset,
|
||||||
bool attachmentMode);
|
int attachmentMode);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxRealPoint* m_points;
|
wxRealPoint* m_points;
|
||||||
|
@@ -1065,7 +1065,7 @@ void wxLineShape::OnMoveLink(wxDC& dc, bool moveControlPoints)
|
|||||||
|
|
||||||
// if (moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
|
// if (moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
|
||||||
// Only move control points if it's a self link. And only works if attachment mode is ON.
|
// Only move control points if it's a self link. And only works if attachment mode is ON.
|
||||||
if ((m_from == m_to) && m_from->GetAttachmentMode() && moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
|
if ((m_from == m_to) && (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) && moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0))
|
||||||
{
|
{
|
||||||
wxNode *node = m_lineControlPoints->First();
|
wxNode *node = m_lineControlPoints->First();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -1110,7 +1110,7 @@ void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, d
|
|||||||
|
|
||||||
if (m_lineControlPoints->Number() > 2)
|
if (m_lineControlPoints->Number() > 2)
|
||||||
{
|
{
|
||||||
if (m_from->GetAttachmentMode())
|
if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
int nth, no_arcs;
|
int nth, no_arcs;
|
||||||
FindNth(m_from, &nth, &no_arcs, FALSE); // Not incoming
|
FindNth(m_from, &nth, &no_arcs, FALSE); // Not incoming
|
||||||
@@ -1121,7 +1121,7 @@ void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, d
|
|||||||
(double)second_point->x, (double)second_point->y,
|
(double)second_point->x, (double)second_point->y,
|
||||||
&end_x, &end_y);
|
&end_x, &end_y);
|
||||||
|
|
||||||
if (m_to->GetAttachmentMode())
|
if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
int nth, no_arcs;
|
int nth, no_arcs;
|
||||||
FindNth(m_to, &nth, &no_arcs, TRUE); // Incoming
|
FindNth(m_to, &nth, &no_arcs, TRUE); // Incoming
|
||||||
@@ -1139,7 +1139,7 @@ void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, d
|
|||||||
double toX = m_to->GetX();
|
double toX = m_to->GetX();
|
||||||
double toY = m_to->GetY();
|
double toY = m_to->GetY();
|
||||||
|
|
||||||
if (m_from->GetAttachmentMode())
|
if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
int nth, no_arcs;
|
int nth, no_arcs;
|
||||||
FindNth(m_from, &nth, &no_arcs, FALSE);
|
FindNth(m_from, &nth, &no_arcs, FALSE);
|
||||||
@@ -1148,7 +1148,7 @@ void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, d
|
|||||||
fromY = end_y;
|
fromY = end_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_to->GetAttachmentMode())
|
if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE)
|
||||||
{
|
{
|
||||||
int nth, no_arcs;
|
int nth, no_arcs;
|
||||||
FindNth(m_to, &nth, &no_arcs, TRUE);
|
FindNth(m_to, &nth, &no_arcs, TRUE);
|
||||||
@@ -1157,12 +1157,12 @@ void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, d
|
|||||||
toY = other_end_y;
|
toY = other_end_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_from->GetAttachmentMode())
|
if (m_from->GetAttachmentMode() == ATTACHMENT_MODE_NONE)
|
||||||
(void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(),
|
(void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(),
|
||||||
toX, toY,
|
toX, toY,
|
||||||
&end_x, &end_y);
|
&end_x, &end_y);
|
||||||
|
|
||||||
if (!m_to->GetAttachmentMode())
|
if (m_to->GetAttachmentMode() == ATTACHMENT_MODE_NONE)
|
||||||
(void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(),
|
(void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(),
|
||||||
fromX, fromY,
|
fromX, fromY,
|
||||||
&other_end_x, &other_end_y);
|
&other_end_x, &other_end_y);
|
||||||
|
@@ -276,15 +276,11 @@ protected:
|
|||||||
// probably be the same)
|
// probably be the same)
|
||||||
wxList* m_lineControlPoints;
|
wxList* m_lineControlPoints;
|
||||||
|
|
||||||
double m_arrowSpacing; // Separation between adjacent arrows
|
double m_arrowSpacing; // Separation between adjacent arrows
|
||||||
|
|
||||||
wxShape* m_to;
|
wxShape* m_to;
|
||||||
wxShape* m_from;
|
wxShape* m_from;
|
||||||
|
|
||||||
/*
|
|
||||||
double m_actualTextWidth; // Space the text takes up
|
|
||||||
double m_actualTextHeight; // (depends on text content unlike nodes)
|
|
||||||
*/
|
|
||||||
int m_attachmentTo; // Attachment point at one end
|
int m_attachmentTo; // Attachment point at one end
|
||||||
int m_attachmentFrom; // Attachment point at other end
|
int m_attachmentFrom; // Attachment point at other end
|
||||||
|
|
||||||
|
@@ -25,8 +25,8 @@ LOCALDOCDIR=$(WXDIR)\utils\ogl\docs
|
|||||||
|
|
||||||
PROGRAM=test
|
PROGRAM=test
|
||||||
|
|
||||||
OBJECTS = basic.obj basic2.obj canvas.obj ogldiag.obj lines.obj misc.obj divided.obj constrnt.obj\
|
OBJECTS = $(THISDIR)\basic.obj $(THISDIR)\basic2.obj $(THISDIR)\canvas.obj $(THISDIR)\ogldiag.obj $(THISDIR)\lines.obj $(THISDIR)\misc.obj $(THISDIR)\divided.obj $(THISDIR)\constrnt.obj\
|
||||||
composit.obj drawn.obj bmpshape.obj mfutils.obj
|
$(THISDIR)\composit.obj $(THISDIR)\drawn.obj $(THISDIR)\bmpshape.obj $(THISDIR)\mfutils.obj
|
||||||
|
|
||||||
LIBTARGET=$(WXDIR)\lib\ogl.lib
|
LIBTARGET=$(WXDIR)\lib\ogl.lib
|
||||||
|
|
||||||
@@ -59,57 +59,57 @@ basic.obj: basic.$(SRCSUFF) basic.h lines.h misc.h canvas.h
|
|||||||
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
basic2.obj: basic2.$(SRCSUFF) basic.h lines.h misc.h canvas.h
|
$(THISDIR)\basic2.obj: basic2.$(SRCSUFF) basic.h lines.h misc.h canvas.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
canvas.obj: canvas.$(SRCSUFF) basic.h misc.h canvas.h
|
$(THISDIR)\canvas.obj: canvas.$(SRCSUFF) basic.h misc.h canvas.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
ogldiag.obj: ogldiag.$(SRCSUFF) ogldiag.h canvas.h basic.h
|
$(THISDIR)\ogldiag.obj: ogldiag.$(SRCSUFF) ogldiag.h canvas.h basic.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
lines.obj: lines.$(SRCSUFF) basic.h misc.h canvas.h lines.h basicp.h linesp.h
|
$(THISDIR)\lines.obj: lines.$(SRCSUFF) basic.h misc.h canvas.h lines.h basicp.h linesp.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
misc.obj: misc.$(SRCSUFF) basic.h misc.h constrnt.h basicp.h
|
$(THISDIR)\misc.obj: misc.$(SRCSUFF) basic.h misc.h constrnt.h basicp.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
divided.obj: divided.$(SRCSUFF) basic.h misc.h canvas.h divided.h basicp.h
|
$(THISDIR)\divided.obj: divided.$(SRCSUFF) basic.h misc.h canvas.h divided.h basicp.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
constrnt.obj: constrnt.$(SRCSUFF) basic.h constrnt.h
|
$(THISDIR)\constrnt.obj: constrnt.$(SRCSUFF) basic.h constrnt.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
composit.obj: composit.$(SRCSUFF) basic.h misc.h canvas.h constrnt.h composit.h basicp.h
|
$(THISDIR)\composit.obj: composit.$(SRCSUFF) basic.h misc.h canvas.h constrnt.h composit.h basicp.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
drawn.obj: drawn.$(SRCSUFF) basic.h misc.h canvas.h drawn.h drawnp.h basicp.h
|
$(THISDIR)\drawn.obj: drawn.$(SRCSUFF) basic.h misc.h canvas.h drawn.h drawnp.h basicp.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
bmpshape.obj: bmpshape.$(SRCSUFF) basic.h misc.h canvas.h bmpshape.h
|
$(THISDIR)\bmpshape.obj: bmpshape.$(SRCSUFF) basic.h misc.h canvas.h bmpshape.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
|
||||||
mfutils.obj: mfutils.$(SRCSUFF) mfutils.h
|
$(THISDIR)\mfutils.obj: mfutils.$(SRCSUFF) mfutils.h
|
||||||
cl @<<
|
cl @<<
|
||||||
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
|
||||||
<<
|
<<
|
||||||
|
@@ -592,3 +592,163 @@ wxShape* wxDiagram::FindShape(long id) const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// Crossings classes
|
||||||
|
|
||||||
|
wxLineCrossings::wxLineCrossings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLineCrossings::~wxLineCrossings()
|
||||||
|
{
|
||||||
|
ClearCrossings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxLineCrossings::FindCrossings(wxDiagram& diagram)
|
||||||
|
{
|
||||||
|
ClearCrossings();
|
||||||
|
wxNode* node1 = diagram.GetShapeList()->First();
|
||||||
|
while (node1)
|
||||||
|
{
|
||||||
|
wxShape* shape1 = (wxShape*) node1->Data();
|
||||||
|
if (shape1->IsKindOf(CLASSINFO(wxLineShape)))
|
||||||
|
{
|
||||||
|
wxLineShape* lineShape1 = (wxLineShape*) shape1;
|
||||||
|
// Iterate through the segments
|
||||||
|
wxList* pts1 = lineShape1->GetLineControlPoints();
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < (pts1->Number() - 1); i++)
|
||||||
|
{
|
||||||
|
wxRealPoint* pt1_a = (wxRealPoint*) (pts1->Nth(i)->Data());
|
||||||
|
wxRealPoint* pt1_b = (wxRealPoint*) (pts1->Nth(i+1)->Data());
|
||||||
|
|
||||||
|
// Now we iterate through the segments again
|
||||||
|
|
||||||
|
wxNode* node2 = diagram.GetShapeList()->First();
|
||||||
|
while (node2)
|
||||||
|
{
|
||||||
|
wxShape* shape2 = (wxShape*) node2->Data();
|
||||||
|
|
||||||
|
// Assume that the same line doesn't cross itself
|
||||||
|
if (shape2->IsKindOf(CLASSINFO(wxLineShape)) && (shape1 != shape2))
|
||||||
|
{
|
||||||
|
wxLineShape* lineShape2 = (wxLineShape*) shape2;
|
||||||
|
// Iterate through the segments
|
||||||
|
wxList* pts2 = lineShape2->GetLineControlPoints();
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < (pts2->Number() - 1); j++)
|
||||||
|
{
|
||||||
|
wxRealPoint* pt2_a = (wxRealPoint*) (pts2->Nth(j)->Data());
|
||||||
|
wxRealPoint* pt2_b = (wxRealPoint*) (pts2->Nth(j+1)->Data());
|
||||||
|
|
||||||
|
// Now let's see if these two segments cross.
|
||||||
|
double ratio1, ratio2;
|
||||||
|
oglCheckLineIntersection(pt1_a->x, pt1_a->y, pt1_b->x, pt1_b->y,
|
||||||
|
pt2_a->x, pt2_a->y, pt2_b->x, pt2_b->y,
|
||||||
|
& ratio1, & ratio2);
|
||||||
|
|
||||||
|
if ((ratio1 < 1.0) && (ratio1 > -1.0))
|
||||||
|
{
|
||||||
|
// Intersection!
|
||||||
|
wxLineCrossing* crossing = new wxLineCrossing;
|
||||||
|
crossing->m_intersect.x = (pt1_a->x + (pt1_b->x - pt1_a->x)*ratio1);
|
||||||
|
crossing->m_intersect.y = (pt1_a->y + (pt1_b->y - pt1_a->y)*ratio1);
|
||||||
|
|
||||||
|
crossing->m_pt1 = * pt1_a;
|
||||||
|
crossing->m_pt2 = * pt1_b;
|
||||||
|
crossing->m_pt3 = * pt2_a;
|
||||||
|
crossing->m_pt4 = * pt2_b;
|
||||||
|
|
||||||
|
crossing->m_lineShape1 = lineShape1;
|
||||||
|
crossing->m_lineShape2 = lineShape2;
|
||||||
|
|
||||||
|
m_crossings.Append(crossing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node2 = node2->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node1 = node1->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxLineCrossings::DrawCrossings(wxDiagram& diagram, wxDC& dc)
|
||||||
|
{
|
||||||
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
|
|
||||||
|
long arcWidth = 8;
|
||||||
|
|
||||||
|
wxNode* node = m_crossings.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxLineCrossing* crossing = (wxLineCrossing*) node->Data();
|
||||||
|
// dc.DrawEllipse((long) (crossing->m_intersect.x - (arcWidth/2.0) + 0.5), (long) (crossing->m_intersect.y - (arcWidth/2.0) + 0.5),
|
||||||
|
// arcWidth, arcWidth);
|
||||||
|
|
||||||
|
|
||||||
|
// Let's do some geometry to find the points on either end of the arc.
|
||||||
|
/*
|
||||||
|
|
||||||
|
(x1, y1)
|
||||||
|
|\
|
||||||
|
| \
|
||||||
|
| \
|
||||||
|
| \
|
||||||
|
| \
|
||||||
|
| |\ c c1
|
||||||
|
| a | \
|
||||||
|
| \
|
||||||
|
| - x <-- centre of arc
|
||||||
|
a1 | b |\
|
||||||
|
| | \ c2
|
||||||
|
| a2 | \
|
||||||
|
| - \
|
||||||
|
| b2 \
|
||||||
|
| \
|
||||||
|
|_______________\ (x2, y2)
|
||||||
|
b1
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
double a1 = wxMax(crossing->m_pt1.y, crossing->m_pt2.y) - wxMin(crossing->m_pt1.y, crossing->m_pt2.y) ;
|
||||||
|
double b1 = wxMax(crossing->m_pt1.x, crossing->m_pt2.x) - wxMin(crossing->m_pt1.x, crossing->m_pt2.x) ;
|
||||||
|
double c1 = sqrt( (a1*a1) + (b1*b1) );
|
||||||
|
|
||||||
|
double c = arcWidth / 2.0;
|
||||||
|
double a = c * a1/c1 ;
|
||||||
|
double b = c * b1/c1 ;
|
||||||
|
|
||||||
|
// I'm not sure this is right, since we don't know which direction we should be going in - need
|
||||||
|
// to know which way the line slopes and choose the sign appropriately.
|
||||||
|
double arcX1 = crossing->m_intersect.x - b;
|
||||||
|
double arcY1 = crossing->m_intersect.y - a;
|
||||||
|
|
||||||
|
double arcX2 = crossing->m_intersect.x + b;
|
||||||
|
double arcY2 = crossing->m_intersect.y + a;
|
||||||
|
|
||||||
|
dc.SetPen(*wxBLACK_PEN);
|
||||||
|
dc.DrawArc( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2,
|
||||||
|
(long) crossing->m_intersect.x, (long) crossing->m_intersect.y);
|
||||||
|
|
||||||
|
dc.SetPen(*wxWHITE_PEN);
|
||||||
|
dc.DrawLine( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2 );
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxLineCrossings::ClearCrossings()
|
||||||
|
{
|
||||||
|
wxNode* node = m_crossings.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxLineCrossing* crossing = (wxLineCrossing*) node->Data();
|
||||||
|
delete crossing;
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
m_crossings.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -93,5 +93,32 @@ protected:
|
|||||||
wxList* m_shapeList;
|
wxList* m_shapeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class wxLineCrossing: public wxObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxLineCrossing() { m_lineShape1 = NULL; m_lineShape2 = NULL; }
|
||||||
|
wxRealPoint m_pt1; // First line
|
||||||
|
wxRealPoint m_pt2;
|
||||||
|
wxRealPoint m_pt3; // Second line
|
||||||
|
wxRealPoint m_pt4;
|
||||||
|
wxRealPoint m_intersect;
|
||||||
|
wxLineShape* m_lineShape1;
|
||||||
|
wxLineShape* m_lineShape2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class wxLineCrossings: public wxObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxLineCrossings();
|
||||||
|
~wxLineCrossings();
|
||||||
|
|
||||||
|
void FindCrossings(wxDiagram& diagram);
|
||||||
|
void DrawCrossings(wxDiagram& diagram, wxDC& dc);
|
||||||
|
void ClearCrossings();
|
||||||
|
|
||||||
|
public:
|
||||||
|
wxList m_crossings;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _OGL_OGLDIAG_H_
|
// _OGL_OGLDIAG_H_
|
||||||
|
@@ -1750,28 +1750,72 @@ bool wxPropertyStringListEditorDialog::dialogCancelled = FALSE;
|
|||||||
// Edit the string list.
|
// Edit the string list.
|
||||||
bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
|
bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
|
||||||
{
|
{
|
||||||
|
int largeButtonWidth = 60;
|
||||||
|
int largeButtonHeight = 25;
|
||||||
|
|
||||||
wxBeginBusyCursor();
|
wxBeginBusyCursor();
|
||||||
wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
|
wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
|
||||||
title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
|
title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
|
||||||
|
|
||||||
dialog->stringList = stringList;
|
dialog->stringList = stringList;
|
||||||
|
|
||||||
wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(5, 5));
|
|
||||||
wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(40, 5));
|
|
||||||
|
|
||||||
// wxButton *helpButton = new wxButton(dialog, (wxFunction)StringListEditorHelpProc, "Help");
|
|
||||||
// helpButton->SetClientData((char *)this);
|
|
||||||
|
|
||||||
dialog->listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
|
dialog->listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
|
||||||
wxPoint(5, 30), wxSize(300, 200), 0, NULL, wxLB_SINGLE);
|
wxPoint(-1, -1), wxSize(-1, -1), 0, NULL, wxLB_SINGLE);
|
||||||
|
|
||||||
dialog->stringText = new wxPropertyStringListEditorText(dialog,
|
dialog->stringText = new wxPropertyStringListEditorText(dialog,
|
||||||
wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
|
wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
|
||||||
wxSize(300, -1), wxPROCESS_ENTER);
|
wxSize(300, -1), wxPROCESS_ENTER);
|
||||||
dialog->stringText->Enable(FALSE);
|
dialog->stringText->Enable(FALSE);
|
||||||
|
|
||||||
wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(5, 280));
|
wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
|
||||||
wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(40, 280));
|
wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
|
||||||
|
wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
|
||||||
|
wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
|
||||||
|
|
||||||
|
okButton->SetDefault();
|
||||||
|
|
||||||
|
wxLayoutConstraints *c = new wxLayoutConstraints;
|
||||||
|
|
||||||
|
c->top.SameAs (dialog, wxTop, 2);
|
||||||
|
c->left.SameAs (dialog, wxLeft, 2);
|
||||||
|
c->right.SameAs (dialog, wxRight, 2);
|
||||||
|
c->bottom.SameAs (dialog->stringText, wxTop, 2);
|
||||||
|
dialog->listBox->SetConstraints(c);
|
||||||
|
|
||||||
|
c = new wxLayoutConstraints;
|
||||||
|
c->left.SameAs (dialog, wxLeft, 2);
|
||||||
|
c->right.SameAs (dialog, wxRight, 2);
|
||||||
|
c->bottom.SameAs (addButton, wxTop, 2);
|
||||||
|
c->height.AsIs();
|
||||||
|
dialog->stringText->SetConstraints(c);
|
||||||
|
|
||||||
|
c = new wxLayoutConstraints;
|
||||||
|
c->bottom.SameAs (dialog, wxBottom, 2);
|
||||||
|
c->left.SameAs (dialog, wxLeft, 2);
|
||||||
|
c->width.AsIs();
|
||||||
|
c->height.AsIs();
|
||||||
|
addButton->SetConstraints(c);
|
||||||
|
|
||||||
|
c = new wxLayoutConstraints;
|
||||||
|
c->bottom.SameAs (dialog, wxBottom, 2);
|
||||||
|
c->left.SameAs (addButton, wxRight, 2);
|
||||||
|
c->width.AsIs();
|
||||||
|
c->height.AsIs();
|
||||||
|
deleteButton->SetConstraints(c);
|
||||||
|
|
||||||
|
c = new wxLayoutConstraints;
|
||||||
|
c->bottom.SameAs (dialog, wxBottom, 2);
|
||||||
|
c->right.SameAs (dialog, wxRight, 2);
|
||||||
|
c->width.AsIs();
|
||||||
|
c->height.AsIs();
|
||||||
|
cancelButton->SetConstraints(c);
|
||||||
|
|
||||||
|
c = new wxLayoutConstraints;
|
||||||
|
c->bottom.SameAs (dialog, wxBottom, 2);
|
||||||
|
c->right.SameAs (cancelButton, wxLeft, 2);
|
||||||
|
c->width.AsIs();
|
||||||
|
c->height.AsIs();
|
||||||
|
okButton->SetConstraints(c);
|
||||||
|
|
||||||
wxNode *node = stringList->First();
|
wxNode *node = stringList->First();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -1783,6 +1827,7 @@ bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialog->SetClientSize(310, 305);
|
dialog->SetClientSize(310, 305);
|
||||||
|
dialog->Layout();
|
||||||
|
|
||||||
dialog->Centre(wxBOTH);
|
dialog->Centre(wxBOTH);
|
||||||
wxEndBusyCursor();
|
wxEndBusyCursor();
|
||||||
|
Reference in New Issue
Block a user