Skip to content

Commit 3afb493

Browse files
author
Koen Deforche
committed
reimplemented WAbstractItemView header item rendering, and various RTL layout issues
1 parent d22671e commit 3afb493

30 files changed

+343
-226
lines changed

Changelog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
19-10-2011:
2+
* WAbstractItemView: reimplemented and simplified header item rendering
3+
4+
* Wt.js: workaround browser bugs in scrollLeft reading in RTL mode, fixing WAbstractItemView column resizing in RTL layouts.
5+
16
12-10-2011:
27
* WRectF: fix isEmpty() to be more restrictive: only a rect with
38
width = 0 and height = 0 is now empty

cmake/WtFindPangoFt2.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
# We set:
2-
# - PANGO_FT2_INCLUDE_DIRS
3-
# - PANGO_FT2_LIBRARIES
4-
# - PANGO_FT2_FOUND
5-
# Taking into account:
6-
# - PANGO_FT2_PREFIX
7-
81
FIND_PACKAGE(PkgConfig)
92

103
PKG_CHECK_MODULES(PC_PANGO_FT2 pangoft2)

examples/dialog/DialogExample.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void DialogExample::messageBoxDone(StandardButton result)
143143
void DialogExample::custom()
144144
{
145145
WDialog dialog("Personalia");
146-
dialog.showCloseIcon();
146+
dialog.setClosable(true);
147147

148148
new WText("Enter your name: ", dialog.contents());
149149
WLineEdit edit(dialog.contents());

examples/treeview/TreeViewExample.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ TreeViewExample::TreeViewExample(WStandardItemModel *model,
4545
panel->setCentralWidget(treeView_ = new WTreeView());
4646
if (!WApplication::instance()->environment().ajax())
4747
treeView_->resize(WLength::Auto, 290);
48+
4849
treeView_->setAlternatingRowColors(true);
4950
treeView_->setRowHeight(25);
5051
treeView_->setModel(model_);

resources/themes/default/wt.css

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,11 +607,16 @@ body.Wt-rtl .Wt-tabs span {
607607
float: right;
608608
width: 4px;
609609
cursor: col-resize;
610-
padding-left: 0px;
611610
}
612611

613612
body.Wt-rtl .Wt-itemview div.Wt-tv-rh {
614-
float: left; padding-right: 0px;
613+
float: left;
614+
}
615+
616+
.Wt-itemview div.Wt-tv-no-rh {
617+
width: 0px;
618+
margin-left: 4px;
619+
cursor: default;
615620
}
616621

617622
/* sort handles */
@@ -702,6 +707,8 @@ body.Wt-rtl .Wt-tableview .Wt-header .Wt-tv-c {
702707
.Wt-tableview .Wt-tv-contents .Wt-tv-c,
703708
.Wt-plaintable .Wt-tv-c {
704709
padding: 0px 3px;
710+
overflow: hidden;
711+
text-overflow: ellipsis;
705712
}
706713

707714
.Wt-tableview .Wt-tv-contents img.icon,

resources/themes/polished/wt.css

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,14 @@
557557
height: 16px;
558558
}
559559

560+
body.Wt-rtl .Wt-tabs .item, body.Wt-rtl .Wt-tabs .itemselected,
561+
body.Wt-rtl .Wt-tabs .citem, body.Wt-rtl .Wt-tabs .citemselected {
562+
float: right;
563+
}
564+
560565
.Wt-tabs li a, .Wt-tabs li button {
561-
text-decoration: none;
562-
color: inherit;
566+
text-decoration: none;
567+
color: inherit;
563568
}
564569

565570
.Wt-tabs li button a {
@@ -702,11 +707,16 @@
702707
float: right;
703708
width: 4px;
704709
cursor: col-resize;
705-
padding-left: 0px;
706710
}
707711

708712
body.Wt-rtl .Wt-itemview div.Wt-tv-rh {
709-
float: left; padding-right: 0px;
713+
float: left;
714+
}
715+
716+
.Wt-itemview div.Wt-tv-no-rh {
717+
width: 0px;
718+
margin-left: 4px;
719+
cursor: default;
710720
}
711721

712722
/* sort handles */
@@ -801,6 +811,8 @@ body.Wt-rtl .Wt-tableview .Wt-header .Wt-tv-c {
801811
.Wt-tableview .Wt-tv-contents .Wt-tv-c,
802812
.Wt-plaintable .Wt-tv-c {
803813
padding: 0px 3px;
814+
overflow: hidden;
815+
text-overflow: ellipsis;
804816
}
805817

806818
.Wt-tableview .Wt-tv-contents img.icon,

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ IF(HAVE_PANGO)
315315
INCLUDE_DIRECTORIES(${PANGO_FT2_INCLUDE_DIRS})
316316
ADD_DEFINITIONS(-DHAVE_PANGO)
317317
MESSAGE("** Enabling advanced font support using libpango")
318+
ELSE(HAVE_PANGO)
319+
MESSAGE("** Disabling advanced font rendering support: requires libpango.")
320+
IF(ENABLE_PANGO)
321+
MESSAGE(" Wt will use pkg-config to retrieve your libpango installation location.")
322+
ENDIF(ENABLE_PANGO)
318323
ENDIF(HAVE_PANGO)
319324

320325
IF(MULTI_THREADED_BUILD)

src/Wt/Chart/WAxis.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ void WAxis::getLabelTicks(WChart2DRenderer& renderer,
810810

811811
double days = daysRange / numLabels;
812812

813-
enum { Days, Months, Years, Hours, Minutes } unit;
813+
enum { Minutes, Hours, Days, Months, Years } unit;
814814
int interval;
815815

816816
if (days > 200) {

src/Wt/WAbstractItemView

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,7 @@ protected:
882882

883883
virtual ColumnInfo createColumnInfo(int column) const;
884884

885+
void saveExtraHeaderWidgets();
885886
WWidget *createHeaderWidget(WApplication *app, int column);
886887
WText *headerTextWidget(int column);
887888

src/Wt/WAbstractItemView.C

Lines changed: 87 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -946,40 +946,43 @@ int WAbstractItemView::headerLevel(int column) const
946946
(asNumber(model_->headerData(column, Horizontal, LevelRole)));
947947
}
948948

949-
WWidget *WAbstractItemView::createHeaderWidget(WApplication *app, int column)
949+
void WAbstractItemView::saveExtraHeaderWidgets()
950950
{
951-
static const char *OneLine = "<div>&nbsp;</div>";
951+
for (int i = 0; i < columnCount(); ++i) {
952+
WWidget *w = columnInfo(i).extraHeaderWidget;
953+
if (w && w->parent())
954+
dynamic_cast<WContainerWidget *>(w->parent())->removeWidget(w);
955+
}
956+
}
952957

953-
int headerLevel = model_ ? this->headerLevel(column) : 0;
958+
WWidget *WAbstractItemView::createHeaderWidget(WApplication *app, int column)
959+
{
960+
/****
961+
* result:
962+
* +------------------------------+
963+
* | +----------------------+ +
964+
* | | +------------------+ | |
965+
* | | | contents | | |
966+
* | | +------------------+ | +-+ |
967+
* | | +------------------+ | | | |
968+
* | | | extra widget | | | <------ resize handle with border right and
969+
* | | | .... | | | | | margin-top for right-border-level
970+
* | | +------------------+ | | | |
971+
* | +----------------------+ +-+ |
972+
* +------------------------------+
973+
*/
954974

955-
int rightBorderLevel = headerLevel;
956-
if (model_) {
957-
int rightColumn = modelColumnIndex(visibleColumnIndex(column) + 1);
958-
if (rightColumn != -1) {
959-
WFlags<HeaderFlag> flagsLeft = model_->headerFlags(column);
960-
WFlags<HeaderFlag> flagsRight = model_->headerFlags(rightColumn);
961-
962-
int rightHeaderLevel = this->headerLevel(rightColumn);
975+
ColumnInfo& info = columnInfo(column);
963976

964-
if (flagsLeft & ColumnIsExpandedRight)
965-
rightBorderLevel = headerLevel + 1;
966-
else if (flagsRight & ColumnIsExpandedLeft)
967-
rightBorderLevel = rightHeaderLevel + 1;
968-
else
969-
rightBorderLevel = std::min(headerLevel, rightHeaderLevel);
970-
}
971-
}
977+
/* Contents */
972978

973-
ColumnInfo& info = columnInfo(column);
974-
WContainerWidget *w = new WContainerWidget();
975-
w->setObjectName("contents");
979+
WContainerWidget *contents = new WContainerWidget();
980+
contents->setObjectName("contents");
976981

977982
if (info.sorting) {
978-
WText *sortIcon = new WText(w);
983+
WText *sortIcon = new WText(contents);
979984
sortIcon->setObjectName("sort");
980985
sortIcon->setInline(false);
981-
if (!columnResize_)
982-
sortIcon->setMargin(4, Right);
983986
sortIcon->setStyleClass("Wt-tv-sh Wt-tv-sh-none");
984987
clickedForSortMapper_->mapConnect(sortIcon->clicked(), info.id);
985988

@@ -991,13 +994,13 @@ WWidget *WAbstractItemView::createHeaderWidget(WApplication *app, int column)
991994

992995
if (model_->headerFlags(column)
993996
& (ColumnIsExpandedLeft | ColumnIsExpandedRight)) {
994-
WImage *collapseIcon = new WImage(w);
997+
WImage *collapseIcon = new WImage(contents);
995998
collapseIcon->setFloatSide(Left);
996999
collapseIcon
9971000
->setImageLink(WLink(WApplication::resourcesUrl() + "minus.gif"));
9981001
clickedForCollapseMapper_->mapConnect(collapseIcon->clicked(), info.id);
9991002
} else if (model_->headerFlags(column) & ColumnIsCollapsed) {
1000-
WImage *expandIcon = new WImage(w);
1003+
WImage *expandIcon = new WImage(contents);
10011004
expandIcon->setFloatSide(Left);
10021005
expandIcon
10031006
->setImageLink(WLink(WApplication::resourcesUrl() + "plus.gif"));
@@ -1008,18 +1011,7 @@ WWidget *WAbstractItemView::createHeaderWidget(WApplication *app, int column)
10081011
0);
10091012
i->setInline(false);
10101013
i->addStyleClass("Wt-label");
1011-
w->addWidget(i);
1012-
1013-
/*
1014-
WText *t = new WText("&nbsp;", w);
1015-
t->setObjectName("text");
1016-
t->setStyleClass("Wt-label");
1017-
t->setInline(false);
1018-
if (multiLineHeader_ || app->environment().agentIsIE())
1019-
t->setWordWrap(true);
1020-
else
1021-
t->setWordWrap(false);
1022-
*/
1014+
contents->addWidget(i);
10231015

10241016
// FIXME: we probably want this as an API option ?
10251017
if (info.sorting) {
@@ -1028,68 +1020,75 @@ WWidget *WAbstractItemView::createHeaderWidget(WApplication *app, int column)
10281020
clickedForSortMapper_->mapConnect(ww->clicked(), info.id);
10291021
}
10301022

1031-
WContainerWidget *result = new WContainerWidget();
1023+
int headerLevel = model_ ? this->headerLevel(column) : 0;
10321024

1033-
if (headerLevel) {
1034-
WContainerWidget *spacer = new WContainerWidget(result);
1035-
WText *t = new WText(spacer);
1036-
t->setInline(false);
1037-
1038-
if (rightBorderLevel < headerLevel) {
1039-
if (rightBorderLevel) {
1040-
t->setText(repeat(OneLine, rightBorderLevel));
1041-
spacer = new WContainerWidget(result);
1042-
t = new WText(spacer);
1043-
t->setInline(false);
1044-
}
1045-
t->setText(repeat(OneLine, headerLevel - rightBorderLevel));
1046-
spacer->setStyleClass("Wt-tv-br");
1047-
} else {
1048-
t->setText(repeat(OneLine, headerLevel));
1025+
contents->setMargin(headerLevel * headerLineHeight_.toPixels(), Top);
1026+
1027+
/* Resize handle (or border-right 1 stub) */
1028+
1029+
int rightBorderLevel = headerLevel;
1030+
if (model_) {
1031+
int rightColumn = modelColumnIndex(visibleColumnIndex(column) + 1);
1032+
if (rightColumn != -1) {
1033+
WFlags<HeaderFlag> flagsLeft = model_->headerFlags(column);
1034+
WFlags<HeaderFlag> flagsRight = model_->headerFlags(rightColumn);
1035+
1036+
int rightHeaderLevel = this->headerLevel(rightColumn);
1037+
1038+
if (flagsLeft & ColumnIsExpandedRight)
1039+
rightBorderLevel = headerLevel + 1;
1040+
else if (flagsRight & ColumnIsExpandedLeft)
1041+
rightBorderLevel = rightHeaderLevel + 1;
1042+
else
1043+
rightBorderLevel = std::min(headerLevel, rightHeaderLevel);
10491044
}
10501045
}
10511046

1052-
if (rightBorderLevel <= headerLevel)
1053-
w->addStyleClass("Wt-tv-br");
1047+
bool activeRH = columnResize_;
10541048

1055-
result->addWidget(w);
1056-
result->setStyleClass(info.styleClass() + " Wt-tv-c headerrh");
1057-
result->setContentAlignment(info.headerHAlignment);
1049+
WContainerWidget *resizeHandle = new WContainerWidget();
1050+
resizeHandle->setStyleClass(std::string("Wt-tv-rh")
1051+
+ (activeRH ? "" : " Wt-tv-no-rh" )
1052+
+ " Wt-tv-br headerrh");
10581053

1059-
if (info.headerVAlignment == AlignMiddle)
1060-
result->setLineHeight(headerLineHeight_);
1061-
else {
1062-
result->setLineHeight(WLength::Auto);
1063-
if (info.headerWordWrap)
1064-
result->addStyleClass("Wt-wwrap");
1065-
}
1054+
if (activeRH)
1055+
resizeHandle->mouseWentDown().connect(resizeHandleMDownJS_);
1056+
1057+
resizeHandle->setMargin(rightBorderLevel * headerLineHeight_.toPixels(), Top);
1058+
1059+
/*
1060+
* Extra widget
1061+
*/
1062+
1063+
if (!columnInfo(column).extraHeaderWidget)
1064+
columnInfo(column).extraHeaderWidget = createExtraHeaderWidget(column);
10661065

10671066
WWidget *extraW = columnInfo(column).extraHeaderWidget;
1068-
if (extraW) {
1069-
result->addWidget(extraW);
1070-
extraW->addStyleClass("Wt-tv-br");
1071-
}
10721067

1073-
if (columnResize_ && app->environment().ajax()) {
1074-
WContainerWidget *resizeHandle = new WContainerWidget();
1075-
resizeHandle->setStyleClass("Wt-tv-rh headerrh");
1076-
resizeHandle->mouseWentDown().connect(resizeHandleMDownJS_);
1068+
/*
1069+
* Assemble into result
1070+
*/
1071+
WContainerWidget *result = new WContainerWidget();
1072+
result->setStyleClass(info.styleClass() + " Wt-tv-c headerrh");
1073+
result->addWidget(resizeHandle);
10771074

1078-
bool ie = wApp->environment().agentIsIE();
1079-
WContainerWidget *parent
1080-
= ie ? w : dynamic_cast<WContainerWidget *>(result->widget(0));
1081-
parent->insertWidget(0, resizeHandle);
1075+
WContainerWidget *main = new WContainerWidget();
1076+
main->setOverflow(WContainerWidget::OverflowHidden);
1077+
main->setContentAlignment(info.headerHAlignment);
1078+
result->addWidget(main);
10821079

1083-
if (ie) {
1084-
parent->setAttributeValue("style", "zoom: 1");
1085-
parent->resize(WLength::Auto, headerLineHeight_);
1086-
}
1080+
main->addWidget(contents);
1081+
1082+
if (info.headerVAlignment == AlignMiddle)
1083+
main->setLineHeight(headerLineHeight_);
1084+
else {
1085+
main->setLineHeight(WLength::Auto);
1086+
if (info.headerWordWrap)
1087+
main->addStyleClass("Wt-wwrap");
10871088
}
10881089

1089-
WText *spacer = new WText();
1090-
spacer->setInline(false);
1091-
spacer->setStyleClass("Wt-tv-br headerrh");
1092-
result->addWidget(spacer);
1090+
if (extraW)
1091+
main->addWidget(extraW);
10931092

10941093
return result;
10951094
}

0 commit comments

Comments
 (0)