From 7fe7d506b191a94ce327c2a18733a4d3bc576cac Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Wed, 25 Nov 1998 21:42:56 +0000 Subject: [PATCH] Various wxMotif changes including size optimisation and debugging operator fix. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1057 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- distrib/msw/generic.rsp | 1 + docs/motif/changes.txt | 19 +++ docs/msw/install.txt | 8 +- include/wx/generic/tabg.h | 3 + include/wx/memory.h | 4 + include/wx/motif/notebook.h | 4 + include/wx/motif/setup.h | 19 +-- include/wx/motif/toolbar.h | 4 + include/wx/msw/setup.h | 11 +- include/wx/object.h | 18 ++- include/wx/stubs/setup.h | 5 + samples/memcheck/memcheck.cpp | 15 +-- src/common/gdicmn.cpp | 7 +- src/common/log.cpp | 11 +- src/common/memory.cpp | 19 +++ src/common/parser.y | 2 +- src/common/string.cpp | 2 +- src/cygnus.bat | 19 ++- src/generic/helpext.cpp | 6 +- src/generic/tabg.cpp | 29 +++++ src/make.env | 2 +- src/motif/dcclient.cpp | 2 +- src/motif/dcscreen.cpp | 2 +- src/motif/frame.cpp | 7 +- src/motif/makefile.unx | 1 + src/motif/mdi.cpp | 26 +++- src/motif/menu.cpp | 7 +- src/motif/notebook.cpp | 90 +++++++++----- src/motif/toolbar.cpp | 221 +++++++++++++++++++++++++++++++++- src/motif/utilsexc.cpp | 1 + src/motif/window.cpp | 87 +++++++++++-- 31 files changed, 549 insertions(+), 103 deletions(-) diff --git a/distrib/msw/generic.rsp b/distrib/msw/generic.rsp index 1e57c7435f..c9381aa6a5 100644 --- a/distrib/msw/generic.rsp +++ b/distrib/msw/generic.rsp @@ -53,6 +53,7 @@ src/zlib/*.3 src/zlib/*.mms include/wx/*.h +include/wx/*.cpp include/wx/protocol/*.h include/wx/*.cpp include/wx/wx_setup.vms diff --git a/docs/motif/changes.txt b/docs/motif/changes.txt index 4ada41c3b9..b8494394f0 100644 --- a/docs/motif/changes.txt +++ b/docs/motif/changes.txt @@ -34,3 +34,22 @@ More recently: tidied up in wxApp so that events are filtered through ProcessXEvent. - wxWindow::GetUpdateRegion should now work. +25/11/98 +-------- + +- Reimplemented MDI using wxNotebook instead of the MDI widgets, which + were too buggy (probably not design for dynamic addition/removal of + child frames). +- Some improvements to the wxNotebook implementation. +- wxToolBar now uses a bulletin board instead of a form, in an attempt + to make it possible to add ordinary wxControls to a toolbar. +- Cured problem with not being able to use global memory operators, + by defining two more global operators, so that the delete will match + the debugging implementation. +- Added wxUSE_DEBUG_NEW_ALWAYS so we can distinguish between using + global memory operators (usually OK) and #defining new to be + WXDEBUG_NEW (sometimes it might not be OK). +- Added time.cpp to makefile; set wxUSE_DATETIME to 1. +- Added a parent-existance check to popup menu code to make it not crash. +- Added some optimization in wxWindow::SetSize to produce less flicker. + It remains to be seen whether this produces any resize bugs. \ No newline at end of file diff --git a/docs/msw/install.txt b/docs/msw/install.txt index 8e6b0a6892..5f6609cb81 100644 --- a/docs/msw/install.txt +++ b/docs/msw/install.txt @@ -57,15 +57,15 @@ Borland C++ 4.5/5.0 compilation NOTE: only a few samples have up-to-date makefiles, e.g. minimal, docview, mdi. The utils makefile does not yet work. -Gnu-Win32 b19/Mingw32 compilation +Gnu-Win32 b19/b20/Mingw32 compilation --------------------------------- -wxWindows 2.0 supports Gnu-Win32 b19, Mingw32, and Mingw32/EGCS. +wxWindows 2.0 supports Gnu-Win32/Cygwin b19, b20, Mingw32, and Mingw32/EGCS. Thanks are due to Keith Garry Boyce (garp@opustel.com) and Cygnus for making it all possible. -From wxWindows 2.0 beta 9, both Gnu-Win32 b19 and Mingw32 (the minimal +From wxWindows 2.0 beta 9, both Gnu-Win32 and Mingw32 (the minimal distribution of Gnu-Win32) can be used with the same makefiles. Here are the steps required: @@ -116,8 +116,6 @@ Gotchas: - install.exe doesn't have built-in decompression because lzexpand.lib isn't available with Gnu-Win32. However, you can use it with external decompression utilities. -- Doesn't compile socket-related files due to a syntax error in - GnuWin32's Sockets.h. - Doesn't compile src/msw/ole files, so no drag and drop. References: diff --git a/include/wx/generic/tabg.h b/include/wx/generic/tabg.h index 3b246de2d5..c5c468a241 100644 --- a/include/wx/generic/tabg.h +++ b/include/wx/generic/tabg.h @@ -120,6 +120,9 @@ public: void ClearTabs(bool deleteTabs = TRUE); + bool SetTabText(int id, const wxString& label); + wxString GetTabText(int id) const; + // Layout tabs (optional, e.g. if resizing window) void Layout(void); diff --git a/include/wx/memory.h b/include/wx/memory.h index 6216211d25..1f2b25d19d 100644 --- a/include/wx/memory.h +++ b/include/wx/memory.h @@ -53,6 +53,10 @@ void wxDebugFree(void * buf, bool isVect = FALSE); #undef new #endif +// Added JACS 25/11/98: needed for some compilers +void * operator new (size_t size); +void * operator new[] (size_t size); + void * operator new (size_t size, char * fileName, int lineNum); void operator delete (void * buf); diff --git a/include/wx/motif/notebook.h b/include/wx/motif/notebook.h index 0615edef40..37d6439d27 100644 --- a/include/wx/motif/notebook.h +++ b/include/wx/motif/notebook.h @@ -201,6 +201,10 @@ public: virtual void ChangeForegroundColour(); virtual wxRect GetAvailableClientSize(); + // Implementation: calculate the layout of the view rect + // and resize the children if required + bool RefreshLayout(bool force = TRUE); + protected: // common part of all ctors void Init(); diff --git a/include/wx/motif/setup.h b/include/wx/motif/setup.h index 8b9f9762e5..8be4743065 100644 --- a/include/wx/motif/setup.h +++ b/include/wx/motif/setup.h @@ -76,7 +76,7 @@ // NOW MANDATORY: don't change. #define wxUSE_MEMORY_TRACING 1 // If 1, enables debugging versions of wxObject::new and - // wxObject::delete *IF* WXDEBUG is also defined. + // wxObject::delete *IF* __WXDEBUG__ is also defined. // WARNING: this code may not work with all architectures, especially // if alignment is an issue. #define wxUSE_DEBUG_CONTEXT 1 @@ -88,11 +88,15 @@ // since you may well need to output // an error log in a production // version (or non-debugging beta) -#define wxUSE_GLOBAL_MEMORY_OPERATORS 0 + +#define wxUSE_GLOBAL_MEMORY_OPERATORS 1 // In debug mode, cause new and delete to be redefined globally. // If this causes problems (e.g. link errors), set this to 0. - // In wxMotif, causes an 'all bets are off' - // memory error (generated by wxWindows) + +#define wxUSE_DEBUG_NEW_ALWAYS 1 + // In debug mode, causes new to be defined to + // be WXDEBUG_NEW (see object.h). + // If this causes problems (e.g. link errors), set this to 0. #define REMOVE_UNUSED_ARG 1 // Set this to 0 if your compiler can't cope @@ -117,11 +121,8 @@ #define wxUSE_GADGETS 0 // Use gadgets where possible -#define wxUSE_MDI_WIDGETS 1 - // Use Scott Sadler's MDI widgets (buggy). - // If 0, uses normal frames. - - +#define wxUSE_TIMEDATE 1 + // Use time and date /* * Finer detail * diff --git a/include/wx/motif/toolbar.h b/include/wx/motif/toolbar.h index 590b417b4f..f93c142d21 100644 --- a/include/wx/motif/toolbar.h +++ b/include/wx/motif/toolbar.h @@ -75,6 +75,10 @@ class WXDLLEXPORT wxToolBar: public wxToolBarBase int FindIndexForWidget(WXWidget w); WXWidget FindWidgetForIndex(int index); + WXWidget GetTopWidget() const; + WXWidget GetClientWidget() const; + WXWidget GetMainWidget() const; + protected: // List of widgets in the toolbar, indexed by tool index wxList m_widgets; diff --git a/include/wx/msw/setup.h b/include/wx/msw/setup.h index 5aacae2c3c..f4846c3d61 100644 --- a/include/wx/msw/setup.h +++ b/include/wx/msw/setup.h @@ -102,12 +102,12 @@ #define wxUSE_DYNAMIC_CLASSES 1 // If 1, enables provision of run-time type information. // NOW MANDATORY: don't change. -#define wxUSE_MEMORY_TRACING 0 +#define wxUSE_MEMORY_TRACING 1 // If 1, enables debugging versions of wxObject::new and // wxObject::delete *IF* __WXDEBUG__ is also defined. // WARNING: this code may not work with all architectures, especially // if alignment is an issue. -#define wxUSE_DEBUG_CONTEXT 0 +#define wxUSE_DEBUG_CONTEXT 1 // If 1, enables wxDebugContext, for // writing error messages to file, etc. // If __WXDEBUG__ is not defined, will still use @@ -116,10 +116,15 @@ // since you may well need to output // an error log in a production // version (or non-debugging beta) -#define wxUSE_GLOBAL_MEMORY_OPERATORS 0 +#define wxUSE_GLOBAL_MEMORY_OPERATORS 1 // In debug mode, cause new and delete to be redefined globally. // If this causes problems (e.g. link errors), set this to 0. +#define wxUSE_DEBUG_NEW_ALWAYS 1 + // In debug mode, causes new to be defined to + // be WXDEBUG_NEW (see object.h). + // If this causes problems (e.g. link errors), set this to 0. + // GnuWin32 (b19) can't copy with these operators. #ifdef __GNUWIN32__ #undef wxUSE_GLOBAL_MEMORY_OPERATORS 1 diff --git a/include/wx/object.h b/include/wx/object.h index 4dd391fb06..2791952dcb 100644 --- a/include/wx/object.h +++ b/include/wx/object.h @@ -246,11 +246,19 @@ private: int m_count; }; -#if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS -// JACS: not necessary now that new can be defined globally -//#ifndef WXDEBUG_NEW -//#define WXDEBUG_NEW new(__FILE__,__LINE__) -//#endif +#ifdef __WXDEBUG__ +#ifndef WXDEBUG_NEW +#define WXDEBUG_NEW new(__FILE__,__LINE__) +#endif +#else +#define WXDEBUG_NEW new +#endif + +// Redefine new to be the debugging version. This doesn't +// work with all compilers, in which case you need to +// use WXDEBUG_NEW explicitly if you wish to use the debugging version. + +#if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS #define new new(__FILE__,__LINE__) #endif diff --git a/include/wx/stubs/setup.h b/include/wx/stubs/setup.h index 7f86b00cf2..8029a0d6a8 100644 --- a/include/wx/stubs/setup.h +++ b/include/wx/stubs/setup.h @@ -87,6 +87,11 @@ // In debug mode, cause new and delete to be redefined globally. // If this causes problems (e.g. link errors), set this to 0. +#define wxUSE_DEBUG_NEW_ALWAYS 1 + // In debug mode, causes new to be defined to + // be WXDEBUG_NEW (see object.h). + // If this causes problems (e.g. link errors), set this to 0. + #define REMOVE_UNUSED_ARG 1 // Set this to 0 if your compiler can't cope // with omission of prototype parameters. diff --git a/samples/memcheck/memcheck.cpp b/samples/memcheck/memcheck.cpp index 65d1cbf235..ee9b073b48 100644 --- a/samples/memcheck/memcheck.cpp +++ b/samples/memcheck/memcheck.cpp @@ -27,7 +27,7 @@ #include "wx/date.h" -#ifdef __WXGTK__ +#if defined(__WXGTK__) || defined(__WXMOTIF__) #include "mondrian.xpm" #endif @@ -35,6 +35,12 @@ #error This program must be compiled in debug mode. #endif +// Normally, new is automatically defined to be the +// debugging version. If not, this does it. +#if !defined(new) && defined(WXDEBUG_NEW) +#define new WXDEBUG_NEW +#endif + // Define a new application type class MyApp: public wxApp { public: @@ -59,11 +65,7 @@ bool MyApp::OnInit(void) MyFrame *frame = new MyFrame((wxFrame *) NULL); // Give it an icon -#ifdef __WXMSW__ - frame->SetIcon(wxIcon("mondrian")); -#else - frame->SetIcon(wxIcon(mondrian_xpm)); -#endif + frame->SetIcon(wxICON(mondrian)); // Make a menubar wxMenu *file_menu = new wxMenu; @@ -82,7 +84,6 @@ bool MyApp::OnInit(void) frame->Show(TRUE); wxDebugContext::SetCheckpoint(); -// wxDebugContext::SetFile("debug.log"); wxString *thing = new wxString; wxDate* date = new wxDate; diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index 57c72604d3..642c03c3ea 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -449,8 +449,7 @@ wxBitmapList::wxBitmapList () wxBitmapList::~wxBitmapList () { -#ifdef __WXMSW__ - +#if defined(__WXMSW__) || defined(__WXMOTIF__) wxNode *node = First (); while (node) { @@ -466,7 +465,7 @@ wxBitmapList::~wxBitmapList () // Pen and Brush lists wxPenList::~wxPenList () { -#ifdef __WXMSW__ +#if defined(__WXMSW__) || defined(__WXMOTIF__) wxNode *node = First (); while (node) { @@ -514,7 +513,7 @@ wxPen *wxPenList::FindOrCreatePen (const wxColour& colour, int width, int style) wxBrushList::~wxBrushList () { -#ifdef __WXMSW__ +#if defined(__WXMSW__) || defined(__WXMOTIF__) wxNode *node = First (); while (node) { diff --git a/src/common/log.cpp b/src/common/log.cpp index 6a4bf7bf0d..3fbaa26c99 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -338,8 +338,11 @@ void wxLog::DoLog(wxLogLevel level, const char *szString) case wxLOG_Trace: case wxLOG_Debug: #ifdef __WXDEBUG__ - DoLogString(str << (level == wxLOG_Trace ? _("Trace") : _("Debug")) - << ": " << szString); + // DoLogString(str << (level == wxLOG_Trace ? _("Trace") : _("Debug")) + // << ": " << szString); + // JACS: we don't really want to prefix with 'Debug'. It's just extra + // verbiage. + DoLogString(szString); #endif break; @@ -506,10 +509,14 @@ void wxLogGui::DoLog(wxLogLevel level, const char *szString) OutputDebugString(strTime + szString + "\n\r"); #else // send them to stderr + /* fprintf(stderr, "%s %s: %s\n", strTime.c_str(), level == wxLOG_Trace ? _("Trace") : _("Debug"), szString); + */ + fprintf(stderr, "%s\n", + szString); fflush(stderr); #endif } diff --git a/src/common/memory.cpp b/src/common/memory.cpp index 37bf42aa41..8f9b0d0ac3 100644 --- a/src/common/memory.cpp +++ b/src/common/memory.cpp @@ -951,6 +951,25 @@ void * operator new (size_t size, char * fileName, int lineNum) #endif } +// Added JACS 25/11/98 +void * operator new (size_t size) +{ +#ifdef NO_DEBUG_ALLOCATION + return malloc(size); +#else + return wxDebugAlloc(size, NULL, 0, FALSE); +#endif +} + +void * operator new[] (size_t size) +{ +#ifdef NO_DEBUG_ALLOCATION + return malloc(size); +#else + return wxDebugAlloc(size, NULL, 0, FALSE, TRUE); +#endif +} + #if !( defined (_MSC_VER) && (_MSC_VER <= 1020) ) void * operator new[] (size_t size, char * fileName, int lineNum) { diff --git a/src/common/parser.y b/src/common/parser.y index 3973c3948c..c834a77e53 100644 --- a/src/common/parser.y +++ b/src/common/parser.y @@ -162,7 +162,7 @@ void yyerror(char *s) #ifndef yywrap #define yywrap() 1 #endif -#else if !defined(__alpha) && !defined(__ultrix) +#else if !defined(__alpha___) && !defined(__ultrix) int yywrap() { return 1; } #endif #endif diff --git a/src/common/string.cpp b/src/common/string.cpp index e4ff09bf0f..15976eb5e1 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -941,7 +941,7 @@ int wxString::Printf(const char *pszFormat, ...) int wxString::PrintfV(const char* pszFormat, va_list argptr) { -#ifdef __BORLANDC__ +#if defined(__BORLANDC__) || defined(__GNUWIN32__) static char s_szScratch[1024]; int iLen = vsprintf(s_szScratch, pszFormat, argptr); diff --git a/src/cygnus.bat b/src/cygnus.bat index 4cf2cf09cf..d641197665 100644 --- a/src/cygnus.bat +++ b/src/cygnus.bat @@ -1,15 +1,10 @@ -rem Cygnus Gnu-Win32 environment variables -rem Assumes that compiler and wxWindows are installed on the g: drive. -rem -set WXWIN=d:\wx2 -path C:\WINDOWS;C:\WINDOWS\COMMAND;g:\gnuwin32\b19\H-i386-cygwin32\bin;g:\gnuwin32\b19\H-i386-cygwin32\lib\gcc-lib\i386-cygwin32\cygnus-2.7.2-970404;c:\bin;g:\gnuwin32\b19\tcl\bin -set GCC_EXEC_PREFIX=G:\gnuwin32\b19\H-i386-cygwin32\lib\gcc-lib\ -set RCINCLUDE=%WXWIN\include -set CPLUS_INCLUDE_PATH=/g/gnuwin32/b19/h-i386-cygwin32/i386-cygwin32/include:/g/gnuwin32/b19/include/g++:/g/gnuwin32/b19/H-i386-cygwin32/lib/gcc-lib/i386-cygwin32/cygnus-2.7.2-970404/include:/d/wx2/include:/g/gnuwin32/b19/include/g++ -set MAKE_MODE=unix -mount G: /g -mount D: /d - +@ECHO OFF +SET MAKE_MODE=UNIX +rem SET PATH=g:\GNUWIN32\B20\CYGWIN~1\H-I586~1\BIN;%PATH% +PATH C:\WINDOWS;C:\WINDOWS\command;g:\GNUWIN32\B20\CYGWIN~1\H-I586~1\BIN;d:\wx\utils\tex2rtf\bin;g:\ast\astex;g:\ast\emtex\bin;g:\cvs;c:\bin +set BISON_SIMPLE=g:\gnuwin32\b20\cygwin-b20\share\bison.simple +set BISON_HAIRY=g:\gnuwin32\b20\cygwin-b20\share\bison.hairy +rem bash rem 4DOS users only... unalias make alias makegnu make -f makefile.g95 diff --git a/src/generic/helpext.cpp b/src/generic/helpext.cpp index 60933b44d6..a785361d42 100644 --- a/src/generic/helpext.cpp +++ b/src/generic/helpext.cpp @@ -105,7 +105,7 @@ wxExtHelpController::Initialize(const wxString& file) bool -wxExtHelpController::LoadFile(const wxString& ifile = "") +wxExtHelpController::LoadFile(const wxString& ifile) { wxString mapFile, file, url, doc; int id,i,len; @@ -118,7 +118,9 @@ wxExtHelpController::LoadFile(const wxString& ifile = "") file = ifile; if(! wxIsAbsolutePath(file)) { - file = wxGetWorkingDirectory(); + char* f = wxGetWorkingDirectory(); + file = f; + delete[] f; // wxGetWorkingDirectory returns new memory file << WXEXTHELP_SEPARATOR << ifile; } else diff --git a/src/generic/tabg.cpp b/src/generic/tabg.cpp index cc6a601bc5..cd9f9355df 100644 --- a/src/generic/tabg.cpp +++ b/src/generic/tabg.cpp @@ -207,7 +207,12 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) dc.GetTextExtent(GetLabel(), &textWidth, &textHeight); int textX = (int)(tabX + (GetWidth() - textWidth)/2.0); + if (textX < (tabX + 2)) + textX = (tabX + 2); + + dc.SetClippingRegion(tabX, tabY, GetWidth(), GetHeight()); dc.DrawText(GetLabel(), textX, textY); + dc.DestroyClippingRegion(); if (m_isSelected) { @@ -615,6 +620,7 @@ bool wxTabView::RemoveTab(int id) m_tabSelection = -1; delete tab; delete tabNode; + m_noTabs --; // The layout has changed Layout(); @@ -626,6 +632,24 @@ bool wxTabView::RemoveTab(int id) } return FALSE; } + +bool wxTabView::SetTabText(int id, const wxString& label) +{ + wxTabControl* control = FindTabControlForId(id); + if (!control) + return FALSE; + control->SetLabel(label); + return TRUE; +} + +wxString wxTabView::GetTabText(int id) const +{ + wxTabControl* control = FindTabControlForId(id); + if (!control) + return wxEmptyString; + else + return control->GetLabel(); +} // Returns the total height of the tabs component -- this may be several // times the height of a tab, if there are several tab layers (rows). @@ -674,6 +698,7 @@ void wxTabView::ClearTabs(bool deleteTabs) delete layerNode; layerNode = nextLayerNode; } + m_noTabs = 0; } @@ -761,6 +786,10 @@ void wxTabView::Layout(void) // Draw all tabs void wxTabView::Draw(wxDC& dc) { + // Don't draw anything if there are no tabs. + if (GetNumberOfTabs() == 0) + return; + // Draw top margin area (beneath tabs and above view area) if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR) { diff --git a/src/make.env b/src/make.env index b07e47c570..571f730386 100644 --- a/src/make.env +++ b/src/make.env @@ -35,7 +35,7 @@ GUISUFFIX = _stubs ########################## Compiler flags ############################# # Misc options -OPTIONS = -D__WXDEBUG__ # -DDEBUG='$(DEBUG)' # -DWXDEBUG +OPTIONS = -D__WXDEBUG__ COPTIONS = DEBUGFLAGS = -ggdb INCLUDE = diff --git a/src/motif/dcclient.cpp b/src/motif/dcclient.cpp index fe58804734..cb48e8250e 100644 --- a/src/motif/dcclient.cpp +++ b/src/motif/dcclient.cpp @@ -1522,7 +1522,7 @@ void wxWindowDC::SetPen( const wxPen &pen ) { Pixmap myStipple; - oldStipple = NULL; // For later reset!! + oldStipple = (wxBitmap*) NULL; // For later reset!! switch (m_currentFill) { diff --git a/src/motif/dcscreen.cpp b/src/motif/dcscreen.cpp index 050acdcd5e..ac4344498e 100644 --- a/src/motif/dcscreen.cpp +++ b/src/motif/dcscreen.cpp @@ -73,7 +73,7 @@ bool wxScreenDC::StartDrawingOnTop(wxWindow* window) return StartDrawingOnTop(& rect); } -bool wxScreenDC::StartDrawingOnTop(wxRect* rect = NULL) +bool wxScreenDC::StartDrawingOnTop(wxRect* rect) { if (sm_overlayWindow) return FALSE; diff --git a/src/motif/frame.cpp b/src/motif/frame.cpp index f0b7089297..c95fc09b97 100644 --- a/src/motif/frame.cpp +++ b/src/motif/frame.cpp @@ -479,10 +479,12 @@ void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags) if (!(height == -1 && width == -1)) { PreResize(); + /* JACS: not sure if this is necessary wxSizeEvent sizeEvent(wxSize(width, height), GetId()); sizeEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(sizeEvent); + */ } } @@ -553,13 +555,10 @@ void wxFrame::SetIcon(const wxIcon& icon) if (!m_frameShell) return; - // TODO - /* if (!icon.Ok() || !icon.GetPixmap()) return; - XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon->.GetPixmap(), NULL); - */ + XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL); } wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id, diff --git a/src/motif/makefile.unx b/src/motif/makefile.unx index fcaa095e9e..e43f53516e 100644 --- a/src/motif/makefile.unx +++ b/src/motif/makefile.unx @@ -46,6 +46,7 @@ LIB_CPP_SRC=\ ../common/textfile.cpp \ ../common/tbarbase.cpp \ ../common/tbarsmpl.cpp \ + ../common/time.cpp \ ../common/timercmn.cpp \ ../common/utilscmn.cpp \ ../common/wincmn.cpp \ diff --git a/src/motif/mdi.cpp b/src/motif/mdi.cpp index 902714acc2..a2076eaf31 100644 --- a/src/motif/mdi.cpp +++ b/src/motif/mdi.cpp @@ -550,7 +550,10 @@ void wxMDIChildFrame::SetIcon(const wxIcon& icon) void wxMDIChildFrame::SetTitle(const wxString& title) { m_title = title; - // TODO: set parent frame title + wxMDIClientWindow* clientWindow = GetMDIParentFrame()->GetClientWindow(); + int pageNo = clientWindow->FindPagePosition(this); + if (pageNo > -1) + clientWindow->SetPageText(pageNo, title); } // MDI operations @@ -623,7 +626,19 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) // m_windowParent = parent; // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); - return wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0); + bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0); + if (success) + { + wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL); + wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD); + GetTabView()->SetTabFont(font); + GetTabView()->SetSelectedTabFont(selFont); + GetTabView()->SetTabSize(120, 18); + GetTabView()->SetTabSelectionHeight(20); + return TRUE; + } + else + return FALSE; } void wxMDIClientWindow::SetSize(int x, int y, int width, int height, int sizeFlags) @@ -670,9 +685,11 @@ void wxMDIClientWindow::OnPageChanged(wxNotebookEvent& event) oldChild->GetEventHandler()->ProcessEvent(event); } } - wxMDIChildFrame* activeChild = (wxMDIChildFrame*) GetPage(event.GetSelection()); - if (activeChild) + if (event.GetSelection() != -1) { + wxMDIChildFrame* activeChild = (wxMDIChildFrame*) GetPage(event.GetSelection()); + if (activeChild) + { wxActivateEvent event(wxEVT_ACTIVATE, TRUE, activeChild->GetId()); event.SetEventObject( activeChild ); activeChild->GetEventHandler()->ProcessEvent(event); @@ -682,6 +699,7 @@ void wxMDIClientWindow::OnPageChanged(wxNotebookEvent& event) activeChild->GetMDIParentFrame()->SetActiveChild(activeChild); activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild); } + } } event.Skip(); } diff --git a/src/motif/menu.cpp b/src/motif/menu.cpp index 91df050e49..1eb8e5a3c9 100644 --- a/src/motif/menu.cpp +++ b/src/motif/menu.cpp @@ -832,8 +832,11 @@ int PostDeletionOfMenu( XtPointer* clientData ) wxMenu *menu = (wxMenu *)clientData; if (menu->GetMainWidget()) { - wxList& list = menu->GetParent()->GetItems(); - list.DeleteObject(menu); + if (menu->GetParent()) + { + wxList& list = menu->GetParent()->GetItems(); + list.DeleteObject(menu); + } menu->DestroyMenu(TRUE); } /* Mark as no longer popped up */ diff --git a/src/motif/notebook.cpp b/src/motif/notebook.cpp index fd0e099d65..00729a08ed 100644 --- a/src/motif/notebook.cpp +++ b/src/motif/notebook.cpp @@ -141,7 +141,6 @@ int wxNotebook::SetSelection(int nPage) wxNotebookPage* pPage = GetPage(nPage); m_tabView->SetTabSelection((int) (long) pPage); - // ChangePage(m_nSelection, nPage); // TODO return 0; @@ -161,7 +160,14 @@ bool wxNotebook::SetPageText(int nPage, const wxString& strText) { wxASSERT( IS_VALID_PAGE(nPage) ); - // TODO + wxNotebookPage* page = GetPage(nPage); + if (page) + { + m_tabView->SetTabText((int) (long) page, strText); + Refresh(); + return TRUE; + } + return FALSE; } @@ -169,8 +175,11 @@ wxString wxNotebook::GetPageText(int nPage) const { wxASSERT( IS_VALID_PAGE(nPage) ); - // TODO - return wxString(""); + wxNotebookPage* page = ((wxNotebook*)this)->GetPage(nPage); + if (page) + return m_tabView->GetTabText((int) (long) page); + else + return wxEmptyString; } int wxNotebook::GetPageImage(int nPage) const @@ -221,13 +230,16 @@ bool wxNotebook::DeletePage(int nPage) m_nSelection = -1; m_tabView->SetTabSelection(-1, FALSE); } - else if (m_nSelection > 0) + else if (m_nSelection > -1) { m_nSelection = -1; m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE); - ChangePage(-1, 0); + if (m_nSelection != 0) + ChangePage(-1, 0); } + RefreshLayout(FALSE); + return TRUE; } @@ -245,11 +257,8 @@ bool wxNotebook::RemovePage(int nPage) { wxCHECK( IS_VALID_PAGE(nPage), FALSE ); - if (m_nSelection != -1) - { - m_aPages[m_nSelection]->Show(FALSE); - m_aPages[m_nSelection]->Lower(); - } + m_aPages[nPage]->Show(FALSE); + // m_aPages[nPage]->Lower(); wxNotebookPage* pPage = GetPage(nPage); m_tabView->RemoveTab((int) (long) pPage); @@ -259,15 +268,30 @@ bool wxNotebook::RemovePage(int nPage) if (m_aPages.GetCount() == 0) { m_nSelection = -1; - m_tabView->SetTabSelection(-1, FALSE); + m_tabView->SetTabSelection(-1, TRUE); } - else if (m_nSelection > 0) + else if (m_nSelection > -1) { - m_nSelection = -1; - m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE); - ChangePage(-1, 0); + // Only change the selection if the page we + // deleted was the selection. + if (nPage == m_nSelection) + { + m_nSelection = -1; + // Select the first tab. Generates a ChangePage. + m_tabView->SetTabSelection((int) (long) GetPage(0), TRUE); + } + else + { + // We must adjust which tab we think is selected. + // If greater than the page we deleted, it must be moved down + // a notch. + if (m_nSelection > nPage) + m_nSelection -- ; + } } + RefreshLayout(FALSE); + return TRUE; } @@ -343,6 +367,8 @@ bool wxNotebook::InsertPage(int nPage, if ( m_nSelection == -1 ) ChangePage(-1, 0); + RefreshLayout(FALSE); + return TRUE; } @@ -360,8 +386,20 @@ void wxNotebook::OnSize(wxSizeEvent& event) s_bFirstTime = FALSE; } + RefreshLayout(); + + // Processing continues to next OnSize + event.Skip(); +} + +// Implementation: calculate the layout of the view rect +// and resize the children if required +bool wxNotebook::RefreshLayout(bool force) +{ if (m_tabView) { + wxRect oldRect = m_tabView->GetViewRect(); + int cw, ch; GetClientSize(& cw, & ch); @@ -388,13 +426,9 @@ void wxNotebook::OnSize(wxSizeEvent& event) m_tabView->SetViewRect(rect); m_tabView->Layout(); - /* - // emulate page change (it's esp. important to do it first time because - // otherwise our page would stay invisible) - int nSel = m_nSelection; - m_nSelection = -1; - SetSelection(nSel); - */ + + if (!force && (rect == oldRect)) + return FALSE; // fit the notebook page to the tab control's display area @@ -411,16 +445,17 @@ void wxNotebook::OnSize(wxSizeEvent& event) } Refresh(); } - - // Processing continues to next OnSize - event.Skip(); + return TRUE; } void wxNotebook::OnSelChange(wxNotebookEvent& event) { // is it our tab control? if ( event.GetEventObject() == this ) - ChangePage(event.GetOldSelection(), event.GetSelection()); + { + if (event.GetSelection() != m_nSelection) + ChangePage(event.GetOldSelection(), event.GetSelection()); + } // we want to give others a chance to process this message as well event.Skip(); @@ -479,6 +514,7 @@ void wxNotebook::Command(wxCommandEvent& event) // hide the currently active panel and show the new one void wxNotebook::ChangePage(int nOldSel, int nSel) { + // cout << "ChangePage: " << nOldSel << ", " << nSel << "\n"; wxASSERT( nOldSel != nSel ); // impossible if ( nOldSel != -1 ) { diff --git a/src/motif/toolbar.cpp b/src/motif/toolbar.cpp index 75c7b30d36..451b10f774 100644 --- a/src/motif/toolbar.cpp +++ b/src/motif/toolbar.cpp @@ -86,7 +86,14 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons Widget parentWidget = (Widget) parent->GetClientWidget(); Widget toolbar = XtVaCreateManagedWidget("toolbar", - xmFormWidgetClass, parentWidget, + xmBulletinBoardWidgetClass, (Widget) parentWidget, + XmNmarginWidth, 0, + XmNmarginHeight, 0, + XmNresizePolicy, XmRESIZE_NONE, + NULL); +/* + Widget toolbar = XtVaCreateManagedWidget("toolbar", + xmFormWidgetClass, (Widget) m_clientWidget, XmNtraversalOn, False, XmNhorizontalSpacing, 0, XmNverticalSpacing, 0, @@ -95,6 +102,7 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons XmNmarginWidth, 0, XmNmarginHeight, 0, NULL); +*/ m_mainWidget = (WXWidget) toolbar; @@ -117,6 +125,200 @@ wxToolBar::~wxToolBar() DestroyPixmaps(); } +bool wxToolBar::CreateTools() +{ + if (m_tools.Number() == 0) + return FALSE; + + // Separator spacing + const int separatorSize = GetToolSeparation(); // 8; + wxSize margins = GetToolMargins(); + int marginX = margins.x; + int marginY = margins.y; + + int currentX = marginX; + int currentY = marginY; + + int buttonHeight = 0; + + int currentSpacing = 0; + + m_widgets.Clear(); + Widget prevButton = (Widget) 0; + wxNode* node = m_tools.First(); + while (node) + { + wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + + if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) + currentX += separatorSize; + else if (tool->m_bitmap1.Ok()) + { + Widget button = (Widget) 0; + + if (tool->m_isToggle) + { + button = XtVaCreateWidget("toggleButton", + xmToggleButtonWidgetClass, (Widget) m_mainWidget, + XmNx, currentX, XmNy, currentY, + // XmNpushButtonEnabled, True, + XmNmultiClick, XmMULTICLICK_KEEP, + XmNlabelType, XmPIXMAP, + NULL); + XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); + } + else + { + button = XtVaCreateWidget("button", + xmPushButtonWidgetClass, (Widget) m_mainWidget, + XmNx, currentX, XmNy, currentY, + XmNpushButtonEnabled, True, + XmNmultiClick, XmMULTICLICK_KEEP, + XmNlabelType, XmPIXMAP, + NULL); + XtAddCallback (button, + XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); + } + + // For each button, if there is a mask, we must create + // a new wxBitmap that has the correct background colour + // for the button. Otherwise the background will just be + // e.g. black if a transparent XPM has been loaded. + wxBitmap originalBitmap = tool->m_bitmap1; + + if (tool->m_bitmap1.GetMask()) + { + int backgroundPixel; + XtVaGetValues(button, XmNbackground, &backgroundPixel, + NULL); + + + wxColour col; + col.SetPixel(backgroundPixel); + + wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap1, col); + + tool->m_bitmap1 = newBitmap; + } + + // Create a selected/toggled bitmap. If there isn't a m_bitmap2, + // we need to create it (with a darker, selected background) + int backgroundPixel; + if (tool->m_isToggle) + XtVaGetValues(button, XmNselectColor, &backgroundPixel, + NULL); + else + XtVaGetValues(button, XmNarmColor, &backgroundPixel, + NULL); + + wxColour col; + col.SetPixel(backgroundPixel); + + if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask()) + { + // Use what's there + wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap2, col); + tool->m_bitmap2 = newBitmap; + } + else + { + // Use unselected bitmap + if (originalBitmap.GetMask()) + { + wxBitmap newBitmap = wxCreateMaskedBitmap(originalBitmap, col); + tool->m_bitmap2 = newBitmap; + } + else + tool->m_bitmap2 = tool->m_bitmap1; + } + + Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap(); + Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap(); + + if (tool->m_isToggle) + { + // Toggle button + Pixmap pixmap2 = (Pixmap) 0; + Pixmap insensPixmap2 = (Pixmap) 0; + + // If there's a bitmap for the toggled state, use it, + // otherwise generate one. + if (tool->m_bitmap2.Ok()) + { + pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); + insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap(); + } + else + { + pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); + insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); + m_pixmaps.Append((wxObject*) insensPixmap2); // Store for later deletion + } + XtVaSetValues (button, + XmNindicatorOn, False, + XmNshadowThickness, 2, + // XmNborderWidth, 0, + // XmNspacing, 0, + XmNmarginWidth, 0, + XmNmarginHeight, 0, + XmNfillOnSelect, True, + XmNlabelPixmap, pixmap, + XmNselectPixmap, pixmap2, + XmNlabelInsensitivePixmap, insensPixmap, + XmNselectInsensitivePixmap, insensPixmap2, + XmNlabelType, XmPIXMAP, + NULL); + } + else + { + Pixmap pixmap2 = (Pixmap) 0; + + // If there's a bitmap for the armed state, use it, + // otherwise generate one. + if (tool->m_bitmap2.Ok()) + { + pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); + } + else + { + pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); + + } + // Normal button + XtVaSetValues(button, + XmNlabelPixmap, pixmap, + XmNlabelInsensitivePixmap, insensPixmap, + XmNarmPixmap, pixmap2, + NULL); + } + XtManageChild(button); + + Dimension width, height; + XtVaGetValues(button, XmNwidth, & width, XmNheight, & height, + NULL); + currentX += width + marginX; + buttonHeight = wxMax(buttonHeight, height); + + XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, + False, wxToolButtonPopupCallback, (XtPointer) this); + m_widgets.Append(tool->m_index, (wxObject*) button); + + prevButton = button; + currentSpacing = 0; + } + node = node->Next(); + } + + SetSize(-1, -1, currentX, buttonHeight + 2*marginY); + + return TRUE; +} + +// Old version, assuming we use a form. Now we use +// a bulletin board, so we can create controls on the toolbar. +#if 0 bool wxToolBar::CreateTools() { if (m_tools.Number() == 0) @@ -296,6 +498,7 @@ bool wxToolBar::CreateTools() return TRUE; } +#endif void wxToolBar::SetToolBitmapSize(const wxSize& size) { @@ -428,6 +631,22 @@ WXWidget wxToolBar::FindWidgetForIndex(int index) return (WXWidget) node->Data(); } +WXWidget wxToolBar::GetTopWidget() const +{ + return m_mainWidget; +} + +WXWidget wxToolBar::GetClientWidget() const +{ + return m_mainWidget; +} + +WXWidget wxToolBar::GetMainWidget() const +{ + return m_mainWidget; +} + + void wxToolButtonCallback (Widget w, XtPointer clientData, XtPointer ptr) { diff --git a/src/motif/utilsexc.cpp b/src/motif/utilsexc.cpp index a47a394130..a748ea126e 100644 --- a/src/motif/utilsexc.cpp +++ b/src/motif/utilsexc.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef VMS /*steve*/ diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 568974519d..7863f36b76 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -661,6 +661,27 @@ void wxWindow::GetClientSize(int *x, int *y) const void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags) { + // A bit of optimization to help sort out the flickers. + int oldX, oldY, oldW, oldH; + GetSize(& oldW, & oldH); + GetPosition(& oldX, & oldY); + + bool useOldPos = FALSE; + bool useOldSize = FALSE; + + if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)) + useOldPos = TRUE; + else if (x == oldX && y == oldY) + useOldPos = TRUE; + + if ((width == -1) && (height == -1)) + useOldSize = TRUE; + else if (width == oldW && height == oldH) + useOldSize = TRUE; + + if (useOldPos && useOldSize) + return; + if (m_drawingArea) { CanvasSetSize(x, y, width, height, sizeFlags); @@ -677,22 +698,32 @@ void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags) int xx = x; int yy = y; AdjustForParentClientOrigin(xx, yy, sizeFlags); - if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - XtVaSetValues(widget, XmNx, xx, NULL); - if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - XtVaSetValues(widget, XmNy, yy, NULL); - if (width > -1) - XtVaSetValues(widget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues(widget, XmNheight, height, NULL); + if (!useOldPos) + { + if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + XtVaSetValues(widget, XmNx, xx, NULL); + if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + XtVaSetValues(widget, XmNy, yy, NULL); + } + if (!useOldSize) + { + if (width > -1) + XtVaSetValues(widget, XmNwidth, width, NULL); + if (height > -1) + XtVaSetValues(widget, XmNheight, height, NULL); + } if (managed) XtManageChild(widget); + // How about this bit. Maybe we don't need to generate size events + // all the time -- they'll be generated when the window is sized anyway. + /* wxSizeEvent sizeEvent(wxSize(width, height), GetId()); sizeEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(sizeEvent); + */ } void wxWindow::SetClientSize(int width, int height) @@ -2504,6 +2535,27 @@ void wxWindow::DoPaint() // SetSize, but as per old wxCanvas (with drawing widget etc.) void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags) { + // A bit of optimization to help sort out the flickers. + int oldX, oldY, oldW, oldH; + GetSize(& oldW, & oldH); + GetPosition(& oldX, & oldY); + + bool useOldPos = FALSE; + bool useOldSize = FALSE; + + if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)) + useOldPos = TRUE; + else if (x == oldX && y == oldY) + useOldPos = TRUE; + + if ((w == -1) && (h == -1)) + useOldSize = TRUE; + else if (w == oldW && h == oldH) + useOldSize = TRUE; + + if (useOldPos && useOldSize) + return; + Widget drawingArea = (Widget) m_drawingArea; bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); @@ -2514,19 +2566,25 @@ void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags) int xx = x; int yy = y; AdjustForParentClientOrigin(xx, yy, sizeFlags); - if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (!useOldPos) + { + if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) { XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, xx, NULL); } - if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) { XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNy, yy, NULL); } + } - if (w > -1) + if (!useOldSize) + { + + if (w > -1) { if (m_borderWidget) { @@ -2588,16 +2646,21 @@ void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags) XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL); } + } + if (managed) XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); XtVaSetValues((Widget) m_drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); + /* int ww, hh; GetClientSize (&ww, &hh); wxSizeEvent sizeEvent(wxSize(ww, hh), GetId()); sizeEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(sizeEvent); + */ + } void wxWindow::CanvasSetClientSize (int w, int h) @@ -2630,10 +2693,12 @@ void wxWindow::CanvasSetClientSize (int w, int h) DoRefresh (); */ + /* wxSizeEvent sizeEvent(wxSize(w, h), GetId()); sizeEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(sizeEvent); + */ } void wxWindow::CanvasGetClientSize (int *w, int *h) const -- 2.45.2