Fixed tab selection bug
Slight improvement to kerning-related jumpy text when selecting Default tab efficiency improvement and naming conventions cleanup git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41987 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
9654efd332
commit
cfa3b25626
@ -1205,9 +1205,21 @@ public:
|
|||||||
/// Get combined attributes of the base style and paragraph style.
|
/// Get combined attributes of the base style and paragraph style.
|
||||||
wxTextAttrEx GetCombinedAttributes() const;
|
wxTextAttrEx GetCombinedAttributes() const;
|
||||||
|
|
||||||
|
/// Create default tabstop array
|
||||||
|
static void InitDefaultTabs();
|
||||||
|
|
||||||
|
/// Clear default tabstop array
|
||||||
|
static void ClearDefaultTabs();
|
||||||
|
|
||||||
|
/// Get default tabstop array
|
||||||
|
static const wxArrayInt& GetDefaultTabs() { return sm_defaultTabs; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// The lines that make up the wrapped paragraph
|
/// The lines that make up the wrapped paragraph
|
||||||
wxRichTextLineList m_cachedLines;
|
wxRichTextLineList m_cachedLines;
|
||||||
|
|
||||||
|
/// Default tabstops
|
||||||
|
static wxArrayInt sm_defaultTabs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -2433,6 +2433,8 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraph, wxRichTextBox)
|
IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraph, wxRichTextBox)
|
||||||
|
|
||||||
|
wxArrayInt wxRichTextParagraph::sm_defaultTabs;
|
||||||
|
|
||||||
wxRichTextParagraph::wxRichTextParagraph(wxRichTextObject* parent, wxTextAttrEx* style):
|
wxRichTextParagraph::wxRichTextParagraph(wxRichTextObject* parent, wxTextAttrEx* style):
|
||||||
wxRichTextBox(parent)
|
wxRichTextBox(parent)
|
||||||
{
|
{
|
||||||
@ -3482,6 +3484,23 @@ wxTextAttrEx wxRichTextParagraph::GetCombinedAttributes() const
|
|||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create default tabstop array
|
||||||
|
void wxRichTextParagraph::InitDefaultTabs()
|
||||||
|
{
|
||||||
|
// create a default tab list at 10 mm each.
|
||||||
|
for (int i = 0; i < 20; ++i)
|
||||||
|
{
|
||||||
|
sm_defaultTabs.Add(i*100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear default tabstop array
|
||||||
|
void wxRichTextParagraph::ClearDefaultTabs()
|
||||||
|
{
|
||||||
|
sm_defaultTabs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* wxRichTextLine
|
* wxRichTextLine
|
||||||
* This object represents a line in a paragraph, and stores
|
* This object represents a line in a paragraph, and stores
|
||||||
@ -3542,6 +3561,8 @@ wxRichTextPlainText::wxRichTextPlainText(const wxString& text, wxRichTextObject*
|
|||||||
m_text = text;
|
m_text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define USE_KERNING_FIX 1
|
||||||
|
|
||||||
/// Draw the item
|
/// Draw the item
|
||||||
bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int WXUNUSED(style))
|
bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int WXUNUSED(style))
|
||||||
{
|
{
|
||||||
@ -3599,6 +3620,23 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
|
|||||||
wxString stringFragment = m_text.Mid(r1 - offset, fragmentLen);
|
wxString stringFragment = m_text.Mid(r1 - offset, fragmentLen);
|
||||||
|
|
||||||
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
|
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false);
|
||||||
|
|
||||||
|
#if USE_KERNING_FIX
|
||||||
|
if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
// Compensate for kerning difference
|
||||||
|
wxString stringFragment2(m_text.Mid(r1 - offset, fragmentLen+1));
|
||||||
|
wxString stringFragment3(m_text.Mid(r1 - offset + fragmentLen, 1));
|
||||||
|
|
||||||
|
wxCoord w1, h1, w2, h2, w3, h3;
|
||||||
|
dc.GetTextExtent(stringFragment, & w1, & h1);
|
||||||
|
dc.GetTextExtent(stringFragment2, & w2, & h2);
|
||||||
|
dc.GetTextExtent(stringFragment3, & w3, & h3);
|
||||||
|
|
||||||
|
int kerningDiff = (w1 + w3) - w2;
|
||||||
|
x = x - kerningDiff;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Selected chunk, if any.
|
// 2. Selected chunk, if any.
|
||||||
@ -3613,6 +3651,23 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
|
|||||||
wxString stringFragment = m_text.Mid(s1 - offset, fragmentLen);
|
wxString stringFragment = m_text.Mid(s1 - offset, fragmentLen);
|
||||||
|
|
||||||
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true);
|
DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true);
|
||||||
|
|
||||||
|
#if USE_KERNING_FIX
|
||||||
|
if (stringChunk.Find(wxT("\t")) == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
// Compensate for kerning difference
|
||||||
|
wxString stringFragment2(m_text.Mid(s1 - offset, fragmentLen+1));
|
||||||
|
wxString stringFragment3(m_text.Mid(s1 - offset + fragmentLen, 1));
|
||||||
|
|
||||||
|
wxCoord w1, h1, w2, h2, w3, h3;
|
||||||
|
dc.GetTextExtent(stringFragment, & w1, & h1);
|
||||||
|
dc.GetTextExtent(stringFragment2, & w2, & h2);
|
||||||
|
dc.GetTextExtent(stringFragment3, & w3, & h3);
|
||||||
|
|
||||||
|
int kerningDiff = (w1 + w3) - w2;
|
||||||
|
x = x - kerningDiff;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Remaining unselected chunk, if any
|
// 3. Remaining unselected chunk, if any
|
||||||
@ -3635,26 +3690,30 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR
|
|||||||
|
|
||||||
bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, const wxRect& rect,wxString& str, wxCoord& x, wxCoord& y, bool selected)
|
bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, const wxRect& rect,wxString& str, wxCoord& x, wxCoord& y, bool selected)
|
||||||
{
|
{
|
||||||
wxArrayInt tab_array = attr.GetTabs();
|
bool hasTabs = (str.Find(wxT('\t')) != wxNOT_FOUND);
|
||||||
if (tab_array.IsEmpty())
|
|
||||||
{
|
|
||||||
// create a default tab list at 10 mm each.
|
|
||||||
for (int i = 0; i < 20; ++i)
|
|
||||||
{
|
|
||||||
tab_array.Add(i*100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int map_mode = dc.GetMapMode();
|
|
||||||
dc.SetMapMode(wxMM_LOMETRIC );
|
|
||||||
int num_tabs = tab_array.GetCount();
|
|
||||||
for (int i = 0; i < num_tabs; ++i)
|
|
||||||
{
|
|
||||||
tab_array[i] = dc.LogicalToDeviceXRel(tab_array[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dc.SetMapMode(map_mode );
|
wxArrayInt tabArray;
|
||||||
int next_tab_pos = -1;
|
int tabCount;
|
||||||
int tab_pos = -1;
|
if (hasTabs)
|
||||||
|
{
|
||||||
|
if (attr.GetTabs().IsEmpty())
|
||||||
|
tabArray = wxRichTextParagraph::GetDefaultTabs();
|
||||||
|
else
|
||||||
|
tabArray = attr.GetTabs();
|
||||||
|
tabCount = tabArray.GetCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < tabCount; ++i)
|
||||||
|
{
|
||||||
|
int pos = tabArray[i];
|
||||||
|
pos = ConvertTenthsMMToPixels(dc, pos);
|
||||||
|
tabArray[i] = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tabCount = 0;
|
||||||
|
|
||||||
|
int nextTabPos = -1;
|
||||||
|
int tabPos = -1;
|
||||||
wxCoord w, h;
|
wxCoord w, h;
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
@ -3670,33 +3729,36 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, c
|
|||||||
dc.SetBackgroundMode(wxTRANSPARENT);
|
dc.SetBackgroundMode(wxTRANSPARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (str.Find(wxT('\t')) >= 0)
|
while (hasTabs)
|
||||||
{
|
{
|
||||||
// the string has a tab
|
// the string has a tab
|
||||||
// break up the string at the Tab
|
// break up the string at the Tab
|
||||||
wxString stringChunk = str.BeforeFirst(wxT('\t'));
|
wxString stringChunk = str.BeforeFirst(wxT('\t'));
|
||||||
str = str.AfterFirst(wxT('\t'));
|
str = str.AfterFirst(wxT('\t'));
|
||||||
dc.GetTextExtent(stringChunk, & w, & h);
|
dc.GetTextExtent(stringChunk, & w, & h);
|
||||||
tab_pos = x + w;
|
tabPos = x + w;
|
||||||
bool not_found = true;
|
bool not_found = true;
|
||||||
for (int i = 0; i < num_tabs && not_found; ++i)
|
for (int i = 0; i < tabCount && not_found; ++i)
|
||||||
{
|
{
|
||||||
next_tab_pos = tab_array.Item(i);
|
nextTabPos = tabArray.Item(i);
|
||||||
if (next_tab_pos > tab_pos)
|
if (nextTabPos > tabPos)
|
||||||
{
|
{
|
||||||
not_found = false;
|
not_found = false;
|
||||||
if (selected)
|
if (selected)
|
||||||
{
|
{
|
||||||
w = next_tab_pos - x;
|
w = nextTabPos - x;
|
||||||
wxRect selRect(x, rect.y, w, rect.GetHeight());
|
wxRect selRect(x, rect.y, w, rect.GetHeight());
|
||||||
dc.DrawRectangle(selRect);
|
dc.DrawRectangle(selRect);
|
||||||
}
|
}
|
||||||
dc.DrawText(stringChunk, x, y);
|
dc.DrawText(stringChunk, x, y);
|
||||||
x = next_tab_pos;
|
x = nextTabPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hasTabs = (str.Find(wxT('\t')) != wxNOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!str.IsEmpty())
|
||||||
|
{
|
||||||
dc.GetTextExtent(str, & w, & h);
|
dc.GetTextExtent(str, & w, & h);
|
||||||
if (selected)
|
if (selected)
|
||||||
{
|
{
|
||||||
@ -3705,6 +3767,7 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, c
|
|||||||
}
|
}
|
||||||
dc.DrawText(str, x, y);
|
dc.DrawText(str, x, y);
|
||||||
x += w;
|
x += w;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3767,29 +3830,25 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
wxString stringChunk = m_text.Mid(startPos, (size_t) len);
|
wxString stringChunk = m_text.Mid(startPos, (size_t) len);
|
||||||
wxCoord w, h;
|
wxCoord w, h;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
if (stringChunk.Find(wxT('\t')) >= 0)
|
if (stringChunk.Find(wxT('\t')) != wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
// the string has a tab
|
// the string has a tab
|
||||||
wxArrayInt tab_array = textAttr.GetTabs();
|
wxArrayInt tabArray;
|
||||||
if (tab_array.IsEmpty())
|
if (textAttr.GetTabs().IsEmpty())
|
||||||
|
tabArray = wxRichTextParagraph::GetDefaultTabs();
|
||||||
|
else
|
||||||
|
tabArray = textAttr.GetTabs();
|
||||||
|
|
||||||
|
int tabCount = tabArray.GetCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < tabCount; ++i)
|
||||||
{
|
{
|
||||||
// create a default tab list at 10 mm each.
|
int pos = tabArray[i];
|
||||||
for (int i = 0; i < 20; ++i)
|
pos = ((wxRichTextPlainText*) this)->ConvertTenthsMMToPixels(dc, pos);
|
||||||
{
|
tabArray[i] = pos;
|
||||||
tab_array.Add(i*100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int map_mode = dc.GetMapMode();
|
int nextTabPos = -1;
|
||||||
dc.SetMapMode(wxMM_LOMETRIC );
|
|
||||||
int num_tabs = tab_array.GetCount();
|
|
||||||
|
|
||||||
for (int i = 0; i < num_tabs; ++i)
|
|
||||||
{
|
|
||||||
tab_array[i] = dc.LogicalToDeviceXRel(tab_array[i]);
|
|
||||||
}
|
|
||||||
dc.SetMapMode(map_mode );
|
|
||||||
int next_tab_pos = -1;
|
|
||||||
|
|
||||||
while (stringChunk.Find(wxT('\t')) >= 0)
|
while (stringChunk.Find(wxT('\t')) >= 0)
|
||||||
{
|
{
|
||||||
@ -3799,15 +3858,15 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
stringChunk = stringChunk.AfterFirst(wxT('\t'));
|
stringChunk = stringChunk.AfterFirst(wxT('\t'));
|
||||||
dc.GetTextExtent(stringFragment, & w, & h);
|
dc.GetTextExtent(stringFragment, & w, & h);
|
||||||
width += w;
|
width += w;
|
||||||
int absolute_width = width + position.x;
|
int absoluteWidth = width + position.x;
|
||||||
bool not_found = true;
|
bool notFound = true;
|
||||||
for (int i = 0; i < num_tabs && not_found; ++i)
|
for (int i = 0; i < tabCount && notFound; ++i)
|
||||||
{
|
{
|
||||||
next_tab_pos = tab_array.Item(i);
|
nextTabPos = tabArray.Item(i);
|
||||||
if (next_tab_pos > absolute_width)
|
if (nextTabPos > absoluteWidth)
|
||||||
{
|
{
|
||||||
not_found = false;
|
notFound = false;
|
||||||
width = next_tab_pos - position.x;
|
width = nextTabPos - position.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4858,8 +4917,18 @@ class wxRichTextModule: public wxModule
|
|||||||
DECLARE_DYNAMIC_CLASS(wxRichTextModule)
|
DECLARE_DYNAMIC_CLASS(wxRichTextModule)
|
||||||
public:
|
public:
|
||||||
wxRichTextModule() {}
|
wxRichTextModule() {}
|
||||||
bool OnInit() { wxRichTextBuffer::InitStandardHandlers(); return true; };
|
bool OnInit()
|
||||||
void OnExit() { wxRichTextBuffer::CleanUpHandlers(); wxRichTextDecimalToRoman(-1); };
|
{
|
||||||
|
wxRichTextBuffer::InitStandardHandlers();
|
||||||
|
wxRichTextParagraph::InitDefaultTabs();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
void OnExit()
|
||||||
|
{
|
||||||
|
wxRichTextBuffer::CleanUpHandlers();
|
||||||
|
wxRichTextDecimalToRoman(-1);
|
||||||
|
wxRichTextParagraph::ClearDefaultTabs();
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRichTextModule, wxModule)
|
IMPLEMENT_DYNAMIC_CLASS(wxRichTextModule, wxModule)
|
||||||
|
Loading…
Reference in New Issue
Block a user