Merge branch 'misc-render-fixes' of https://github.com/discnl/wxWidgets
Fixes for rendering text with bottom/right alignment for wxMSW and not only. See https://github.com/wxWidgets/wxWidgets/pull/2446
This commit is contained in:
@@ -71,7 +71,8 @@ public:
|
|||||||
|
|
||||||
void BuildDataViewCtrl(wxPanel* parent,
|
void BuildDataViewCtrl(wxPanel* parent,
|
||||||
unsigned int nPanel,
|
unsigned int nPanel,
|
||||||
unsigned long style = 0);
|
unsigned long style = 0,
|
||||||
|
int modelFlags = wxALIGN_CENTRE);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// event handlers
|
// event handlers
|
||||||
@@ -167,6 +168,13 @@ private:
|
|||||||
enum Lang { Lang_English, Lang_French };
|
enum Lang { Lang_English, Lang_French };
|
||||||
void FillIndexList(Lang lang);
|
void FillIndexList(Lang lang);
|
||||||
|
|
||||||
|
// Helper for checking ModelFlags of current panel (either currently
|
||||||
|
// building or selected one).
|
||||||
|
bool HasModelFlag(int flag) const
|
||||||
|
{
|
||||||
|
return (m_modelFlags[m_currentPanel] & flag) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// HasValue page.
|
// HasValue page.
|
||||||
void OnHasValueValueChanged(wxDataViewEvent& event);
|
void OnHasValueValueChanged(wxDataViewEvent& event);
|
||||||
|
|
||||||
@@ -186,7 +194,9 @@ private:
|
|||||||
Page_Max
|
Page_Max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int m_currentPanel;
|
||||||
wxDataViewCtrl* m_ctrl[Page_Max];
|
wxDataViewCtrl* m_ctrl[Page_Max];
|
||||||
|
int m_modelFlags[Page_Max];
|
||||||
|
|
||||||
// Some of the models associated with the controls:
|
// Some of the models associated with the controls:
|
||||||
|
|
||||||
@@ -406,6 +416,18 @@ enum
|
|||||||
ID_HORIZ_RULES,
|
ID_HORIZ_RULES,
|
||||||
ID_VERT_RULES,
|
ID_VERT_RULES,
|
||||||
|
|
||||||
|
ID_ALIGN_LEFT,
|
||||||
|
ID_ALIGN_CENTRE_H,
|
||||||
|
ID_ALIGN_RIGHT,
|
||||||
|
|
||||||
|
ID_ALIGN_TOP,
|
||||||
|
ID_ALIGN_CENTRE_V,
|
||||||
|
ID_ALIGN_BOTTOM,
|
||||||
|
|
||||||
|
ID_TOGGLE_USE_TALL_ROWS,
|
||||||
|
ID_TOGGLE_KEEP_LOGO_SMALL,
|
||||||
|
ID_TOGGLE_USE_MULTI_LINE_TEXT,
|
||||||
|
|
||||||
ID_EXIT = wxID_EXIT,
|
ID_EXIT = wxID_EXIT,
|
||||||
|
|
||||||
// about menu
|
// about menu
|
||||||
@@ -449,7 +471,8 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_MENU_RANGE( ID_MULTIPLE, ID_VERT_RULES, MyFrame::OnStyleChange )
|
EVT_MENU_RANGE( ID_MULTIPLE, ID_TOGGLE_USE_MULTI_LINE_TEXT,
|
||||||
|
MyFrame::OnStyleChange )
|
||||||
EVT_MENU( ID_EXIT, MyFrame::OnQuit )
|
EVT_MENU( ID_EXIT, MyFrame::OnQuit )
|
||||||
EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
|
EVT_MENU( ID_ABOUT, MyFrame::OnAbout )
|
||||||
EVT_MENU( ID_CLEARLOG, MyFrame::OnClearLog )
|
EVT_MENU( ID_CLEARLOG, MyFrame::OnClearLog )
|
||||||
@@ -552,6 +575,23 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
|
|||||||
style_menu->AppendCheckItem(ID_HORIZ_RULES, "Display horizontal rules");
|
style_menu->AppendCheckItem(ID_HORIZ_RULES, "Display horizontal rules");
|
||||||
style_menu->AppendCheckItem(ID_VERT_RULES, "Display vertical rules");
|
style_menu->AppendCheckItem(ID_VERT_RULES, "Display vertical rules");
|
||||||
|
|
||||||
|
wxMenu* align_menu = new wxMenu;
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_LEFT, "Left\tCtrl-1");
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_CENTRE_H, "Centre Horizontal\tCtrl-2");
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_RIGHT, "Right\tCtrl-3");
|
||||||
|
align_menu->AppendSeparator();
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_TOP, "Top\tCtrl-4");
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_CENTRE_V, "Centre Vertical\tCtrl-5");
|
||||||
|
align_menu->AppendRadioItem(ID_ALIGN_BOTTOM, "Bottom\tCtrl-6");
|
||||||
|
|
||||||
|
wxMenu* size_menu = new wxMenu;
|
||||||
|
size_menu->AppendCheckItem(ID_TOGGLE_USE_TALL_ROWS,
|
||||||
|
"Use Tall Rows\tCtrl-7");
|
||||||
|
size_menu->AppendCheckItem(ID_TOGGLE_KEEP_LOGO_SMALL,
|
||||||
|
"Keep Logo Size Small\tCtrl-8");
|
||||||
|
size_menu->AppendCheckItem(ID_TOGGLE_USE_MULTI_LINE_TEXT,
|
||||||
|
"Use Multi-line Text\tCtrl-9");
|
||||||
|
|
||||||
wxMenu *file_menu = new wxMenu;
|
wxMenu *file_menu = new wxMenu;
|
||||||
file_menu->Append(ID_CLEARLOG, "&Clear log\tCtrl-L");
|
file_menu->Append(ID_CLEARLOG, "&Clear log\tCtrl-L");
|
||||||
file_menu->Append(ID_GET_PAGE_INFO, "Show current &page info");
|
file_menu->Append(ID_GET_PAGE_INFO, "Show current &page info");
|
||||||
@@ -563,6 +603,8 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
|
|||||||
file_menu->AppendCheckItem(ID_CUSTOM_HEADER_HEIGHT, "Custom header &height");
|
file_menu->AppendCheckItem(ID_CUSTOM_HEADER_HEIGHT, "Custom header &height");
|
||||||
#endif // wxHAS_GENERIC_DATAVIEWCTRL
|
#endif // wxHAS_GENERIC_DATAVIEWCTRL
|
||||||
file_menu->Append(ID_STYLE_MENU, "&Style", style_menu);
|
file_menu->Append(ID_STYLE_MENU, "&Style", style_menu);
|
||||||
|
file_menu->Append(wxID_ANY, "&Alignment", align_menu);
|
||||||
|
file_menu->Append(wxID_ANY, "Si&ze", size_menu);
|
||||||
file_menu->Append(ID_INC_INDENT, "&Increase indent\tCtrl-I");
|
file_menu->Append(ID_INC_INDENT, "&Increase indent\tCtrl-I");
|
||||||
file_menu->Append(ID_DEC_INDENT, "&Decrease indent\tShift-Ctrl-I");
|
file_menu->Append(ID_DEC_INDENT, "&Decrease indent\tShift-Ctrl-I");
|
||||||
file_menu->AppendSeparator();
|
file_menu->AppendSeparator();
|
||||||
@@ -749,10 +791,14 @@ MyFrame::~MyFrame()
|
|||||||
delete wxLog::SetActiveTarget(m_logOld);
|
delete wxLog::SetActiveTarget(m_logOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned long style)
|
void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel,
|
||||||
|
unsigned long style, int modelFlags)
|
||||||
{
|
{
|
||||||
wxASSERT(!m_ctrl[nPanel]); // should only be initialized once
|
wxASSERT(!m_ctrl[nPanel]); // should only be initialized once
|
||||||
|
|
||||||
|
m_currentPanel = nPanel;
|
||||||
|
m_modelFlags[nPanel] = modelFlags;
|
||||||
|
|
||||||
switch (nPanel)
|
switch (nPanel)
|
||||||
{
|
{
|
||||||
case Page_Music:
|
case Page_Music:
|
||||||
@@ -844,7 +890,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
|||||||
m_ctrl[Page_List] = new wxDataViewCtrl( parent, ID_ATTR_CTRL, wxDefaultPosition,
|
m_ctrl[Page_List] = new wxDataViewCtrl( parent, ID_ATTR_CTRL, wxDefaultPosition,
|
||||||
wxDefaultSize, style );
|
wxDefaultSize, style );
|
||||||
|
|
||||||
m_list_model = new MyListModel;
|
m_list_model = new MyListModel(modelFlags);
|
||||||
m_ctrl[Page_List]->AssociateModel( m_list_model.get() );
|
m_ctrl[Page_List]->AssociateModel( m_list_model.get() );
|
||||||
|
|
||||||
wxDataViewColumn* const colCheckIconText = new wxDataViewColumn
|
wxDataViewColumn* const colCheckIconText = new wxDataViewColumn
|
||||||
@@ -855,13 +901,17 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
|||||||
wxCOL_WIDTH_AUTOSIZE
|
wxCOL_WIDTH_AUTOSIZE
|
||||||
);
|
);
|
||||||
m_ctrl[Page_List]->AppendColumn(colCheckIconText);
|
m_ctrl[Page_List]->AppendColumn(colCheckIconText);
|
||||||
|
const int alignment = modelFlags & wxALIGN_MASK;
|
||||||
|
colCheckIconText->GetRenderer()->SetAlignment(alignment);
|
||||||
|
|
||||||
m_ctrl[Page_List]->AppendTextColumn("editable string",
|
wxDataViewColumn* const colEditable =
|
||||||
|
m_ctrl[Page_List]->AppendTextColumn("editable string",
|
||||||
MyListModel::Col_EditableText,
|
MyListModel::Col_EditableText,
|
||||||
wxDATAVIEW_CELL_EDITABLE,
|
wxDATAVIEW_CELL_EDITABLE,
|
||||||
wxCOL_WIDTH_AUTOSIZE,
|
wxCOL_WIDTH_AUTOSIZE,
|
||||||
wxALIGN_NOT,
|
wxALIGN_NOT,
|
||||||
wxDATAVIEW_COL_SORTABLE);
|
wxDATAVIEW_COL_SORTABLE);
|
||||||
|
colEditable->GetRenderer()->SetAlignment(alignment);
|
||||||
|
|
||||||
m_ctrl[Page_List]->AppendDateColumn("date",
|
m_ctrl[Page_List]->AppendDateColumn("date",
|
||||||
MyListModel::Col_Date);
|
MyListModel::Col_Date);
|
||||||
@@ -936,7 +986,11 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
|||||||
wxDefaultSize, style | wxDV_NO_HEADER );
|
wxDefaultSize, style | wxDV_NO_HEADER );
|
||||||
m_ctrl[Page_TreeStore] = tc;
|
m_ctrl[Page_TreeStore] = tc;
|
||||||
|
|
||||||
wxImageList *ilist = new wxImageList( 16, 16 );
|
const bool useDefaultSize = !HasModelFlag(MODEL_USE_TALL_ROWS)
|
||||||
|
|| HasModelFlag(MODEL_KEEP_LOGO_SMALL);
|
||||||
|
const int imageSize = useDefaultSize ? 16 : 32;
|
||||||
|
wxImageList *ilist = new wxImageList( imageSize, imageSize );
|
||||||
|
|
||||||
ilist->Add( wxIcon(wx_small_xpm) );
|
ilist->Add( wxIcon(wx_small_xpm) );
|
||||||
tc->AssignImageList( ilist );
|
tc->AssignImageList( ilist );
|
||||||
|
|
||||||
@@ -1045,6 +1099,8 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( HasModelFlag(MODEL_USE_TALL_ROWS) )
|
||||||
|
m_ctrl[nPanel]->SetRowHeight(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1158,6 +1214,7 @@ void MyFrame::OnDecIndent(wxCommandEvent& WXUNUSED(event))
|
|||||||
void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
|
void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
|
||||||
{
|
{
|
||||||
unsigned int nPanel = m_notebook->GetSelection();
|
unsigned int nPanel = m_notebook->GetSelection();
|
||||||
|
m_currentPanel = nPanel;
|
||||||
|
|
||||||
GetMenuBar()->FindItem(ID_STYLE_MENU)->SetItemLabel(
|
GetMenuBar()->FindItem(ID_STYLE_MENU)->SetItemLabel(
|
||||||
wxString::Format("Style of panel #%d", nPanel+1));
|
wxString::Format("Style of panel #%d", nPanel+1));
|
||||||
@@ -1189,6 +1246,49 @@ void MyFrame::OnPageChanged( wxBookCtrlEvent& WXUNUSED(event) )
|
|||||||
GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
|
GetMenuBar()->FindItem(id)->Check( m_ctrl[nPanel]->HasFlag(style) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int modelFlags = m_modelFlags[nPanel];
|
||||||
|
|
||||||
|
for (unsigned int id = ID_ALIGN_LEFT; id <= ID_ALIGN_BOTTOM; ++id)
|
||||||
|
{
|
||||||
|
int align = wxALIGN_NOT;
|
||||||
|
bool check = false;
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case ID_ALIGN_LEFT:
|
||||||
|
check = !(modelFlags & (wxALIGN_CENTRE_HORIZONTAL | wxALIGN_RIGHT));
|
||||||
|
break;
|
||||||
|
case ID_ALIGN_CENTRE_H:
|
||||||
|
align = wxALIGN_CENTRE_HORIZONTAL;
|
||||||
|
break;
|
||||||
|
case ID_ALIGN_RIGHT:
|
||||||
|
align = wxALIGN_RIGHT;
|
||||||
|
break;
|
||||||
|
case ID_ALIGN_TOP:
|
||||||
|
check = !(modelFlags & (wxALIGN_CENTRE_VERTICAL | wxALIGN_BOTTOM));
|
||||||
|
break;
|
||||||
|
case ID_ALIGN_CENTRE_V:
|
||||||
|
align = wxALIGN_CENTRE_VERTICAL;
|
||||||
|
break;
|
||||||
|
case ID_ALIGN_BOTTOM:
|
||||||
|
align = wxALIGN_BOTTOM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wxFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( align != wxALIGN_NOT )
|
||||||
|
check = (modelFlags & align) != 0;
|
||||||
|
|
||||||
|
GetMenuBar()->FindItem(id)->Check(check);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetMenuBar()->FindItem(ID_TOGGLE_USE_TALL_ROWS)->Check(
|
||||||
|
HasModelFlag(MODEL_USE_TALL_ROWS));
|
||||||
|
GetMenuBar()->FindItem(ID_TOGGLE_KEEP_LOGO_SMALL)->Check(
|
||||||
|
HasModelFlag(MODEL_KEEP_LOGO_SMALL));
|
||||||
|
GetMenuBar()->FindItem(ID_TOGGLE_USE_MULTI_LINE_TEXT)->Check(
|
||||||
|
HasModelFlag(MODEL_USE_MULTI_LINE_TEXT));
|
||||||
|
|
||||||
GetMenuBar()->FindItem(ID_DISABLE)->Check(!m_ctrl[nPanel]->IsEnabled());
|
GetMenuBar()->FindItem(ID_DISABLE)->Check(!m_ctrl[nPanel]->IsEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1223,8 +1323,26 @@ void MyFrame::OnStyleChange( wxCommandEvent& WXUNUSED(event) )
|
|||||||
else if (nPanel == 4)
|
else if (nPanel == 4)
|
||||||
m_long_music_model.reset(NULL);
|
m_long_music_model.reset(NULL);
|
||||||
|
|
||||||
|
int flags = 0;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_ALIGN_CENTRE_H)->IsChecked() )
|
||||||
|
flags |= wxALIGN_CENTRE_HORIZONTAL;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_ALIGN_RIGHT)->IsChecked() )
|
||||||
|
flags |= wxALIGN_RIGHT;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_ALIGN_CENTRE_V)->IsChecked() )
|
||||||
|
flags |= wxALIGN_CENTRE_VERTICAL;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_ALIGN_BOTTOM)->IsChecked() )
|
||||||
|
flags |= wxALIGN_BOTTOM;
|
||||||
|
|
||||||
|
if ( GetMenuBar()->FindItem(ID_TOGGLE_USE_TALL_ROWS)->IsChecked() )
|
||||||
|
flags |= MODEL_USE_TALL_ROWS;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_TOGGLE_KEEP_LOGO_SMALL)->IsChecked() )
|
||||||
|
flags |= MODEL_KEEP_LOGO_SMALL;
|
||||||
|
if ( GetMenuBar()->FindItem(ID_TOGGLE_USE_MULTI_LINE_TEXT)->IsChecked() )
|
||||||
|
flags |= MODEL_USE_MULTI_LINE_TEXT;
|
||||||
|
|
||||||
// rebuild the DVC for the selected panel:
|
// rebuild the DVC for the selected panel:
|
||||||
BuildDataViewCtrl((wxPanel*)m_notebook->GetPage(nPanel), nPanel, style);
|
BuildDataViewCtrl((wxPanel*)m_notebook->GetPage(nPanel),
|
||||||
|
nPanel, style, flags);
|
||||||
|
|
||||||
sz->Prepend(m_ctrl[nPanel], 1, wxGROW|wxALL, 5);
|
sz->Prepend(m_ctrl[nPanel], 1, wxGROW|wxALL, 5);
|
||||||
sz->Layout();
|
sz->Layout();
|
||||||
|
@@ -339,9 +339,12 @@ static int my_sort( int *v1, int *v2 )
|
|||||||
|
|
||||||
#define INITIAL_NUMBER_OF_ITEMS 10000
|
#define INITIAL_NUMBER_OF_ITEMS 10000
|
||||||
|
|
||||||
MyListModel::MyListModel() :
|
MyListModel::MyListModel(int modelFlags) :
|
||||||
wxDataViewVirtualListModel( INITIAL_NUMBER_OF_ITEMS )
|
wxDataViewVirtualListModel( INITIAL_NUMBER_OF_ITEMS )
|
||||||
{
|
{
|
||||||
|
const wxString multiLineText = L"top (\u1ED6)\ncentre\nbottom (g)";
|
||||||
|
const bool useMultiLine = (modelFlags & MODEL_USE_MULTI_LINE_TEXT) != 0;
|
||||||
|
|
||||||
// the first 100 items are really stored in this model;
|
// the first 100 items are really stored in this model;
|
||||||
// all the others are synthesized on request
|
// all the others are synthesized on request
|
||||||
static const unsigned NUMBER_REAL_ITEMS = 100;
|
static const unsigned NUMBER_REAL_ITEMS = 100;
|
||||||
@@ -349,17 +352,32 @@ MyListModel::MyListModel() :
|
|||||||
m_toggleColValues.reserve(NUMBER_REAL_ITEMS);
|
m_toggleColValues.reserve(NUMBER_REAL_ITEMS);
|
||||||
m_textColValues.reserve(NUMBER_REAL_ITEMS);
|
m_textColValues.reserve(NUMBER_REAL_ITEMS);
|
||||||
m_toggleColValues.push_back(false);
|
m_toggleColValues.push_back(false);
|
||||||
m_textColValues.push_back("first row with long label to test ellipsization");
|
m_textColValues.push_back(useMultiLine
|
||||||
|
? multiLineText
|
||||||
|
: wxString("first row with long label to test ellipsization"));
|
||||||
for (unsigned int i = 1; i < NUMBER_REAL_ITEMS; i++)
|
for (unsigned int i = 1; i < NUMBER_REAL_ITEMS; i++)
|
||||||
{
|
{
|
||||||
m_toggleColValues.push_back(false);
|
m_toggleColValues.push_back(false);
|
||||||
m_textColValues.push_back(wxString::Format("real row %d", i));
|
m_textColValues.push_back(wxString::Format("real row %d", i));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_iconColValues.assign(NUMBER_REAL_ITEMS, "test");
|
m_iconColValues.assign(NUMBER_REAL_ITEMS,
|
||||||
|
useMultiLine ? multiLineText : wxString("test"));
|
||||||
|
|
||||||
m_icon[0] = wxIcon( null_xpm );
|
m_icon[0] = wxIcon( null_xpm );
|
||||||
m_icon[1] = wxIcon( wx_small_xpm );
|
|
||||||
|
const int newSize = m_icon[0].GetWidth() * 2;
|
||||||
|
const bool useTallRows = (modelFlags & MODEL_USE_TALL_ROWS) != 0;
|
||||||
|
|
||||||
|
if ( useTallRows )
|
||||||
|
m_icon[0].CopyFromBitmap(
|
||||||
|
wxImage(null_xpm).Rescale(newSize, newSize));
|
||||||
|
|
||||||
|
if ( !useTallRows || (modelFlags & MODEL_KEEP_LOGO_SMALL) )
|
||||||
|
m_icon[1] = wxIcon( wx_small_xpm );
|
||||||
|
else
|
||||||
|
m_icon[1].CopyFromBitmap(
|
||||||
|
wxImage(wx_small_xpm).Rescale(newSize, newSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyListModel::Prepend( const wxString &text )
|
void MyListModel::Prepend( const wxString &text )
|
||||||
|
@@ -216,7 +216,7 @@ public:
|
|||||||
Col_Max
|
Col_Max
|
||||||
};
|
};
|
||||||
|
|
||||||
MyListModel();
|
MyListModel(int modelFlags);
|
||||||
|
|
||||||
// helper methods to change the model
|
// helper methods to change the model
|
||||||
|
|
||||||
@@ -310,3 +310,10 @@ private:
|
|||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(MyIndexListModel);
|
wxDECLARE_NO_COPY_CLASS(MyIndexListModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ModelFlags
|
||||||
|
{
|
||||||
|
MODEL_USE_TALL_ROWS = 1 << 0,
|
||||||
|
MODEL_KEEP_LOGO_SMALL = 1 << 1,
|
||||||
|
MODEL_USE_MULTI_LINE_TEXT = 1 << 2
|
||||||
|
};
|
||||||
|
@@ -246,6 +246,26 @@ private:
|
|||||||
dc.DrawText("Using flags: " + flagsString, x1, y);
|
dc.DrawText("Using flags: " + flagsString, x1, y);
|
||||||
y += lineHeight*3;
|
y += lineHeight*3;
|
||||||
|
|
||||||
|
const wxCoord heightListItem = FromDIP(48);
|
||||||
|
const wxCoord widthListItem = 30*GetCharWidth();
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
dc.DrawText("DrawItemText() alignment", x1, y);
|
||||||
|
|
||||||
|
wxRect textRect(x2, y, widthListItem, heightListItem);
|
||||||
|
wxDCBrushChanger setBrush(dc, *wxTRANSPARENT_BRUSH);
|
||||||
|
wxDCPenChanger setPen(dc, *wxGREEN_PEN);
|
||||||
|
dc.DrawRectangle(textRect);
|
||||||
|
|
||||||
|
renderer.DrawItemText(this, dc, L"Top Left (\u1ED6)", textRect);
|
||||||
|
renderer.DrawItemText(this, dc, "Bottom right", textRect,
|
||||||
|
wxALIGN_BOTTOM | wxALIGN_RIGHT);
|
||||||
|
|
||||||
|
y += lineHeight + heightListItem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const wxCoord heightHdr = renderer.GetHeaderButtonHeight(this);
|
const wxCoord heightHdr = renderer.GetHeaderButtonHeight(this);
|
||||||
const wxCoord width = 15*GetCharWidth();
|
const wxCoord width = 15*GetCharWidth();
|
||||||
|
|
||||||
@@ -288,9 +308,15 @@ private:
|
|||||||
wxRect(wxPoint(x2, y), sizeMark), m_flags);
|
wxRect(wxPoint(x2, y), sizeMark), m_flags);
|
||||||
y += lineHeight + sizeMark.y;
|
y += lineHeight + sizeMark.y;
|
||||||
|
|
||||||
|
const wxString notImplementedText = "(generic version unimplemented)";
|
||||||
|
|
||||||
dc.DrawText("DrawRadioBitmap()", x1, y);
|
dc.DrawText("DrawRadioBitmap()", x1, y);
|
||||||
renderer.DrawRadioBitmap(this, dc,
|
if ( m_useGeneric )
|
||||||
wxRect(wxPoint(x2, y), sizeCheck), m_flags);
|
dc.DrawText(notImplementedText, x2, y);
|
||||||
|
else
|
||||||
|
renderer.DrawRadioBitmap(this, dc,
|
||||||
|
wxRect(wxPoint(x2, y), sizeCheck), m_flags);
|
||||||
|
|
||||||
y += lineHeight + sizeCheck.y;
|
y += lineHeight + sizeCheck.y;
|
||||||
|
|
||||||
dc.DrawText("DrawCollapseButton()", x1, y);
|
dc.DrawText("DrawCollapseButton()", x1, y);
|
||||||
@@ -340,9 +366,6 @@ private:
|
|||||||
|
|
||||||
y += lineHeight + heightGauge;
|
y += lineHeight + heightGauge;
|
||||||
|
|
||||||
const wxCoord heightListItem = FromDIP(48);
|
|
||||||
const wxCoord widthListItem = 30*GetCharWidth();
|
|
||||||
|
|
||||||
dc.DrawText("DrawItemSelectionRect()", x1, y);
|
dc.DrawText("DrawItemSelectionRect()", x1, y);
|
||||||
renderer.DrawItemSelectionRect(this, dc,
|
renderer.DrawItemSelectionRect(this, dc,
|
||||||
wxRect(x2, y, widthListItem, heightListItem), m_flags | wxCONTROL_SELECTED);
|
wxRect(x2, y, widthListItem, heightListItem), m_flags | wxCONTROL_SELECTED);
|
||||||
@@ -354,8 +377,11 @@ private:
|
|||||||
|
|
||||||
y += lineHeight;
|
y += lineHeight;
|
||||||
dc.DrawText("DrawChoice()", x1, y);
|
dc.DrawText("DrawChoice()", x1, y);
|
||||||
renderer.DrawChoice(this, dc,
|
if ( m_useGeneric )
|
||||||
wxRect(x2, y, width, 1.5*GetCharHeight()), m_flags);
|
dc.DrawText(notImplementedText, x2, y);
|
||||||
|
else
|
||||||
|
renderer.DrawChoice(this, dc,
|
||||||
|
wxRect(x2, y, width, 1.5*GetCharHeight()), m_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_flags;
|
int m_flags;
|
||||||
|
@@ -32,6 +32,10 @@
|
|||||||
#include "wx/access.h"
|
#include "wx/access.h"
|
||||||
#endif // wxUSE_ACCESSIBILITY
|
#endif // wxUSE_ACCESSIBILITY
|
||||||
|
|
||||||
|
// Uncomment this line to, for custom renderers, visually show the extent
|
||||||
|
// of both a cell and its item.
|
||||||
|
//#define DEBUG_RENDER_EXTENTS
|
||||||
|
|
||||||
const char wxDataViewCtrlNameStr[] = "dataviewCtrl";
|
const char wxDataViewCtrlNameStr[] = "dataviewCtrl";
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -1035,6 +1039,20 @@ wxDataViewCustomRendererBase::WXCallRender(wxRect rectCell, wxDC *dc, int state)
|
|||||||
if ( m_attr.HasFont() )
|
if ( m_attr.HasFont() )
|
||||||
changeFont.Set(m_attr.GetEffectiveFont(dc->GetFont()));
|
changeFont.Set(m_attr.GetEffectiveFont(dc->GetFont()));
|
||||||
|
|
||||||
|
#ifdef DEBUG_RENDER_EXTENTS
|
||||||
|
{
|
||||||
|
|
||||||
|
wxDCBrushChanger changeBrush(*dc, *wxTRANSPARENT_BRUSH);
|
||||||
|
wxDCPenChanger changePen(*dc, *wxRED);
|
||||||
|
|
||||||
|
dc->DrawRectangle(rectCell);
|
||||||
|
|
||||||
|
dc->SetPen(*wxGREEN);
|
||||||
|
dc->DrawRectangle(rectItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Render(rectItem, dc, state);
|
Render(rectItem, dc, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1072,17 +1090,12 @@ wxDataViewCustomRendererBase::RenderText(const wxString& text,
|
|||||||
if ( !(GetOwner()->GetOwner()->IsEnabled() && GetEnabled()) )
|
if ( !(GetOwner()->GetOwner()->IsEnabled() && GetEnabled()) )
|
||||||
flags |= wxCONTROL_DISABLED;
|
flags |= wxCONTROL_DISABLED;
|
||||||
|
|
||||||
// Notice that we intentionally don't use any alignment here: it is not
|
|
||||||
// necessary because the cell rectangle had been already adjusted to
|
|
||||||
// account for the alignment in WXCallRender() and using the alignment here
|
|
||||||
// results in problems with ellipsization when using native MSW renderer,
|
|
||||||
// see https://trac.wxwidgets.org/ticket/17363, so just don't do it.
|
|
||||||
wxRendererNative::Get().DrawItemText(
|
wxRendererNative::Get().DrawItemText(
|
||||||
GetOwner()->GetOwner(),
|
GetOwner()->GetOwner(),
|
||||||
*dc,
|
*dc,
|
||||||
text,
|
text,
|
||||||
rectText,
|
rectText,
|
||||||
wxALIGN_NOT,
|
GetEffectiveAlignment(),
|
||||||
flags,
|
flags,
|
||||||
GetEllipsizeMode());
|
GetEllipsizeMode());
|
||||||
}
|
}
|
||||||
|
@@ -1196,7 +1196,7 @@ void wxDC::DrawLabel(const wxString& text,
|
|||||||
wxCoord x, y;
|
wxCoord x, y;
|
||||||
if ( alignment & wxALIGN_RIGHT )
|
if ( alignment & wxALIGN_RIGHT )
|
||||||
{
|
{
|
||||||
x = rect.GetRight() - width;
|
x = rect.GetRight() - width + 1;
|
||||||
}
|
}
|
||||||
else if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
|
else if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
|
||||||
{
|
{
|
||||||
@@ -1209,7 +1209,7 @@ void wxDC::DrawLabel(const wxString& text,
|
|||||||
|
|
||||||
if ( alignment & wxALIGN_BOTTOM )
|
if ( alignment & wxALIGN_BOTTOM )
|
||||||
{
|
{
|
||||||
y = rect.GetBottom() - height;
|
y = rect.GetBottom() - height + 1;
|
||||||
}
|
}
|
||||||
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
|
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
|
||||||
{
|
{
|
||||||
|
@@ -1279,13 +1279,13 @@ void wxGCDCImpl::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( height )
|
if ( height )
|
||||||
*height = (wxCoord)wxRound(h);
|
*height = (wxCoord)ceil(h);
|
||||||
if ( descent )
|
if ( descent )
|
||||||
*descent = (wxCoord)wxRound(d);
|
*descent = (wxCoord)ceil(d);
|
||||||
if ( externalLeading )
|
if ( externalLeading )
|
||||||
*externalLeading = (wxCoord)wxRound(e);
|
*externalLeading = (wxCoord)ceil(e);
|
||||||
if ( width )
|
if ( width )
|
||||||
*width = (wxCoord)wxRound(w);
|
*width = (wxCoord)ceil(w);
|
||||||
|
|
||||||
if ( theFont )
|
if ( theFont )
|
||||||
{
|
{
|
||||||
|
@@ -1043,7 +1043,10 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
|||||||
const int itemState = GetListItemState(flags);
|
const int itemState = GetListItemState(flags);
|
||||||
|
|
||||||
typedef HRESULT(__stdcall *DrawThemeTextEx_t)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, RECT *, const WXDTTOPTS *);
|
typedef HRESULT(__stdcall *DrawThemeTextEx_t)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, RECT *, const WXDTTOPTS *);
|
||||||
|
typedef HRESULT(__stdcall *GetThemeTextExtent_t)(HTHEME, HDC, int, int, const wchar_t *, int, DWORD, RECT *, RECT *);
|
||||||
|
|
||||||
static DrawThemeTextEx_t s_DrawThemeTextEx = NULL;
|
static DrawThemeTextEx_t s_DrawThemeTextEx = NULL;
|
||||||
|
static GetThemeTextExtent_t s_GetThemeTextExtent = NULL;
|
||||||
static bool s_initDone = false;
|
static bool s_initDone = false;
|
||||||
|
|
||||||
if ( !s_initDone )
|
if ( !s_initDone )
|
||||||
@@ -1052,12 +1055,13 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
|||||||
{
|
{
|
||||||
wxLoadedDLL dllUxTheme(wxS("uxtheme.dll"));
|
wxLoadedDLL dllUxTheme(wxS("uxtheme.dll"));
|
||||||
wxDL_INIT_FUNC(s_, DrawThemeTextEx, dllUxTheme);
|
wxDL_INIT_FUNC(s_, DrawThemeTextEx, dllUxTheme);
|
||||||
|
wxDL_INIT_FUNC(s_, GetThemeTextExtent, dllUxTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_initDone = true;
|
s_initDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( s_DrawThemeTextEx && // Might be not available if we're under XP
|
if ( s_DrawThemeTextEx && // Not available under XP
|
||||||
::IsThemePartDefined(hTheme, LVP_LISTITEM, 0) )
|
::IsThemePartDefined(hTheme, LVP_LISTITEM, 0) )
|
||||||
{
|
{
|
||||||
RECT rc = ConvertToRECT(dc, rect);
|
RECT rc = ConvertToRECT(dc, rect);
|
||||||
@@ -1082,23 +1086,139 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
|||||||
textOpts.crText = textColour.GetPixel();
|
textOpts.crText = textColour.GetPixel();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD textFlags = DT_NOPREFIX;
|
const DWORD defTextFlags = DT_NOPREFIX;
|
||||||
|
DWORD textFlags = defTextFlags;
|
||||||
|
|
||||||
|
// Always use DT_* flags for horizontal alignment.
|
||||||
if ( align & wxALIGN_CENTER_HORIZONTAL )
|
if ( align & wxALIGN_CENTER_HORIZONTAL )
|
||||||
textFlags |= DT_CENTER;
|
textFlags |= DT_CENTER;
|
||||||
else if ( align & wxALIGN_RIGHT )
|
else if ( align & wxALIGN_RIGHT )
|
||||||
{
|
|
||||||
textFlags |= DT_RIGHT;
|
textFlags |= DT_RIGHT;
|
||||||
rc.right--; // Alignment is inconsistent with DrawLabel otherwise
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
textFlags |= DT_LEFT;
|
textFlags |= DT_LEFT;
|
||||||
|
|
||||||
if ( align & wxALIGN_BOTTOM )
|
/*
|
||||||
textFlags |= DT_BOTTOM;
|
Bottom (DT_BOTTOM) and centered vertical (DT_VCENTER) alignment
|
||||||
else if ( align & wxALIGN_CENTER_VERTICAL )
|
are documented to be only used with the DT_SINGLELINE flag which
|
||||||
textFlags |= DT_VCENTER;
|
doesn't handle multi-lines. In case of drawing multi-lines with
|
||||||
else
|
such alignment use DT_TOP (0), which does work for multi-lines,
|
||||||
textFlags |= DT_TOP;
|
and deal with the actual desired vertical alignment ourselves with
|
||||||
|
the help of GetThemeTextExtent().
|
||||||
|
|
||||||
|
[TODO] Ideally text measurement should only be needed for the above
|
||||||
|
mentioned situations but because there can be a difference between
|
||||||
|
the extent from GetThemeTextExtent() and the rect received by this
|
||||||
|
function could have involved other text measurements (e.g. with wxDVC,
|
||||||
|
see #18487), use it in all cases for now.
|
||||||
|
*/
|
||||||
|
bool useTopDrawing = false;
|
||||||
|
|
||||||
|
if ( s_GetThemeTextExtent != NULL )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Get the actual text extent using GetThemeTextExtent() and adjust
|
||||||
|
drawing rect if needed.
|
||||||
|
|
||||||
|
Note that DrawThemeTextEx() in combination with DT_CALCRECT
|
||||||
|
and DTT_CALCRECT can also be used to get the text extent.
|
||||||
|
This seems to always result in the exact same extent (checked
|
||||||
|
with an assert) as using GetThemeTextExtent(), despite having
|
||||||
|
an additional WXDTTOPTS argument for various effects.
|
||||||
|
Some effects have been tried (DTT_BORDERSIZE, DTT_SHADOWTYPE
|
||||||
|
and DTT_SHADOWOFFSET) and while rendered correctly with effects
|
||||||
|
the returned extent remains the same as without effects.
|
||||||
|
|
||||||
|
Official docs don't seem to prefer one method over the other
|
||||||
|
though a possibly outdated note for DrawThemeText() recommends
|
||||||
|
using GetThemeTextExtent(). Because Wine as of writing doesn't
|
||||||
|
support DT_CALCRECT with DrawThemeTextEx() while it does support
|
||||||
|
GetThemeTextExtent(), opt to use the latter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
It's important for the dwTextFlags parameter passed to
|
||||||
|
GetThemeTextExtent() not to have some DT_* flags because they
|
||||||
|
influence the extent size in unwanted ways: Using
|
||||||
|
DT_SINGLELINE combined with either DT_VCENTER or DT_BOTTOM
|
||||||
|
results in a height that can't be used (either halved or 0),
|
||||||
|
and having DT_END_ELLIPSIS ends up always ellipsizing.
|
||||||
|
Passing a non-NULL rect solves these problems but is not
|
||||||
|
really a good option as it doesn't make the rectangle extent
|
||||||
|
a tight fit and calculations would have to be done with large
|
||||||
|
numbers needlessly (provided the passed rect is set to
|
||||||
|
something like {0, 0, LONG_MAX, LONG_MAX} ).
|
||||||
|
*/
|
||||||
|
RECT rcExtent;
|
||||||
|
HRESULT hr = s_GetThemeTextExtent(hTheme, dc.GetHDC(),
|
||||||
|
LVP_LISTITEM, itemState, text.wchar_str(), -1,
|
||||||
|
defTextFlags, NULL, &rcExtent);
|
||||||
|
if ( SUCCEEDED(hr) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Compensate for rare cases where the horizontal extents differ
|
||||||
|
slightly. Don't use the width of the passed rect here to deal
|
||||||
|
with horizontal alignment as it results in the text always
|
||||||
|
fitting and ellipsization then can't occur. Instead check for
|
||||||
|
width differences by comparing with the extent as calculated
|
||||||
|
by wxDC.
|
||||||
|
*/
|
||||||
|
const int textWidthDc = dc.GetMultiLineTextExtent(text).x;
|
||||||
|
const int widthDiff = textWidthDc - rcExtent.right;
|
||||||
|
if ( widthDiff )
|
||||||
|
{
|
||||||
|
if ( align & wxALIGN_CENTRE_HORIZONTAL )
|
||||||
|
{
|
||||||
|
const int widthOffset = widthDiff / 2;
|
||||||
|
rc.left += widthOffset;
|
||||||
|
rc.right -= widthOffset;
|
||||||
|
}
|
||||||
|
else if ( align & wxALIGN_RIGHT )
|
||||||
|
rc.left += widthDiff;
|
||||||
|
else // left aligned
|
||||||
|
rc.right -= widthDiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
For height compare with the height of the passed rect and use
|
||||||
|
the difference for handling vertical alignment. This has
|
||||||
|
consequences for particularly multi-line text: it will now
|
||||||
|
always try to fit vertically while a rect received from wxDVC
|
||||||
|
may have its extent based on calculations for a single line
|
||||||
|
only and therefore couldn't show more than one line.
|
||||||
|
As a result of the expanded height clipping may be needed
|
||||||
|
which at least already happens with wxDVC which (out of
|
||||||
|
necessity) confines rendering to a cell's bounds.
|
||||||
|
*/
|
||||||
|
const int heightDiff = rect.GetHeight() - rcExtent.bottom;
|
||||||
|
if ( heightDiff
|
||||||
|
&& (align & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL))
|
||||||
|
&& text.Contains(wxS('\n')) )
|
||||||
|
{
|
||||||
|
useTopDrawing = true;
|
||||||
|
|
||||||
|
if ( align & wxALIGN_CENTRE_VERTICAL )
|
||||||
|
{
|
||||||
|
const int heightOffset = heightDiff / 2;
|
||||||
|
rc.top += heightOffset;
|
||||||
|
rc.bottom -= heightOffset;
|
||||||
|
}
|
||||||
|
else if ( align & wxALIGN_BOTTOM )
|
||||||
|
rc.top += heightDiff;
|
||||||
|
else // top aligned
|
||||||
|
rc.bottom -= heightDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !useTopDrawing )
|
||||||
|
{
|
||||||
|
if ( align & wxALIGN_BOTTOM )
|
||||||
|
textFlags |= DT_BOTTOM | DT_SINGLELINE;
|
||||||
|
else if ( align & wxALIGN_CENTER_VERTICAL )
|
||||||
|
textFlags |= DT_VCENTER | DT_SINGLELINE;
|
||||||
|
else
|
||||||
|
textFlags |= DT_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
const wxString* drawText = &text;
|
const wxString* drawText = &text;
|
||||||
wxString ellipsizedText;
|
wxString ellipsizedText;
|
||||||
|
@@ -185,7 +185,7 @@ void wxControlRenderer::DrawBitmap(wxDC &dc,
|
|||||||
{
|
{
|
||||||
if ( alignment & wxALIGN_RIGHT )
|
if ( alignment & wxALIGN_RIGHT )
|
||||||
{
|
{
|
||||||
x = rect.GetRight() - width;
|
x = rect.GetRight() - width + 1;
|
||||||
}
|
}
|
||||||
else if ( alignment & wxALIGN_CENTRE )
|
else if ( alignment & wxALIGN_CENTRE )
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ void wxControlRenderer::DrawBitmap(wxDC &dc,
|
|||||||
|
|
||||||
if ( alignment & wxALIGN_BOTTOM )
|
if ( alignment & wxALIGN_BOTTOM )
|
||||||
{
|
{
|
||||||
y = rect.GetBottom() - height;
|
y = rect.GetBottom() - height + 1;
|
||||||
}
|
}
|
||||||
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
|
else if ( alignment & wxALIGN_CENTRE_VERTICAL )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user