added hyperlink alignment flags (patch 1537043)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41153 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-09-10 23:57:26 +00:00
parent 490f72fd16
commit 914f515762
4 changed files with 201 additions and 43 deletions

View File

@@ -39,8 +39,11 @@ Note that standard \helpref{wxWindow}{wxwindow} functions like \helpref{SetBackg
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{\windowstyle{wxHL\_ALIGN\_LEFT}}{Align the text to the left.}
\twocolitem{\windowstyle{wxHL\_ALIGN\_RIGHT}}{Align the text to the right.}
\twocolitem{\windowstyle{wxHL\_ALIGN\_CENTRE}}{Center the text (horizontally).}
\twocolitem{\windowstyle{wxHL\_CONTEXTMENU}}{Pop up a context menu when the hyperlink is right-clicked. The context menu contains a \texttt{``Copy URL"} menu item which is automatically handled by the hyperlink and which just copies in the clipboard the URL (not the label) of the control.}
\twocolitem{\windowstyle{wxHL\_DEFAULT\_STYLE}}{The default style for wxHyperlinkCtrl: \texttt{wxNO\_BORDER|wxHL\_CONTEXTMENU}.}
\twocolitem{\windowstyle{wxHL\_DEFAULT\_STYLE}}{The default style for wxHyperlinkCtrl: \texttt{wxNO\_BORDER|wxHL\_CONTEXTMENU|wxHL\_ALIGN\_CENTRE}.}
\end{twocollist}
See also \helpref{window styles overview}{windowstyles}.

View File

@@ -23,7 +23,10 @@
// ----------------------------------------------------------------------------
#define wxHL_CONTEXTMENU 0x0001
#define wxHL_DEFAULT_STYLE wxHL_CONTEXTMENU|wxNO_BORDER
#define wxHL_ALIGN_LEFT 0x0002
#define wxHL_ALIGN_RIGHT 0x0004
#define wxHL_ALIGN_CENTRE 0x0008
#define wxHL_DEFAULT_STYLE (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_CENTRE)
extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxHyperlinkCtrlNameStr[];
@@ -96,6 +99,12 @@ protected:
// Renders the hyperlink.
void OnPaint(wxPaintEvent& event);
// Returns the wxRect of the label of this hyperlink.
// This is different from the clientsize's rectangle when
// clientsize != bestsize and this rectangle is influenced
// by the alignment of the label (wxHL_ALIGN_*).
wxRect GetLabelRect() const;
// If the click originates inside the bounding box of the label,
// a flag is set so that an event will be fired when the left
// button is released.
@@ -108,7 +117,7 @@ protected:
// Changes the cursor to a hand, if the mouse is inside the label's
// bounding box.
void OnEnterWindow(wxMouseEvent& event);
void OnMotion(wxMouseEvent& event);
// Changes the cursor back to the default, if necessary.
void OnLeaveWindow(wxMouseEvent& event);
@@ -116,6 +125,9 @@ protected:
// handles "Copy URL" menuitem
void OnPopUpCopy(wxCommandEvent& event);
// Refreshes the control to update label's position if necessary
void OnSize(wxSizeEvent& event);
// overridden base class virtuals

View File

@@ -61,6 +61,15 @@ enum
HyperlinkPage_Ctrl
};
// alignment radiobox indices
enum
{
Align_Left,
Align_Centre,
Align_Right,
Align_Max
};
// ----------------------------------------------------------------------------
// CheckBoxWidgetsPage
// ----------------------------------------------------------------------------
@@ -83,19 +92,21 @@ protected:
void OnButtonSetURL(wxCommandEvent& event);
void OnButtonReset(wxCommandEvent& event);
void OnAlignment(wxCommandEvent& event);
// reset the control parameters
void Reset();
// (re)create the hyperctrl
void CreateHyperlink();
void CreateHyperlinkLong(long);
// the controls
// ------------
// the checkbox itself and the sizer it is in
wxHyperlinkCtrl *m_hyperlink;
wxSizer *m_sizerHyperlink;
wxHyperlinkCtrl *m_hyperlinkLong;
wxTextCtrl *m_label;
wxTextCtrl *m_url;
@@ -106,6 +117,8 @@ protected:
// the text entries for command parameters
wxTextCtrl *m_textLabel;
wxRadioBox *m_radioAlignMode;
private:
DECLARE_EVENT_TABLE()
DECLARE_WIDGETS_PAGE(HyperlinkWidgetsPage)
@@ -119,6 +132,8 @@ BEGIN_EVENT_TABLE(HyperlinkWidgetsPage, WidgetsPage)
EVT_BUTTON(HyperlinkPage_Reset, HyperlinkWidgetsPage::OnButtonReset)
EVT_BUTTON(HyperlinkPage_SetLabel, HyperlinkWidgetsPage::OnButtonSetLabel)
EVT_BUTTON(HyperlinkPage_SetURL, HyperlinkWidgetsPage::OnButtonSetURL)
EVT_RADIOBOX(wxID_ANY, HyperlinkWidgetsPage::OnAlignment)
END_EVENT_TABLE()
// ============================================================================
@@ -150,8 +165,27 @@ void HyperlinkWidgetsPage::CreateContent()
sizerLeft->Add( CreateSizerWithTextAndButton( HyperlinkPage_SetURL , wxT("Set &URL"), wxID_ANY, &m_url ),
0, wxALL | wxALIGN_RIGHT , 5 );
static const wxString alignments[] =
{
_T("&left"),
_T("&centre"),
_T("&right")
};
wxCOMPILE_TIME_ASSERT( WXSIZEOF(alignments) == Align_Max,
AlignMismatch );
m_radioAlignMode = new wxRadioBox(this, wxID_ANY, _T("alignment"),
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(alignments), alignments);
m_radioAlignMode->SetSelection(1); // start with "centre" selected since
// wxHL_DEFAULT_STYLE contains wxHL_ALIGN_CENTRE
sizerLeft->Add(m_radioAlignMode, 0, wxALL|wxGROW, 5);
// right pane
wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
wxSizer *szHyperlinkLong = new wxBoxSizer(wxVERTICAL);
wxSizer *szHyperlink = new wxBoxSizer(wxHORIZONTAL);
m_visit = new wxStaticText(this, wxID_ANY, wxT("Visit "));
@@ -162,17 +196,28 @@ void HyperlinkWidgetsPage::CreateContent()
m_fun = new wxStaticText(this, wxID_ANY, wxT(" for fun!"));
sizerRight->Add(0, 0, 1, wxCENTRE);
sizerRight->Add(m_visit, 0, wxCENTRE);
sizerRight->Add(m_hyperlink, 0, wxCENTRE);
sizerRight->Add(m_fun, 0, wxCENTRE);
sizerRight->Add(0, 0, 1, wxCENTRE);
sizerRight->SetMinSize(150, 0);
m_sizerHyperlink = sizerRight; // save it to modify it later
szHyperlink->Add(0, 0, 1, wxCENTRE);
szHyperlink->Add(m_visit, 0, wxCENTRE);
szHyperlink->Add(m_hyperlink, 0, wxCENTRE);
szHyperlink->Add(m_fun, 0, wxCENTRE);
szHyperlink->Add(0, 0, 1, wxCENTRE);
szHyperlink->SetMinSize(150, 0);
m_hyperlinkLong = new wxHyperlinkCtrl(this,
wxID_ANY,
wxT("This is a long hyperlink"),
wxT("www.wxwidgets.org"));
szHyperlinkLong->Add(0, 0, 1, wxCENTRE);
szHyperlinkLong->Add(szHyperlink, 0, wxCENTRE|wxGROW);
szHyperlinkLong->Add(0, 0, 1, wxCENTRE);
szHyperlinkLong->Add(m_hyperlinkLong, 0, wxGROW);
szHyperlinkLong->Add(0, 0, 1, wxCENTRE);
// the 3 panes panes compose the window
sizerTop->Add(sizerLeft, 0, (wxALL & ~wxLEFT), 10);
sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
sizerTop->Add(szHyperlinkLong, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
// final initializations
Reset();
@@ -193,25 +238,42 @@ void HyperlinkWidgetsPage::CreateHyperlink()
const wxString label = m_hyperlink->GetLabel();
const wxString url = m_hyperlink->GetURL();
size_t count = m_sizerHyperlink->GetChildren().GetCount();
for ( size_t n = 0; n < count; n++ )
{
m_sizerHyperlink->Remove(0);
}
delete m_hyperlink;
m_hyperlink = new wxHyperlinkCtrl(this,
wxHyperlinkCtrl *hyp = new wxHyperlinkCtrl(this,
HyperlinkPage_Ctrl,
label,
url);
m_sizerHyperlink->Add(0, 0, 1, wxCENTRE);
m_sizerHyperlink->Add(m_visit, 0, wxCENTRE);
m_sizerHyperlink->Add(m_hyperlink, 0, wxCENTRE);
m_sizerHyperlink->Add(m_fun, 0, wxCENTRE);
m_sizerHyperlink->Add(0, 0, 1, wxCENTRE);
m_sizerHyperlink->Layout();
// update sizer's child window
GetSizer()->Replace(m_hyperlink, hyp, true);
// update our pointer
delete m_hyperlink;
m_hyperlink = hyp;
// relayout the sizer
GetSizer()->Layout();
}
void HyperlinkWidgetsPage::CreateHyperlinkLong(long style)
{
style = (wxHL_DEFAULT_STYLE & ~wxHL_ALIGN_CENTRE)|style;
wxHyperlinkCtrl *hyp = new wxHyperlinkCtrl(this,
wxID_ANY,
wxT("This is a long hyperlink"),
wxT("www.wxwidgets.org"),
wxDefaultPosition,
wxDefaultSize,
style);
// update sizer's child window
GetSizer()->Replace(m_hyperlinkLong, hyp, true);
// update our pointer
delete m_hyperlinkLong;
m_hyperlinkLong = hyp;
// relayout the sizer
GetSizer()->Layout();
}
// ----------------------------------------------------------------------------
@@ -237,4 +299,30 @@ void HyperlinkWidgetsPage::OnButtonSetURL(wxCommandEvent& WXUNUSED(event))
CreateHyperlink();
}
void HyperlinkWidgetsPage::OnAlignment(wxCommandEvent& WXUNUSED(event))
{
long addstyle;
switch ( m_radioAlignMode->GetSelection() )
{
default:
case Align_Max:
wxFAIL_MSG( _T("unknown alignment") );
// fall through
case Align_Left:
addstyle = wxHL_ALIGN_LEFT;
break;
case Align_Centre:
addstyle = wxHL_ALIGN_CENTRE;
break;
case Align_Right:
addstyle = wxHL_ALIGN_RIGHT;
break;
}
CreateHyperlinkLong(addstyle);
}
#endif // wxUSE_HYPERLINKCTRL

View File

@@ -62,8 +62,9 @@ BEGIN_EVENT_TABLE(wxHyperlinkCtrl, wxControl)
EVT_LEFT_DOWN(wxHyperlinkCtrl::OnLeftDown)
EVT_LEFT_UP(wxHyperlinkCtrl::OnLeftUp)
EVT_RIGHT_UP(wxHyperlinkCtrl::OnRightUp)
EVT_ENTER_WINDOW(wxHyperlinkCtrl::OnEnterWindow)
EVT_MOTION(wxHyperlinkCtrl::OnMotion)
EVT_LEAVE_WINDOW(wxHyperlinkCtrl::OnLeaveWindow)
EVT_SIZE(wxHyperlinkCtrl::OnSize)
// for the context menu
EVT_MENU(wxHYPERLINKCTRL_POPUP_COPY_ID, wxHyperlinkCtrl::OnPopUpCopy)
@@ -76,6 +77,14 @@ bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
wxASSERT_MSG(!url.empty() || !label.empty(),
wxT("Both URL and label are empty ?"));
#ifdef __WXDEBUG__
int alignment = (int)((style & wxHL_ALIGN_LEFT) != 0) +
(int)((style & wxHL_ALIGN_CENTRE) != 0) +
(int)((style & wxHL_ALIGN_RIGHT) != 0);
wxASSERT_MSG(alignment == 1,
wxT("Specify exactly one align flag!"));
#endif
if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
return false;
@@ -90,9 +99,6 @@ bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
else
SetLabel(label);
// by default the cursor to use in this window is wxCURSOR_HAND
SetCursor(wxCursor(wxCURSOR_HAND));
m_rollover = false;
m_clicking = false;
m_visited = false;
@@ -159,6 +165,24 @@ void wxHyperlinkCtrl::DoContextMenu(const wxPoint &pos)
delete menuPopUp;
}
wxRect wxHyperlinkCtrl::GetLabelRect() const
{
// our best size is always the size of the label without borders
wxSize c(GetClientSize()), b(GetBestSize());
wxPoint offset;
// the label is always centered vertically
offset.y = (c.GetHeight()-b.GetHeight())/2;
if (HasFlag(wxHL_ALIGN_CENTRE))
offset.x = (c.GetWidth()-b.GetWidth())/2;
else if (HasFlag(wxHL_ALIGN_RIGHT))
offset.x = c.GetWidth()-b.GetWidth();
else if (HasFlag(wxHL_ALIGN_LEFT))
offset.x = 0;
return wxRect(offset, b);
}
// ----------------------------------------------------------------------------
@@ -171,17 +195,21 @@ void wxHyperlinkCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
dc.SetFont(GetFont());
dc.SetTextForeground(GetForegroundColour());
dc.SetTextBackground(GetBackgroundColour());
dc.DrawText(GetLabel(), 0, 0);
dc.DrawText(GetLabel(), GetLabelRect().GetTopLeft());
}
void wxHyperlinkCtrl::OnLeftDown(wxMouseEvent& WXUNUSED(event))
void wxHyperlinkCtrl::OnLeftDown(wxMouseEvent& event)
{
m_clicking = true;
// the left click must start from the hyperlink rect
m_clicking = GetLabelRect().Inside(event.GetPosition());
}
void wxHyperlinkCtrl::OnLeftUp(wxMouseEvent& WXUNUSED(event))
void wxHyperlinkCtrl::OnLeftUp(wxMouseEvent& event)
{
if (!m_clicking) return;
// the click must be started and ended in the hyperlink rect
if (!m_clicking || !GetLabelRect().Inside(event.GetPosition()))
return;
SetForegroundColour(m_visitedColour);
m_visited = true;
@@ -197,20 +225,40 @@ void wxHyperlinkCtrl::OnLeftUp(wxMouseEvent& WXUNUSED(event))
void wxHyperlinkCtrl::OnRightUp(wxMouseEvent& event)
{
if( GetWindowStyle() & wxHL_CONTEXTMENU )
if ( GetLabelRect().Inside(event.GetPosition()) )
DoContextMenu(wxPoint(event.m_x, event.m_y));
}
void wxHyperlinkCtrl::OnEnterWindow(wxMouseEvent& WXUNUSED(event))
void wxHyperlinkCtrl::OnMotion(wxMouseEvent& event)
{
wxRect textrc = GetLabelRect();
if (textrc.Inside(event.GetPosition()))
{
SetCursor(wxCursor(wxCURSOR_HAND));
SetForegroundColour(m_hoverColour);
m_rollover = true;
Refresh();
}
else if (m_rollover)
{
SetCursor(*wxSTANDARD_CURSOR);
SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
m_rollover = false;
Refresh();
}
}
void wxHyperlinkCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event) )
{
// NB: when the label rect and the client size rect have the same
// height this function is indispensable to remove the "rollover"
// effect as the OnMotion() event handler could not be called
// in that case moving the mouse out of the label vertically...
if (m_rollover)
{
SetCursor(*wxSTANDARD_CURSOR);
SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
m_rollover = false;
Refresh();
@@ -229,4 +277,11 @@ void wxHyperlinkCtrl::OnPopUpCopy( wxCommandEvent& WXUNUSED(event) )
#endif // wxUSE_CLIPBOARD
}
void wxHyperlinkCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
{
// update the position of the label in the screen respecting
// the selected align flag
Refresh();
}
#endif // wxUSE_HYPERLINKCTRL