Improve UICheckBox in different pixel densities.

Improve stylesheet units printing.
Added `dpr` as device-pixel rounded stylesheet length unit.
Fixes in 7GUIs Cells.
This commit is contained in:
Martín Lucas Golini
2024-02-20 00:34:52 -03:00
parent b48a49b47c
commit d276aa5bc7
18 changed files with 105 additions and 49 deletions

View File

@@ -225,7 +225,7 @@ CheckBox:hover CheckBox::inactive {
CheckBox::active {
border-color: var(--primary);
background-image: rectangle(solid, var(--primary));
background-size: 70% 70%;
background-size: 8dpru 8dpru;
background-position: center;
}

View File

@@ -2511,7 +2511,7 @@ Read [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) documenta
* Supported lenghts: `em`, `rem`, `pt`, `pc`, `in`, `cm`, `mm`, `vw`, `vh`, `vmin`, `vmax`.
* Also adds: `dp` as [Device-independent pixel](https://en.wikipedia.org/wiki/Device-independent_pixel). Plus `dprd` (dp rounded down) and `dpru` (dp rounded up).
* Also adds: `dp` as [Device-independent pixel](https://en.wikipedia.org/wiki/Device-independent_pixel). Plus `dpr` (dp rounded), `dprd` (dp rounded down) and `dpru` (dp rounded up).
---

View File

@@ -32,6 +32,7 @@ class EE_API StyleSheetLength {
Rem,
Dprd,
Dpru,
Dpr,
};
static Unit unitFromString( std::string unitStr );

View File

@@ -63,8 +63,8 @@ std::string Time::toString() const {
if ( asSeconds() < 1 ) {
if ( asMilliseconds() == static_cast<double>( (Int64)asMilliseconds() ) )
return String::format( "%.fms", asMilliseconds() );
return String::format( "%.2fms", asMilliseconds() );
return String::fromFloat( asMilliseconds() );
return String::fromFloat( asMilliseconds() );
} else if ( totalSeconds < 60 ) {
return String::format( "%lus", static_cast<unsigned long>( totalSeconds ) );
}

View File

@@ -874,7 +874,7 @@ std::string UIAbstractTableView::getPropertyString( const PropertyDefinition* pr
switch ( propertyDef->getPropertyId() ) {
case PropertyId::RowHeight:
return String::format( "%.2fpx", getRowHeight() );
return String::fromFloat( getRowHeight(), "px" );
default:
return UIAbstractView::getPropertyString( propertyDef, propertyIndex );
}

View File

@@ -28,6 +28,7 @@ enum UnitHashes : String::HashType {
Rem = String::hash( "rem" ),
Dprd = String::hash( "dprd" ),
Dpru = String::hash( "dpru" ),
Dpr = String::hash( "dpr" ),
};
enum PercentagePositions : String::HashType {
@@ -112,6 +113,8 @@ StyleSheetLength::Unit StyleSheetLength::unitFromString( std::string unitStr ) {
return Unit::Dprd;
case UnitHashes::Dpru:
return Unit::Dpru;
case UnitHashes::Dpr:
return Unit::Dpr;
}
return Unit::Px;
}
@@ -156,6 +159,8 @@ std::string StyleSheetLength::unitToString( const StyleSheetLength::Unit& unit )
return "dprd";
case Unit::Dpru:
return "dpru";
case Unit::Dpr:
return "dpr";
}
return "px";
}
@@ -197,11 +202,13 @@ Float StyleSheetLength::asPixels( const Float& parentSize, const Sizef& viewSize
case Unit::Dp:
ret = PixelDensity::dpToPx( mValue );
break;
case Unit::Dpr:
return round( PixelDensity::dpToPx( mValue ) );
case Unit::Dprd:
ret = roundDown( PixelDensity::dpToPx( mValue ) );
ret = Math::roundDown( PixelDensity::dpToPx( mValue ) );
break;
case Unit::Dpru:
ret = roundUp( PixelDensity::dpToPx( mValue ) );
ret = Math::roundUp( PixelDensity::dpToPx( mValue ) );
break;
case Unit::Em:
ret = Math::round( mValue * elFontSize );
@@ -300,12 +307,10 @@ StyleSheetLength StyleSheetLength::fromString( const std::string& str, const Flo
}
std::string StyleSheetLength::toString() const {
std::string res;
if ( (Int64)mValue == mValue )
res = String::format( "%lld%s", (Int64)mValue, unitToString( mUnit ).c_str() );
else
res = String::format( "%.2f%s", mValue, unitToString( mUnit ).c_str() );
std::string res( String::format( "%.2f", mValue ) );
String::replace( res, ",", "." );
String::numberCleanInPlace( res );
res += unitToString( mUnit );
return res;
}

View File

@@ -2283,11 +2283,11 @@ std::string UICodeEditor::getPropertyString( const PropertyDefinition* propertyD
case PropertyId::FontFamily:
return NULL != getFont() ? getFont()->getName() : "";
case PropertyId::FontSize:
return String::format( "%.2fpx", getFontSize() );
return String::fromFloat( getFontSize(), "px" );
case PropertyId::FontStyle:
return Text::styleFlagToString( getFontStyle() );
case PropertyId::TextStrokeWidth:
return String::toString( PixelDensity::dpToPx( getOutlineThickness() ) );
return String::fromFloat( PixelDensity::dpToPx( getOutlineThickness() ), "px" );
case PropertyId::TextStrokeColor:
return getOutlineColor().toHexString();
case PropertyId::TextSelection:

View File

@@ -232,11 +232,11 @@ std::string UIConsole::getPropertyString( const PropertyDefinition* propertyDef,
case PropertyId::FontFamily:
return NULL != getFont() ? getFont()->getName() : "";
case PropertyId::FontSize:
return String::format( "%.2fpx", getFontSize() );
return String::fromFloat( getFontSize(), "px" );
case PropertyId::FontStyle:
return Text::styleFlagToString( getFontStyleConfig().getFontStyle() );
case PropertyId::TextStrokeWidth:
return String::toString( PixelDensity::dpToPx( getFontOutlineThickness() ) );
return String::fromFloat( PixelDensity::dpToPx( getFontOutlineThickness() ), "px" );
case PropertyId::TextStrokeColor:
return getFontOutlineColor().toHexString();
default:

View File

@@ -477,7 +477,7 @@ std::string UITextInput::getPropertyString( const PropertyDefinition* propertyDe
case PropertyId::HintFontStyle:
return Text::styleFlagToString( getHintFontStyle() );
case PropertyId::HintStrokeWidth:
return String::toString( PixelDensity::dpToPx( getHintOutlineThickness() ) );
return String::fromFloat( PixelDensity::dpToPx( getHintOutlineThickness() ), "px" );
case PropertyId::HintStrokeColor:
return getHintOutlineColor().toHexString();
default:

View File

@@ -803,7 +803,7 @@ std::string UITextView::getPropertyString( const PropertyDefinition* propertyDef
case PropertyId::FontStyle:
return Text::styleFlagToString( getFontStyle() );
case PropertyId::TextStrokeWidth:
return String::toString( PixelDensity::dpToPx( getOutlineThickness() ) );
return String::fromFloat( PixelDensity::dpToPx( getOutlineThickness() ), "px" );
case PropertyId::TextStrokeColor:
return getOutlineColor().toHexString();
case PropertyId::Wordwrap:

View File

@@ -431,7 +431,7 @@ std::string UITooltip::getPropertyString( const PropertyDefinition* propertyDef,
case PropertyId::FontStyle:
return Text::styleFlagToString( getFontStyle() );
case PropertyId::TextStrokeWidth:
return String::toString( PixelDensity::dpToPx( getOutlineThickness() ) );
return String::fromFloat( PixelDensity::dpToPx( getOutlineThickness() ), "px" );
case PropertyId::TextStrokeColor:
return getOutlineColor().toHexString();
case PropertyId::TextAlign:

View File

@@ -293,11 +293,11 @@ std::string UIViewPager::getPropertyString( const PropertyDefinition* propertyDe
case PropertyId::Orientation:
return getOrientation() == UIOrientation::Horizontal ? "horizontal" : "vertical";
case PropertyId::DragResistance:
return String::format( "%.2f", mDragResistance );
return String::fromFloat( mDragResistance );
case PropertyId::ChangePagePercent:
return String::format( "%.2f", mChangePagePercent );
return String::fromFloat( mChangePagePercent );
case PropertyId::MaxEdgeResistance:
return String::format( "%.2f", mMaxEdgeResistance );
return String::fromFloat( mMaxEdgeResistance );
case PropertyId::PageTransitionDuration:
return mPageTransitionDuration.toString();
case PropertyId::TimingFunction:

View File

@@ -1391,13 +1391,13 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef,
case PropertyId::Height:
return String::fromFloat( getSize().getHeight(), "dp" );
case PropertyId::MarginLeft:
return String::format( "%.2fdp", getLayoutMargin().Left );
return String::fromFloat( getLayoutMargin().Left, "dp" );
case PropertyId::MarginTop:
return String::format( "%.2fdp", getLayoutMargin().Top );
return String::fromFloat( getLayoutMargin().Top, "dp" );
case PropertyId::MarginRight:
return String::format( "%.2fdp", getLayoutMargin().Right );
return String::fromFloat( getLayoutMargin().Right, "dp" );
case PropertyId::MarginBottom:
return String::format( "%.2fdp", getLayoutMargin().Bottom );
return String::fromFloat( getLayoutMargin().Bottom, "dp" );
case PropertyId::PaddingLeft:
return String::fromFloat( getPadding().Left, "dp" );
case PropertyId::PaddingTop:
@@ -1495,21 +1495,27 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef,
case PropertyId::BorderBottomWidth:
return String::fromFloat( setBorderEnabled( true )->getBorders().bottom.width, "px" );
case PropertyId::BorderTopLeftRadius:
return String::format( "%.2fpx %.2fpx",
setBorderEnabled( true )->getBorders().radius.topLeft.x,
getBorder()->getBorders().radius.topLeft.y );
return String::format(
"%s %s",
String::fromFloat( setBorderEnabled( true )->getBorders().radius.topLeft.x, "px" ),
String::fromFloat( getBorder()->getBorders().radius.topLeft.y, "px" ) );
case PropertyId::BorderTopRightRadius:
return String::format( "%.2fpx %.2fpx",
setBorderEnabled( true )->getBorders().radius.topRight.x,
getBorder()->getBorders().radius.topRight.y );
return String::format(
"%s %s",
String::fromFloat( setBorderEnabled( true )->getBorders().radius.topRight.x, "px" ),
String::fromFloat( getBorder()->getBorders().radius.topRight.y, "px" ) );
case PropertyId::BorderBottomLeftRadius:
return String::format( "%.2fpx %.2fpx",
setBorderEnabled( true )->getBorders().radius.bottomLeft.x,
getBorder()->getBorders().radius.bottomLeft.y );
return String::format(
"%s %s",
String::fromFloat( setBorderEnabled( true )->getBorders().radius.bottomLeft.x,
"px" ),
String::fromFloat( getBorder()->getBorders().radius.bottomLeft.y, "px" ) );
case PropertyId::BorderBottomRightRadius:
return String::format( "%.2fpx %.2fpx",
setBorderEnabled( true )->getBorders().radius.bottomRight.x,
getBorder()->getBorders().radius.bottomRight.y );
return String::format(
"%s %s",
String::fromFloat( setBorderEnabled( true )->getBorders().radius.bottomRight.x,
"px" ),
String::fromFloat( getBorder()->getBorders().radius.bottomRight.y, "px" ) );
case PropertyId::BorderSmooth:
return mBorder ? ( mBorder->isSmooth() ? "true" : "false" ) : "false";
case PropertyId::BackgroundSmooth:
@@ -1968,7 +1974,7 @@ std::string UIWidget::getLayoutWidthPolicyString() const {
return "match_parent";
else if ( rules == SizePolicy::WrapContent )
return "wrap_content";
return String::toString( getSize().getHeight() ) + "dp";
return String::fromFloat( getSize().getHeight(), "dp" );
}
std::string UIWidget::getLayoutHeightPolicyString() const {
@@ -1978,7 +1984,7 @@ std::string UIWidget::getLayoutHeightPolicyString() const {
return "match_parent";
else if ( rules == SizePolicy::WrapContent )
return "wrap_content";
return String::toString( getSize().getHeight() ) + "dp";
return String::fromFloat( getSize().getHeight(), "dp" );
}
static std::string getGravityStringFromUint( const Uint32& gravity ) {

View File

@@ -26,12 +26,20 @@ EE_MAIN_FUNC int main( int, char** ) {
table->setColumnsWidth( PixelDensity::dpToPx( 80 ) );
table->setRowHeaderWidth( PixelDensity::dpToPx( 32 ) );
table->setSelectionType( UITableView::SelectionType::Cell );
table->setRowSearchByName( false );
table->setEditable( true );
table->setEditTriggers( UIAbstractView::EditTrigger::DoubleClicked |
UIAbstractTableView::EditTrigger::EditKeyPressed );
table->setEditShortcuts( { { KEY_F2 }, { KEY_RETURN }, { KEY_KP_ENTER } } );
table->setSelection( model->index( 0, 0 ) );
table->setFocus();
table->on( Event::KeyDown, [table, model]( const Event* event ) {
if ( table->getSelection().first().isValid() &&
event->asKeyEvent()->getKeyCode() == KEY_DELETE ) {
model->cell( table->getSelection().first() ).clear();
model->invalidate( Model::UpdateFlag::DontInvalidateIndexes );
}
} );
table->onCreateEditingDelegate = [table,
model]( const ModelIndex& index ) -> ModelEditingDelegate* {
auto ret = StringModelEditingDelegate::New();

View File

@@ -54,6 +54,8 @@ void SheetFunction::initOpTable() {
tot += val;
return vals.empty() ? 0 : tot / vals.size();
} } );
opTable.insert( { String::hash( "COUNT" ),
[]( const std::vector<double>& vals ) { return vals.size(); } } );
}
std::vector<double> SheetFunction::evalList( const std::vector<std::shared_ptr<Formula>>& args,

View File

@@ -16,20 +16,41 @@ void Cell::parseFormula( const std::string& formulaStr ) {
Cell::Cell( std::string val, Spreadsheet& sheet ) : value( std::move( val ) ), sheet( sheet ) {}
void Cell::setData( std::string&& data ) {
Cell::~Cell() {}
bool Cell::subscribeToObservers() {
if ( formula ) {
for ( const auto& ref : formula->getReferences( sheet ) ) {
if ( this == ref || hasObserver( ref ) ) {
unsubscribeFromObservers();
return false;
}
ref->addObserver( this );
}
}
return true;
}
void Cell::unsubscribeFromObservers() {
if ( formula ) {
for ( const auto& ref : formula->getReferences( sheet ) )
ref->deleteObserver( this );
}
}
void Cell::setData( std::string&& data ) {
unsubscribeFromObservers();
value = std::move( data );
parseFormula( value );
calc();
if ( formula ) {
for ( const auto& ref : formula->getReferences( sheet ) )
ref->addObserver( this );
bool circular = !subscribeToObservers();
if ( circular ) {
displayValue = "!CIRCULAR";
formulaContainsErrors = true;
} else {
setChanged();
notifyObservers();
}
setChanged();
notifyObservers();
}
std::optional<double> Cell::eval() const {
@@ -72,6 +93,12 @@ void Cell::calc() {
setChanged();
}
void Cell::clear() {
value = displayValue = "";
formula = {};
formulaContainsErrors = false;
}
void Cell::update() {
calc();
notifyObservers();

View File

@@ -32,6 +32,8 @@ class Observable {
void notifyObservers();
bool hasObserver( Observer* observer ) { return mObservers.count( observer ); }
protected:
std::unordered_set<Observer*> mObservers;
std::atomic<bool> mChanged{ false };
@@ -46,7 +48,7 @@ class Cell : public Observer, public Observable {
public:
Cell( std::string val, Spreadsheet& sheet );
virtual ~Cell() {}
virtual ~Cell();
void setData( std::string&& data );
@@ -58,6 +60,8 @@ class Cell : public Observer, public Observable {
void calc();
void clear();
void update();
bool hasFormula() const;
@@ -74,6 +78,10 @@ class Cell : public Observer, public Observable {
bool formulaContainsErrors{ false };
void parseFormula( const std::string& formulaStr );
bool subscribeToObservers();
void unsubscribeFromObservers();
};
class Spreadsheet : public Model {

View File

@@ -1057,8 +1057,7 @@ void App::setUIScaleFactor() {
i18n( "set_ui_scale_factor", "Set the UI scale factor (pixel density):\nMinimum value is "
"1, and maximum 6. Requires restart." ) );
msgBox->setTitle( mWindowTitle );
msgBox->getTextInput()->setText(
String::numberClean( String::format( "%.2f", mConfig.windowState.pixelDensity ) ) );
msgBox->getTextInput()->setText( String::fromFloat( mConfig.windowState.pixelDensity ) );
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
msgBox->showWhenReady();
msgBox->on( Event::OnConfirm, [this, msgBox]( const Event* ) {