mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
Implemented row header for TableView.
Added shorthands for border-left, border-right, border-top, border-bottom.
This commit is contained in:
@@ -881,7 +881,9 @@ Splitter::separator:hover {
|
||||
}
|
||||
|
||||
tableview::header,
|
||||
listview::header {
|
||||
listview::header,
|
||||
tableview::rowheader,
|
||||
listview::rowheader {
|
||||
background-color: var(--back);
|
||||
}
|
||||
|
||||
@@ -900,9 +902,24 @@ listview::header::column {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tableview::rowheader::row,
|
||||
treeview::rowheader::row,
|
||||
listview::rowheader::row {
|
||||
background-color: var(--back);
|
||||
border-right-color: var(--tab-line);
|
||||
border-right-width: 1dp;
|
||||
border-bottom-color: var(--tab-line);
|
||||
border-bottom-width: 1dp;
|
||||
border-type: inside;
|
||||
color: var(--font);
|
||||
}
|
||||
|
||||
tableview::header::column:hover,
|
||||
treeview::header::column:hover,
|
||||
listview::header::column:hover {
|
||||
listview::header::column:hover,
|
||||
tableview::rowheader::row:hover,
|
||||
treeview::rowheader::row:hover,
|
||||
listview::rowheader::row:hover {
|
||||
background-color: var(--tab-hover);
|
||||
}
|
||||
|
||||
|
||||
@@ -2203,24 +2203,52 @@ Read [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) documenta
|
||||
|
||||
---
|
||||
|
||||
### border-bottom
|
||||
|
||||
Read [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom) documentation.
|
||||
`border-style` is not implemented yet.
|
||||
|
||||
---
|
||||
|
||||
### border-color
|
||||
|
||||
Read [border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color) documentation.
|
||||
|
||||
---
|
||||
|
||||
### border-left
|
||||
|
||||
Read [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border-left) documentation.
|
||||
`border-style` is not implemented yet.
|
||||
|
||||
---
|
||||
|
||||
### border-radius
|
||||
|
||||
Read [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) documentation.
|
||||
|
||||
---
|
||||
|
||||
### border-right
|
||||
|
||||
Read [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border-right) documentation.
|
||||
`border-style` is not implemented yet.
|
||||
|
||||
---
|
||||
|
||||
### border-width
|
||||
|
||||
Read [border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width) documentation.
|
||||
|
||||
---
|
||||
|
||||
### border-top
|
||||
|
||||
Read [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border-top) documentation.
|
||||
`border-style` is not implemented yet.
|
||||
|
||||
---
|
||||
|
||||
### box-margin
|
||||
|
||||
Shorthand for [column-margin](#column-margin) and [row-margin](#row-margin) (in that order).
|
||||
|
||||
@@ -124,6 +124,14 @@ class EE_API UIAbstractTableView : public UIAbstractView {
|
||||
virtual void onOpenMenuModelIndex( const ModelIndex& index,
|
||||
const Event* triggerEvent = nullptr );
|
||||
|
||||
bool isRowHeaderVisible() const;
|
||||
|
||||
void setRowHeaderVisible( bool rowHeaderVisible );
|
||||
|
||||
Float getRowHeaderWidth() const;
|
||||
|
||||
void setRowHeaderWidth( Float rowHeaderWidth );
|
||||
|
||||
protected:
|
||||
friend class EE::UI::UITableHeaderColumn;
|
||||
|
||||
@@ -140,7 +148,8 @@ class EE_API UIAbstractTableView : public UIAbstractView {
|
||||
mutable std::vector<UITableRow*> mRows;
|
||||
mutable std::vector<ColumnData> mColumn;
|
||||
mutable std::vector<UnorderedMap<int, UIWidget*>> mWidgets;
|
||||
UILinearLayout* mHeader;
|
||||
UILinearLayout* mHeader{ nullptr };
|
||||
UILinearLayout* mRowHeader{ nullptr };
|
||||
Float mDragBorderDistance{ 8 };
|
||||
size_t mIconSize{ 12 };
|
||||
size_t mSortIconSize{ 16 };
|
||||
@@ -153,6 +162,7 @@ class EE_API UIAbstractTableView : public UIAbstractView {
|
||||
std::string mSearchText;
|
||||
size_t mMainColumn{ 0 };
|
||||
std::unordered_map<UIWidget*, std::vector<Uint32>> mWidgetsClickCbId;
|
||||
Float mRowHeaderWidth{ 0 };
|
||||
|
||||
virtual ~UIAbstractTableView();
|
||||
|
||||
@@ -210,6 +220,10 @@ class EE_API UIAbstractTableView : public UIAbstractView {
|
||||
int visibleColumn();
|
||||
|
||||
void resetColumnData();
|
||||
|
||||
void buildRowHeader();
|
||||
|
||||
void updateRowHeader( int realRowIndex, const ModelIndex& index, Float yOffset );
|
||||
};
|
||||
|
||||
}}} // namespace EE::UI::Abstract
|
||||
|
||||
@@ -70,6 +70,8 @@ class EE_API Model {
|
||||
|
||||
virtual std::string columnName( const size_t& /*column*/ ) const { return {}; }
|
||||
|
||||
virtual std::string rowName( const size_t& /*row*/ ) const { return {}; }
|
||||
|
||||
virtual Variant data( const ModelIndex&, ModelRole = ModelRole::Display ) const = 0;
|
||||
|
||||
virtual void update() { onModelUpdate(); }
|
||||
|
||||
@@ -238,7 +238,7 @@ Sizef UIAbstractTableView::getContentSize() const {
|
||||
if ( !getModel() )
|
||||
return {};
|
||||
size_t count = getModel()->columnCount();
|
||||
Sizef size;
|
||||
Sizef size( mRowHeaderWidth, 0.f );
|
||||
for ( size_t i = 0; i < count; i++ )
|
||||
if ( !isColumnHidden( i ) )
|
||||
size.x += columnData( i ).width;
|
||||
@@ -490,7 +490,8 @@ UITableRow* UIAbstractTableView::updateRow( const int& rowIndex, const ModelInde
|
||||
}
|
||||
rowWidget->setCurIndex( index );
|
||||
rowWidget->setPixelsSize( getContentSize().getWidth(), getRowHeight() );
|
||||
rowWidget->setPixelsPosition( { -mScrollOffset.x, yOffset - mScrollOffset.y } );
|
||||
rowWidget->setPixelsPosition(
|
||||
{ mRowHeaderWidth + -mScrollOffset.x, yOffset - mScrollOffset.y } );
|
||||
if ( isRowSelection() ) {
|
||||
if ( getSelection().contains( index ) ) {
|
||||
rowWidget->pushState( UIState::StateSelected );
|
||||
@@ -502,7 +503,7 @@ UITableRow* UIAbstractTableView::updateRow( const int& rowIndex, const ModelInde
|
||||
}
|
||||
|
||||
void UIAbstractTableView::onScrollChange() {
|
||||
mHeader->setPixelsPosition( -mScrollOffset.x, 0 );
|
||||
mHeader->setPixelsPosition( mRowHeaderWidth + -mScrollOffset.x, 0 );
|
||||
}
|
||||
|
||||
void UIAbstractTableView::bindNavigationClick( UIWidget* widget ) {
|
||||
@@ -684,6 +685,64 @@ void UIAbstractTableView::onOpenMenuModelIndex( const ModelIndex& index,
|
||||
sendEvent( &event );
|
||||
}
|
||||
|
||||
Float UIAbstractTableView::getRowHeaderWidth() const {
|
||||
return mRowHeaderWidth;
|
||||
}
|
||||
|
||||
void UIAbstractTableView::setRowHeaderWidth( Float rowHeaderWidth ) {
|
||||
if ( mRowHeaderWidth == rowHeaderWidth )
|
||||
return;
|
||||
mRowHeaderWidth = rowHeaderWidth;
|
||||
onScrollChange();
|
||||
buildRowHeader();
|
||||
}
|
||||
|
||||
void UIAbstractTableView::buildRowHeader() {
|
||||
if ( mRowHeaderWidth == 0 ) {
|
||||
if ( mRowHeader )
|
||||
mRowHeader->setVisible( false )->setEnabled( false );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mRowHeader == nullptr ) {
|
||||
mRowHeader = UILinearLayout::NewWithTag( mTag + "::rowheader", UIOrientation::Vertical );
|
||||
mRowHeader->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||
mRowHeader->setParent( this )->setVisible( true )->setEnabled( true );
|
||||
}
|
||||
|
||||
mRowHeader->setPaddingTop( mHeader->getSize().getHeight() );
|
||||
mRowHeader->setPixelsSize( { mRowHeaderWidth, getPixelsSize().getHeight() } );
|
||||
mRowHeader->setClipType( ClipType::PaddingBox );
|
||||
|
||||
int rowsCount = Math::roundUp( mSize.getHeight() / getRowHeight() ) + 1;
|
||||
|
||||
if ( mRowHeader->getChildCount() < rowsCount ) {
|
||||
int createCount = rowsCount - mRowHeader->getChildCount();
|
||||
for ( int i = 0; i < createCount; i++ ) {
|
||||
UIWidget* row = UIPushButton::NewWithTag( mTag + "::rowheader::row" );
|
||||
row->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||
row->setParent( mRowHeader );
|
||||
row->setPixelsSize( mRowHeaderWidth, getRowHeight() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIAbstractTableView::updateRowHeader( int realRowIndex, const ModelIndex& index,
|
||||
Float yOffset ) {
|
||||
if ( !mRowHeader || mRowHeaderWidth == 0 )
|
||||
return;
|
||||
Node* child = mRowHeader->getChildAt( realRowIndex );
|
||||
if ( !child )
|
||||
return;
|
||||
UIPushButton* row = child->asType<UIPushButton>();
|
||||
|
||||
row->setPixelsSize( mRowHeaderWidth, getRowHeight() );
|
||||
row->setLayoutMarginTop( PixelDensity::pxToDp( yOffset ) );
|
||||
|
||||
if ( getModel() )
|
||||
row->setText( getModel()->rowName( index.row() ) );
|
||||
}
|
||||
|
||||
void UIAbstractTableView::onRowCreated( UITableRow* row ) {
|
||||
RowCreatedEvent rowEvent( this, Event::OnRowCreated, row );
|
||||
sendEvent( &rowEvent );
|
||||
|
||||
@@ -459,6 +459,17 @@ void StyleSheetSpecification::registerDefaultProperties() {
|
||||
"color-vector2" );
|
||||
registerShorthand( "hint-shadow", { "hint-shadow-color", "hint-shadow-offset" },
|
||||
"color-vector2" );
|
||||
registerShorthand( "border-left",
|
||||
{ "border-left-width", "border-left-style", "border-left-color" },
|
||||
"border-side" );
|
||||
registerShorthand( "border-right",
|
||||
{ "border-right-width", "border-right-style", "border-right-color" },
|
||||
"border-side" );
|
||||
registerShorthand( "border-top", { "border-top-width", "border-top-style", "border-top-color" },
|
||||
"border-side" );
|
||||
registerShorthand( "border-bottom",
|
||||
{ "border-bottom-width", "border-bottom-style", "border-bottom-color" },
|
||||
"border-side" );
|
||||
}
|
||||
|
||||
void StyleSheetSpecification::registerNodeSelector( const std::string& name,
|
||||
@@ -939,6 +950,38 @@ void StyleSheetSpecification::registerDefaultShorthandParsers() {
|
||||
return properties;
|
||||
};
|
||||
|
||||
mShorthandParsers["border-side"] = []( const ShorthandDefinition* shorthand,
|
||||
std::string value ) -> std::vector<StyleSheetProperty> {
|
||||
value = String::trim( value );
|
||||
if ( value.empty() || "none" == value )
|
||||
return {};
|
||||
|
||||
std::vector<StyleSheetProperty> properties;
|
||||
const std::vector<std::string>& propNames = shorthand->getProperties();
|
||||
std::vector<std::string> tokens = String::split( value, " ", "", "(" );
|
||||
|
||||
for ( auto& tok : tokens ) {
|
||||
if ( -1 !=
|
||||
String::valueIndex(
|
||||
tok, "none;hidden;dotted;dashed;solid;double;groove;ridge;inset;outset" ) ) {
|
||||
int pos = getIndexEndingWith( propNames, "-style" );
|
||||
// boder-style is not implemented yet
|
||||
if ( pos != -1 )
|
||||
continue;
|
||||
} else if ( Color::isColorString( tok ) || String::startsWith( tok, "var(" ) ) {
|
||||
int pos = getIndexEndingWith( propNames, "-color" );
|
||||
if ( pos != -1 )
|
||||
properties.emplace_back( StyleSheetProperty( propNames[pos], tok ) );
|
||||
} else {
|
||||
int pos = getIndexEndingWith( propNames, "-width" );
|
||||
if ( pos != -1 )
|
||||
properties.emplace_back( StyleSheetProperty( propNames[pos], tok ) );
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
};
|
||||
|
||||
mShorthandParsers["color-vector2"] =
|
||||
[]( const ShorthandDefinition* shorthand,
|
||||
std::string value ) -> std::vector<StyleSheetProperty> {
|
||||
|
||||
@@ -30,6 +30,7 @@ void UITableView::drawChilds() {
|
||||
int realRowIndex = 0;
|
||||
int realColIndex = 0;
|
||||
ConditionalLock l( getModel() != nullptr, getModel() ? &getModel()->resourceMutex() : nullptr );
|
||||
buildRowHeader();
|
||||
if ( getModel() ) {
|
||||
Float rowHeight = getRowHeight();
|
||||
size_t start = mScrollOffset.y / rowHeight;
|
||||
@@ -66,11 +67,18 @@ void UITableView::drawChilds() {
|
||||
realColIndex++;
|
||||
}
|
||||
rowNode->nodeDraw();
|
||||
if ( mRowHeaderWidth ) {
|
||||
updateRowHeader( realRowIndex, rowIndex,
|
||||
realRowIndex == 0 ? std::fmodf( -mScrollOffset.y, rowHeight )
|
||||
: 0.f );
|
||||
}
|
||||
realRowIndex++;
|
||||
}
|
||||
}
|
||||
if ( mHeader && mHeader->isVisible() )
|
||||
mHeader->nodeDraw();
|
||||
if ( mRowHeader && mRowHeader->isVisible() )
|
||||
mRowHeader->nodeDraw();
|
||||
if ( mHScroll->isVisible() )
|
||||
mHScroll->nodeDraw();
|
||||
if ( mVScroll->isVisible() )
|
||||
@@ -94,6 +102,8 @@ Node* UITableView::overFind( const Vector2f& point ) {
|
||||
return pOver;
|
||||
if ( mHeader && ( pOver = mHeader->overFind( point ) ) )
|
||||
return pOver;
|
||||
if ( mRowHeader && ( pOver = mRowHeader->overFind( point ) ) )
|
||||
return pOver;
|
||||
Float rowHeight = getRowHeight();
|
||||
Float headerHeight = getHeaderHeight();
|
||||
Float itemCount = getItemCount();
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
#include <eepp/ee.hpp>
|
||||
|
||||
// Referece https://eugenkiss.github.io/7guis/tasks/#cells
|
||||
// Row header pending
|
||||
EE_MAIN_FUNC int main( int, char** ) {
|
||||
UIApplication app( { 1024, 768, "eepp - 7GUIs - Cells" } );
|
||||
UIWidget* rlay = app.getUI()->loadLayoutFromString( R"xml(
|
||||
<style>
|
||||
#sheet tableview::cell {
|
||||
border: 1dp solid var(--button-border);
|
||||
border-type: inside;
|
||||
border-right: 1dprd solid var(--button-border);
|
||||
border-bottom: 1dprd solid var(--button-border);
|
||||
}
|
||||
</style>
|
||||
<RelativeLayout layout_width="match_parent" layout_height="match_parent">
|
||||
@@ -19,6 +20,7 @@ EE_MAIN_FUNC int main( int, char** ) {
|
||||
auto model = std::make_shared<Spreadsheet>();
|
||||
table->setModel( model );
|
||||
table->setColumnsWidth( PixelDensity::dpToPx( 80 ) );
|
||||
table->setRowHeaderWidth( PixelDensity::dpToPx( 32 ) );
|
||||
table->setSelectionType( UITableView::SelectionType::Cell );
|
||||
table->setEditable( true );
|
||||
table->setEditTriggers( UIAbstractView::EditTrigger::DoubleClicked |
|
||||
|
||||
@@ -83,6 +83,10 @@ class Spreadsheet : public Model {
|
||||
return String::format( "%c", column + 'A' );
|
||||
}
|
||||
|
||||
virtual std::string rowName( const size_t& row ) const {
|
||||
return String::format( "%zu", row + 1 );
|
||||
}
|
||||
|
||||
virtual Variant data( const ModelIndex& index, ModelRole role ) const;
|
||||
|
||||
void createCell( int col, int row );
|
||||
|
||||
Reference in New Issue
Block a user