More-or-less finished reasonably cool wxToolBar class with tooltips.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@899 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
ef366d323b
commit
1a3ac83faf
@ -37,29 +37,19 @@ High Priority
|
|||||||
|
|
||||||
- wxSpinButton
|
- wxSpinButton
|
||||||
|
|
||||||
- wxTextCtrl text file loading and saving.
|
|
||||||
|
|
||||||
- A generic version of wxNotebook that can be used in wxMotif and
|
- A generic version of wxNotebook that can be used in wxMotif and
|
||||||
other toolkits that don't have a native control. Perhaps use wxTab as a
|
other toolkits that don't have a native control. Perhaps use wxTab as a
|
||||||
starting point.
|
starting point.
|
||||||
|
|
||||||
- Complete the MDI implementation. Could eventually alter the MDI
|
|
||||||
widgets to be more Windows-like -- currently it's half-hearted.
|
|
||||||
|
|
||||||
- Tidy dialogs such as the colour and font selectors.
|
- Tidy dialogs such as the colour and font selectors.
|
||||||
|
|
||||||
- Use generic wxTreeCtrl, wxListCtrl: debug and enhance these.
|
- Use generic wxTreeCtrl, wxListCtrl: debug and enhance these.
|
||||||
|
|
||||||
- Write a better generic wxToolBar class than wxToolBarSimple.
|
|
||||||
Alternatively, write a toolbar using Motif as described here:
|
|
||||||
http://www.motifzone.com/tmd/articles/Kurt_Huhner/jun96.html.
|
|
||||||
This article also explains how to implement tooltips.
|
|
||||||
|
|
||||||
- Find out why modal dialogs give a grab warning.
|
- Find out why modal dialogs give a grab warning.
|
||||||
|
|
||||||
- Find out why UI updates aren't working (probably an OnIdle failure).
|
- wxSystemSettings. Eventually, should have control panel-like utility
|
||||||
|
to change colours/fonts but meanwhile should maybe read them
|
||||||
- wxSystemSettings
|
from a file.
|
||||||
|
|
||||||
- wxThread (hopefully, similar to wxGTK)
|
- wxThread (hopefully, similar to wxGTK)
|
||||||
|
|
||||||
@ -106,8 +96,14 @@ Low Priority
|
|||||||
Netscape is running. See:
|
Netscape is running. See:
|
||||||
http://www.motifzone.com/tmd/articles/John_Cwikla/index.html
|
http://www.motifzone.com/tmd/articles/John_Cwikla/index.html
|
||||||
|
|
||||||
|
- wxRCConfig (a config class using X .rc files). Could simply
|
||||||
|
implement it in terms of current wxGet/WriteResource functions.
|
||||||
|
|
||||||
- wxCheckBoxList
|
- wxCheckBoxList
|
||||||
|
|
||||||
|
- Reimplement combobox using Lesstif's widget (avoiding GPL'ed
|
||||||
|
widget currently used).
|
||||||
|
|
||||||
- Write generic wxDirDialog (directory selector)
|
- Write generic wxDirDialog (directory selector)
|
||||||
|
|
||||||
- Use native Motif dialogs for wxMessageBox
|
- Use native Motif dialogs for wxMessageBox
|
||||||
@ -116,3 +112,6 @@ Low Priority
|
|||||||
Linux)
|
Linux)
|
||||||
|
|
||||||
- Blit scaling
|
- Blit scaling
|
||||||
|
|
||||||
|
- Could eventually alter the MDI widgets to be more Windows-like
|
||||||
|
-- currently it's half-hearted.
|
||||||
|
@ -70,10 +70,19 @@ class WXDLLEXPORT wxToolBar: public wxToolBarBase
|
|||||||
// necessary for completing the toolbar construction.
|
// necessary for completing the toolbar construction.
|
||||||
bool Realize() { return CreateTools(); };
|
bool Realize() { return CreateTools(); };
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
void DestroyPixmaps();
|
||||||
|
int FindIndexForWidget(WXWidget w);
|
||||||
|
WXWidget FindWidgetForIndex(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// List of widgets in the toolbar, indexed by tool index
|
// List of widgets in the toolbar, indexed by tool index
|
||||||
wxList m_widgets;
|
wxList m_widgets;
|
||||||
|
|
||||||
|
// List of pixmaps to destroy when tools are recreated or
|
||||||
|
// or toolbar is destroyed.
|
||||||
|
wxList m_pixmaps;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ MAKE=make
|
|||||||
LEX=flex.exe -t -L
|
LEX=flex.exe -t -L
|
||||||
|
|
||||||
# YACC. byacc or bison
|
# YACC. byacc or bison
|
||||||
# YACC=byacc.exe
|
YACC=byacc.exe
|
||||||
YACC=bison.exe
|
# YACC=bison.exe
|
||||||
|
|
||||||
# Resource compiler
|
# Resource compiler
|
||||||
RESCOMP=windres.exe
|
RESCOMP=windres.exe
|
||||||
|
@ -169,7 +169,7 @@ void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap)
|
|||||||
// since it is no longer valid.
|
// since it is no longer valid.
|
||||||
XtVaSetValues ((Widget) m_mainWidget,
|
XtVaSetValues ((Widget) m_mainWidget,
|
||||||
XmNlabelType, XmSTRING,
|
XmNlabelType, XmSTRING,
|
||||||
XmNlabelPixmap, NULL, // TODO: Does this work?
|
XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
|
||||||
XmNlabelInsensitivePixmap, NULL,
|
XmNlabelInsensitivePixmap, NULL,
|
||||||
XmNarmPixmap, NULL,
|
XmNarmPixmap, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -114,7 +114,7 @@ void wxStaticBitmap::SetBitmap(const wxBitmap& bitmap)
|
|||||||
// since it is no longer valid.
|
// since it is no longer valid.
|
||||||
XtVaSetValues (widget,
|
XtVaSetValues (widget,
|
||||||
XmNlabelType, XmSTRING,
|
XmNlabelType, XmSTRING,
|
||||||
XmNlabelPixmap, NULL, // TODO: Does this work?
|
XmNlabelPixmap, XmUNSPECIFIED_PIXMAP,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,37 +257,36 @@ bool wxTextCtrl::LoadFile(const wxString& file)
|
|||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
ifstream input((char*) (const char*) file, ios::nocreate | ios::in);
|
Widget textWidget = (Widget) m_mainWidget;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
if (!input.bad())
|
struct stat statb;
|
||||||
|
if ((stat ((char*) (const char*) file, &statb) == -1) || (statb.st_mode & S_IFMT) != S_IFREG ||
|
||||||
|
!(fp = fopen ((char*) (const char*) file, "r")))
|
||||||
{
|
{
|
||||||
struct stat stat_buf;
|
return FALSE;
|
||||||
if (stat(file, &stat_buf) < 0)
|
}
|
||||||
return FALSE;
|
else
|
||||||
// This may need to be a bigger buffer than the file size suggests,
|
{
|
||||||
// if it's a UNIX file. Give it an extra 1000 just in case.
|
long len = statb.st_size;
|
||||||
char *tmp_buffer = (char*)malloc((size_t)(stat_buf.st_size+1+1000));
|
char *text;
|
||||||
long no_lines = 0;
|
if (!(text = XtMalloc ((unsigned) (len + 1))))
|
||||||
long pos = 0;
|
{
|
||||||
while (!input.eof() && input.peek() != EOF)
|
fclose (fp);
|
||||||
{
|
return FALSE;
|
||||||
input.getline(wxBuffer, 500);
|
}
|
||||||
int len = strlen(wxBuffer);
|
if (fread (text, sizeof (char), len, fp) != (size_t) len)
|
||||||
wxBuffer[len] = 13;
|
{
|
||||||
wxBuffer[len+1] = 10;
|
}
|
||||||
wxBuffer[len+2] = 0;
|
fclose (fp);
|
||||||
strcpy(tmp_buffer+pos, wxBuffer);
|
|
||||||
pos += strlen(wxBuffer);
|
text[len] = 0;
|
||||||
no_lines++;
|
XmTextSetString (textWidget, text);
|
||||||
}
|
// m_textPosition = len;
|
||||||
|
XtFree (text);
|
||||||
// TODO add line
|
m_modified = FALSE;
|
||||||
|
return TRUE;
|
||||||
free(tmp_buffer);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If file is null, try saved file name first
|
// If file is null, try saved file name first
|
||||||
@ -301,13 +300,31 @@ bool wxTextCtrl::SaveFile(const wxString& file)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
m_fileName = theFile;
|
m_fileName = theFile;
|
||||||
|
|
||||||
ofstream output((char*) (const char*) theFile);
|
Widget textWidget = (Widget) m_mainWidget;
|
||||||
if (output.bad())
|
FILE *fp;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// TODO get and save text
|
if (!(fp = fopen ((char*) (const char*) theFile, "w")))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *text = XmTextGetString (textWidget);
|
||||||
|
long len = XmTextGetLastPosition (textWidget);
|
||||||
|
|
||||||
return FALSE;
|
if (fwrite (text, sizeof (char), len, fp) != (size_t) len)
|
||||||
|
{
|
||||||
|
// Did not write whole file
|
||||||
|
}
|
||||||
|
// Make sure newline terminates the file
|
||||||
|
if (text[len - 1] != '\n')
|
||||||
|
fputc ('\n', fp);
|
||||||
|
|
||||||
|
fclose (fp);
|
||||||
|
XtFree (text);
|
||||||
|
m_modified = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextCtrl::WriteText(const wxString& text)
|
void wxTextCtrl::WriteText(const wxString& text)
|
||||||
|
@ -55,6 +55,7 @@ wxTimer::wxTimer()
|
|||||||
wxTimer::~wxTimer()
|
wxTimer::~wxTimer()
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
|
wxTimerList.DeleteObject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTimer::Start(int milliseconds, bool mode)
|
bool wxTimer::Start(int milliseconds, bool mode)
|
||||||
|
@ -14,11 +14,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/wx.h"
|
#include "wx/wx.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/timer.h"
|
||||||
#include "wx/motif/toolbar.h"
|
#include "wx/motif/toolbar.h"
|
||||||
|
|
||||||
#include <Xm/Xm.h>
|
#include <Xm/Xm.h>
|
||||||
#include <Xm/PushBG.h>
|
#include <Xm/PushBG.h>
|
||||||
#include <Xm/PushB.h>
|
#include <Xm/PushB.h>
|
||||||
|
#include <Xm/Label.h>
|
||||||
#include <Xm/ToggleB.h>
|
#include <Xm/ToggleB.h>
|
||||||
#include <Xm/ToggleBG.h>
|
#include <Xm/ToggleBG.h>
|
||||||
#include <Xm/Form.h>
|
#include <Xm/Form.h>
|
||||||
@ -32,6 +35,30 @@ BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
|
|||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void wxToolButtonCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr);
|
||||||
|
static void wxToolButtonPopupCallback (Widget w, XtPointer client_data,
|
||||||
|
XEvent *event, Boolean *continue_to_dispatch);
|
||||||
|
|
||||||
|
wxBitmap wxCreateMaskedBitmap(wxBitmap& bitmap, wxColour& colour);
|
||||||
|
|
||||||
|
class wxToolBarTimer: public wxTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxToolBarTimer() { }
|
||||||
|
virtual void Notify();
|
||||||
|
|
||||||
|
static Widget help_popup;
|
||||||
|
static Widget buttonWidget;
|
||||||
|
static wxString helpString;
|
||||||
|
};
|
||||||
|
|
||||||
|
static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL;
|
||||||
|
|
||||||
|
Widget wxToolBarTimer::help_popup = (Widget) 0;
|
||||||
|
Widget wxToolBarTimer::buttonWidget = (Widget) 0;
|
||||||
|
wxString wxToolBarTimer::helpString = "";
|
||||||
|
|
||||||
wxToolBar::wxToolBar():
|
wxToolBar::wxToolBar():
|
||||||
m_widgets(wxKEY_INTEGER)
|
m_widgets(wxKEY_INTEGER)
|
||||||
{
|
{
|
||||||
@ -39,7 +66,6 @@ wxToolBar::wxToolBar():
|
|||||||
m_maxHeight = -1;
|
m_maxHeight = -1;
|
||||||
m_defaultWidth = 24;
|
m_defaultWidth = 24;
|
||||||
m_defaultHeight = 22;
|
m_defaultHeight = 22;
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
|
bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
|
||||||
@ -66,6 +92,10 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons
|
|||||||
XmNtraversalOn, False,
|
XmNtraversalOn, False,
|
||||||
XmNhorizontalSpacing, 0,
|
XmNhorizontalSpacing, 0,
|
||||||
XmNverticalSpacing, 0,
|
XmNverticalSpacing, 0,
|
||||||
|
XmNleftOffset, 0,
|
||||||
|
XmNrightOffset, 0,
|
||||||
|
XmNmarginWidth, 0,
|
||||||
|
XmNmarginHeight, 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
m_mainWidget = (WXWidget) toolbar;
|
m_mainWidget = (WXWidget) toolbar;
|
||||||
@ -81,7 +111,10 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons
|
|||||||
|
|
||||||
wxToolBar::~wxToolBar()
|
wxToolBar::~wxToolBar()
|
||||||
{
|
{
|
||||||
// TODO
|
delete wxTheToolBarTimer;
|
||||||
|
wxTheToolBarTimer = NULL;
|
||||||
|
ClearTools();
|
||||||
|
DestroyPixmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxToolBar::CreateTools()
|
bool wxToolBar::CreateTools()
|
||||||
@ -89,13 +122,21 @@ bool wxToolBar::CreateTools()
|
|||||||
if (m_tools.Number() == 0)
|
if (m_tools.Number() == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
// Separator spacing
|
||||||
|
const int separatorSize = GetToolSeparation(); // 8;
|
||||||
|
|
||||||
|
int currentSpacing = 0;
|
||||||
|
|
||||||
m_widgets.Clear();
|
m_widgets.Clear();
|
||||||
Widget prevButton = (Widget) 0;
|
Widget prevButton = (Widget) 0;
|
||||||
wxNode* node = m_tools.First();
|
wxNode* node = m_tools.First();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
||||||
if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok())
|
|
||||||
|
if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR)
|
||||||
|
currentSpacing = separatorSize;
|
||||||
|
else if (tool->m_bitmap1.Ok())
|
||||||
{
|
{
|
||||||
Widget button = (Widget) 0;
|
Widget button = (Widget) 0;
|
||||||
|
|
||||||
@ -105,12 +146,14 @@ bool wxToolBar::CreateTools()
|
|||||||
xmToggleButtonWidgetClass, (Widget) m_mainWidget,
|
xmToggleButtonWidgetClass, (Widget) m_mainWidget,
|
||||||
XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
|
XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
|
||||||
XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
|
XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
|
||||||
XmNleftOffset, 0,
|
XmNleftOffset, currentSpacing,
|
||||||
XmNtopAttachment, XmATTACH_FORM,
|
XmNtopAttachment, XmATTACH_FORM,
|
||||||
// XmNpushButtonEnabled, True,
|
// XmNpushButtonEnabled, True,
|
||||||
XmNmultiClick, XmMULTICLICK_KEEP,
|
XmNmultiClick, XmMULTICLICK_KEEP,
|
||||||
XmNlabelType, XmPIXMAP,
|
XmNlabelType, XmPIXMAP,
|
||||||
NULL);
|
NULL);
|
||||||
|
XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback,
|
||||||
|
(XtPointer) this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -118,23 +161,25 @@ bool wxToolBar::CreateTools()
|
|||||||
xmPushButtonWidgetClass, (Widget) m_mainWidget,
|
xmPushButtonWidgetClass, (Widget) m_mainWidget,
|
||||||
XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
|
XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET,
|
||||||
XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
|
XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton,
|
||||||
XmNleftOffset, 0,
|
XmNleftOffset, currentSpacing,
|
||||||
XmNtopAttachment, XmATTACH_FORM,
|
XmNtopAttachment, XmATTACH_FORM,
|
||||||
XmNpushButtonEnabled, True,
|
XmNpushButtonEnabled, True,
|
||||||
XmNmultiClick, XmMULTICLICK_KEEP,
|
XmNmultiClick, XmMULTICLICK_KEEP,
|
||||||
XmNlabelType, XmPIXMAP,
|
XmNlabelType, XmPIXMAP,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
XtAddCallback (button,
|
||||||
|
XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback,
|
||||||
|
(XtPointer) this);
|
||||||
|
}
|
||||||
|
|
||||||
// For each button, if there is a mask, we must create
|
// For each button, if there is a mask, we must create
|
||||||
// a new wxBitmap that has the correct background colour
|
// a new wxBitmap that has the correct background colour
|
||||||
// for the button. Otherwise the background will just be
|
// for the button. Otherwise the background will just be
|
||||||
// e.g. black if a transparent XPM has been loaded.
|
// e.g. black if a transparent XPM has been loaded.
|
||||||
|
wxBitmap originalBitmap = tool->m_bitmap1;
|
||||||
|
|
||||||
if (tool->m_bitmap1.GetMask())
|
if (tool->m_bitmap1.GetMask())
|
||||||
{
|
{
|
||||||
wxBitmap newBitmap(tool->m_bitmap1.GetWidth(),
|
|
||||||
tool->m_bitmap1.GetHeight(),
|
|
||||||
tool->m_bitmap1.GetDepth());
|
|
||||||
int backgroundPixel;
|
int backgroundPixel;
|
||||||
XtVaGetValues(button, XmNbackground, &backgroundPixel,
|
XtVaGetValues(button, XmNbackground, &backgroundPixel,
|
||||||
NULL);
|
NULL);
|
||||||
@ -143,50 +188,48 @@ bool wxToolBar::CreateTools()
|
|||||||
wxColour col;
|
wxColour col;
|
||||||
col.SetPixel(backgroundPixel);
|
col.SetPixel(backgroundPixel);
|
||||||
|
|
||||||
wxMemoryDC destDC;
|
wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap1, col);
|
||||||
wxMemoryDC srcDC;
|
|
||||||
srcDC.SelectObject(tool->m_bitmap1);
|
|
||||||
destDC.SelectObject(newBitmap);
|
|
||||||
|
|
||||||
wxBrush brush(col, wxSOLID);
|
|
||||||
destDC.SetOptimization(FALSE);
|
|
||||||
destDC.SetBackground(brush);
|
|
||||||
destDC.Clear();
|
|
||||||
destDC.Blit(0, 0, tool->m_bitmap1.GetWidth(), tool->m_bitmap1.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
|
|
||||||
|
|
||||||
tool->m_bitmap1 = newBitmap;
|
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())
|
if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask())
|
||||||
{
|
{
|
||||||
wxBitmap newBitmap(tool->m_bitmap2.GetWidth(),
|
// Use what's there
|
||||||
tool->m_bitmap2.GetHeight(),
|
wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap2, col);
|
||||||
tool->m_bitmap2.GetDepth());
|
|
||||||
int backgroundPixel;
|
|
||||||
XtVaGetValues(button, XmNbackground, &backgroundPixel,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
|
||||||
wxColour col;
|
|
||||||
col.SetPixel(backgroundPixel);
|
|
||||||
|
|
||||||
wxMemoryDC destDC;
|
|
||||||
wxMemoryDC srcDC;
|
|
||||||
srcDC.SelectObject(tool->m_bitmap2);
|
|
||||||
destDC.SelectObject(newBitmap);
|
|
||||||
|
|
||||||
wxBrush brush(col, wxSOLID);
|
|
||||||
destDC.SetOptimization(FALSE);
|
|
||||||
destDC.SetBackground(brush);
|
|
||||||
destDC.Clear();
|
|
||||||
destDC.Blit(0, 0, tool->m_bitmap2.GetWidth(), tool->m_bitmap2.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
|
|
||||||
|
|
||||||
tool->m_bitmap2 = newBitmap;
|
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 pixmap = (Pixmap) tool->m_bitmap1.GetPixmap();
|
||||||
Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap();
|
Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap();
|
||||||
|
|
||||||
if (tool->m_isToggle)
|
if (tool->m_isToggle)
|
||||||
{
|
{
|
||||||
|
// Toggle button
|
||||||
Pixmap pixmap2 = (Pixmap) 0;
|
Pixmap pixmap2 = (Pixmap) 0;
|
||||||
Pixmap insensPixmap2 = (Pixmap) 0;
|
Pixmap insensPixmap2 = (Pixmap) 0;
|
||||||
|
|
||||||
@ -200,34 +243,53 @@ bool wxToolBar::CreateTools()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button);
|
pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button);
|
||||||
// This has to be both toggled and insensitive, but
|
insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2);
|
||||||
// wxBitmap doesn't yet have a member to store & destroy
|
m_pixmaps.Append((wxObject*) insensPixmap2); // Store for later deletion
|
||||||
// it, so make it the same as pixmap2. Actually it's not
|
|
||||||
// used!
|
|
||||||
insensPixmap2 = pixmap2;
|
|
||||||
}
|
}
|
||||||
XtVaSetValues (button,
|
XtVaSetValues (button,
|
||||||
XmNlabelPixmap, pixmap,
|
XmNindicatorOn, False,
|
||||||
XmNselectPixmap, pixmap,
|
XmNshadowThickness, 2,
|
||||||
XmNlabelInsensitivePixmap, insensPixmap,
|
// XmNborderWidth, 0,
|
||||||
XmNselectInsensitivePixmap, insensPixmap,
|
// XmNspacing, 0,
|
||||||
XmNarmPixmap, pixmap2,
|
XmNmarginWidth, 0,
|
||||||
XmNlabelType, XmPIXMAP,
|
XmNmarginHeight, 0,
|
||||||
NULL);
|
XmNfillOnSelect, True,
|
||||||
|
XmNlabelPixmap, pixmap,
|
||||||
}
|
XmNselectPixmap, pixmap2,
|
||||||
|
XmNlabelInsensitivePixmap, insensPixmap,
|
||||||
|
XmNselectInsensitivePixmap, insensPixmap2,
|
||||||
|
XmNlabelType, XmPIXMAP,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
else
|
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,
|
XtVaSetValues(button,
|
||||||
XmNlabelPixmap, pixmap,
|
XmNlabelPixmap, pixmap,
|
||||||
XmNlabelInsensitivePixmap, insensPixmap,
|
XmNlabelInsensitivePixmap, insensPixmap,
|
||||||
NULL);
|
XmNarmPixmap, pixmap2,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask,
|
||||||
|
False, wxToolButtonPopupCallback, (XtPointer) this);
|
||||||
m_widgets.Append(tool->m_index, (wxObject*) button);
|
m_widgets.Append(tool->m_index, (wxObject*) button);
|
||||||
|
|
||||||
prevButton = button;
|
prevButton = button;
|
||||||
|
currentSpacing = 0;
|
||||||
}
|
}
|
||||||
node = node->Next();
|
node = node->Next();
|
||||||
}
|
}
|
||||||
@ -261,7 +323,12 @@ void wxToolBar::EnableTool(int toolIndex, bool enable)
|
|||||||
{
|
{
|
||||||
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
||||||
tool->m_enabled = enable;
|
tool->m_enabled = enable;
|
||||||
// TODO enable button
|
|
||||||
|
WXWidget widget = FindWidgetForIndex(tool->m_index);
|
||||||
|
if (widget == (WXWidget) 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XtSetSensitive((Widget) widget, (Boolean) enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +341,12 @@ void wxToolBar::ToggleTool(int toolIndex, bool toggle)
|
|||||||
if (tool->m_isToggle)
|
if (tool->m_isToggle)
|
||||||
{
|
{
|
||||||
tool->m_toggleState = toggle;
|
tool->m_toggleState = toggle;
|
||||||
// TODO: set toggle state
|
|
||||||
|
WXWidget widget = FindWidgetForIndex(tool->m_index);
|
||||||
|
if (widget == (WXWidget) 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XmToggleButtonSetState((Widget) widget, (Boolean) toggle, False);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,10 +361,23 @@ void wxToolBar::ClearTools()
|
|||||||
node = node->Next();
|
node = node->Next();
|
||||||
}
|
}
|
||||||
m_widgets.Clear();
|
m_widgets.Clear();
|
||||||
|
DestroyPixmaps();
|
||||||
|
|
||||||
wxToolBarBase::ClearTools();
|
wxToolBarBase::ClearTools();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxToolBar::DestroyPixmaps()
|
||||||
|
{
|
||||||
|
wxNode* node = m_pixmaps.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
Pixmap pixmap = (Pixmap) node->Data();
|
||||||
|
XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()), pixmap);
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
m_pixmaps.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
// If pushedBitmap is NULL, a reversed version of bitmap is
|
// If pushedBitmap is NULL, a reversed version of bitmap is
|
||||||
// created and used as the pushed/toggled image.
|
// created and used as the pushed/toggled image.
|
||||||
// If toggle is TRUE, the button toggles between the two states.
|
// If toggle is TRUE, the button toggles between the two states.
|
||||||
@ -319,3 +404,180 @@ wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBit
|
|||||||
return tool;
|
return tool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wxToolBar::FindIndexForWidget(WXWidget w)
|
||||||
|
{
|
||||||
|
wxNode* node = m_widgets.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
WXWidget widget = (WXWidget) node->Data();
|
||||||
|
if (widget == w)
|
||||||
|
return (int) node->key.integer;
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WXWidget wxToolBar::FindWidgetForIndex(int index)
|
||||||
|
{
|
||||||
|
wxNode* node = m_widgets.Find((long) index);
|
||||||
|
if (!node)
|
||||||
|
return (WXWidget) 0;
|
||||||
|
else
|
||||||
|
return (WXWidget) node->Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxToolButtonCallback (Widget w, XtPointer clientData,
|
||||||
|
XtPointer ptr)
|
||||||
|
{
|
||||||
|
wxToolBar *toolBar = (wxToolBar *) clientData;
|
||||||
|
int index = toolBar->FindIndexForWidget((WXWidget) w);
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
wxNode *node = toolBar->GetTools().Find((long)index);
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
||||||
|
if (tool->m_isToggle)
|
||||||
|
tool->m_toggleState = toolBar->GetToolState(index);
|
||||||
|
|
||||||
|
(void) toolBar->OnLeftClick(index, tool->m_toggleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a bitmap with transparent areas drawn in
|
||||||
|
// the given colour.
|
||||||
|
wxBitmap wxCreateMaskedBitmap(wxBitmap& bitmap, wxColour& colour)
|
||||||
|
{
|
||||||
|
wxBitmap newBitmap(bitmap.GetWidth(),
|
||||||
|
bitmap.GetHeight(),
|
||||||
|
bitmap.GetDepth());
|
||||||
|
wxMemoryDC destDC;
|
||||||
|
wxMemoryDC srcDC;
|
||||||
|
srcDC.SelectObject(bitmap);
|
||||||
|
destDC.SelectObject(newBitmap);
|
||||||
|
|
||||||
|
wxBrush brush(colour, wxSOLID);
|
||||||
|
destDC.SetOptimization(FALSE);
|
||||||
|
destDC.SetBackground(brush);
|
||||||
|
destDC.Clear();
|
||||||
|
destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
|
||||||
|
|
||||||
|
return newBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wxToolButtonPopupCallback (Widget w, XtPointer client_data,
|
||||||
|
XEvent *event, Boolean *continue_to_dispatch)
|
||||||
|
{
|
||||||
|
// TODO: retrieve delay before popping up tooltip from wxSystemSettings.
|
||||||
|
int delayMilli = 800;
|
||||||
|
wxToolBar* toolBar = (wxToolBar*) client_data;
|
||||||
|
|
||||||
|
int index = toolBar->FindIndexForWidget((WXWidget) w);
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
wxNode *node = toolBar->GetTools().Find((long)index);
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
wxToolBarTool *tool = (wxToolBarTool *)node->Data();
|
||||||
|
wxString str(toolBar->GetToolShortHelp(index));
|
||||||
|
if (str.IsNull() || str == "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!wxTheToolBarTimer)
|
||||||
|
wxTheToolBarTimer = new wxToolBarTimer;
|
||||||
|
|
||||||
|
wxToolBarTimer::buttonWidget = w;
|
||||||
|
wxToolBarTimer::helpString = str;
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Popup help label */
|
||||||
|
/************************************************************/
|
||||||
|
if (event->type == EnterNotify)
|
||||||
|
{
|
||||||
|
if (wxToolBarTimer::help_popup != (Widget) 0)
|
||||||
|
{
|
||||||
|
XtDestroyWidget (wxToolBarTimer::help_popup);
|
||||||
|
XtPopdown (wxToolBarTimer::help_popup);
|
||||||
|
}
|
||||||
|
wxToolBarTimer::help_popup = (Widget) 0;
|
||||||
|
|
||||||
|
// One shot
|
||||||
|
wxTheToolBarTimer->Start(delayMilli, TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
/************************************************************/
|
||||||
|
/* Popdown help label */
|
||||||
|
/************************************************************/
|
||||||
|
else if (event->type == LeaveNotify)
|
||||||
|
{
|
||||||
|
if (wxTheToolBarTimer)
|
||||||
|
wxTheToolBarTimer->Stop();
|
||||||
|
if (wxToolBarTimer::help_popup != (Widget) 0)
|
||||||
|
{
|
||||||
|
XtDestroyWidget (wxToolBarTimer::help_popup);
|
||||||
|
XtPopdown (wxToolBarTimer::help_popup);
|
||||||
|
}
|
||||||
|
wxToolBarTimer::help_popup = (Widget) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxToolBarTimer::Notify()
|
||||||
|
{
|
||||||
|
Position x, y;
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Create shell without window decorations */
|
||||||
|
/************************************************************/
|
||||||
|
help_popup = XtVaCreatePopupShell ("shell",
|
||||||
|
overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Get absolute position on display of toolbar button */
|
||||||
|
/************************************************************/
|
||||||
|
XtTranslateCoords (buttonWidget,
|
||||||
|
(Position) 0,
|
||||||
|
(Position) 0,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
|
// Move the tooltip more or less above the button
|
||||||
|
int yOffset = 20; // TODO: What should be really?
|
||||||
|
y -= yOffset;
|
||||||
|
if (y < yOffset) y = 0;
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Set the position of the help popup */
|
||||||
|
/************************************************************/
|
||||||
|
XtVaSetValues (help_popup,
|
||||||
|
XmNx, (Position) x,
|
||||||
|
XmNy, (Position) y,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Create help label */
|
||||||
|
/************************************************************/
|
||||||
|
XmString text = XmStringCreateSimple ((char*) (const char*) helpString);
|
||||||
|
XtVaCreateManagedWidget ("help_label",
|
||||||
|
xmLabelWidgetClass, help_popup,
|
||||||
|
XmNlabelString, text,
|
||||||
|
XtVaTypedArg,
|
||||||
|
XmNforeground, XtRString, "black",
|
||||||
|
strlen("black")+1,
|
||||||
|
XtVaTypedArg,
|
||||||
|
XmNbackground, XtRString, "LightGoldenrod",
|
||||||
|
strlen("LightGoldenrod")+1,
|
||||||
|
NULL);
|
||||||
|
XmStringFree (text);
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* Popup help label */
|
||||||
|
/************************************************************/
|
||||||
|
XtPopup (help_popup, XtGrabNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user