Item Tree: Attempt to fix OS font scaling (#2488)

This commit is contained in:
Adomas Ven 2022-04-11 12:16:59 +03:00 committed by GitHub
parent 2af7275968
commit 4c445554a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 20 deletions

View file

@ -34,7 +34,7 @@ const { injectIntl } = require('react-intl');
const { IconDownChevron, getDOMElement } = require('components/icons'); const { IconDownChevron, getDOMElement } = require('components/icons');
const TYPING_TIMEOUT = 1000; const TYPING_TIMEOUT = 1000;
const DEFAULT_ROW_HEIGHT = 20; // px const MINIMUM_ROW_HEIGHT = 20; // px
const RESIZER_WIDTH = 5; // px const RESIZER_WIDTH = 5; // px
const noop = () => 0; const noop = () => 0;
@ -283,14 +283,10 @@ class VirtualizedTable extends React.Component {
this._columns = new Columns(this); this._columns = new Columns(this);
this._rowHeight = props.rowHeight || DEFAULT_ROW_HEIGHT; this._renderedTextHeight = this._getRenderedTextHeight();
if (!props.disableFontSizeScaling) { this._rowHeight = this._getRowHeight();
this._rowHeight *= Zotero.Prefs.get('fontSize');
}
this.selection = new TreeSelection(this); this.selection = new TreeSelection(this);
// Due to how the Draggable element works dragging (for column dragging and for resizing) // Due to how the Draggable element works dragging (for column dragging and for resizing)
// is not handled via React events but via native ones attached on `document` // is not handled via React events but via native ones attached on `document`
// Since React attaches its event handlers on `document` as well // Since React attaches its event handlers on `document` as well
@ -312,6 +308,7 @@ class VirtualizedTable extends React.Component {
static defaultProps = { static defaultProps = {
label: '', label: '',
role: 'grid', role: 'grid',
linesPerRow: 1,
showHeader: false, showHeader: false,
// Array of column objects like the ones in itemTreeColumns.js // Array of column objects like the ones in itemTreeColumns.js
@ -358,8 +355,9 @@ class VirtualizedTable extends React.Component {
getRowCount: PropTypes.func.isRequired, getRowCount: PropTypes.func.isRequired,
renderItem: PropTypes.func, renderItem: PropTypes.func,
rowHeight: PropTypes.number, // Row height specified as lines of text per row. Defaults to 1
// Use rowHeight or default row height without adjusting for current UI font size linesPerRow: PropTypes.number,
// Do not adjust for Zotero-defined font scaling
disableFontSizeScaling: PropTypes.bool, disableFontSizeScaling: PropTypes.bool,
// An array of two elements for alternating row colors // An array of two elements for alternating row colors
alternatingRowColors: PropTypes.array, alternatingRowColors: PropTypes.array,
@ -1065,6 +1063,7 @@ class VirtualizedTable extends React.Component {
node.addEventListener('dblclick', e => this._activateNode(e, [index]), { passive: true }); node.addEventListener('dblclick', e => this._activateNode(e, [index]), { passive: true });
} }
node.style.height = this._rowHeight + 'px'; node.style.height = this._rowHeight + 'px';
node.style.lineHeight = this._rowHeight + 'px';
node.id = this.props.id + "-row-" + index; node.id = this.props.id + "-row-" + index;
if (!node.hasAttribute('role')) { if (!node.hasAttribute('role')) {
node.setAttribute('role', 'row'); node.setAttribute('role', 'row');
@ -1224,8 +1223,7 @@ class VirtualizedTable extends React.Component {
+ "disabled. Change the prop instead."); + "disabled. Change the prop instead.");
return; return;
} }
this._rowHeight = this.props.rowHeight || DEFAULT_ROW_HEIGHT; this._rowHeight = this._getRowHeight();
this._rowHeight *= Zotero.Prefs.get('fontSize');
if (!this._jsWindow) return; if (!this._jsWindow) return;
this._jsWindow.update(this._getWindowedListOptions()); this._jsWindow.update(this._getWindowedListOptions());
@ -1233,6 +1231,27 @@ class VirtualizedTable extends React.Component {
this._jsWindow.invalidate(); this._jsWindow.invalidate();
} }
_getRowHeight() {
let rowHeight = this.props.linesPerRow * this._renderedTextHeight;
if (!this.props.disableFontSizeScaling) {
rowHeight *= Zotero.Prefs.get('fontSize');
}
// padding
rowHeight *= 1.4;
rowHeight = Math.round(Math.max(MINIMUM_ROW_HEIGHT, rowHeight));
return rowHeight;
}
_getRenderedTextHeight() {
let div = document.createElementNS("http://www.w3.org/1999/xhtml", 'div');
div.style.visibility = "hidden";
div.textContent = "Zotero";
document.documentElement.appendChild(div);
let height = window.getComputedStyle(div).height;
document.documentElement.removeChild(div);
return parseFloat(height.split('px')[0]);
}
_debouncedRerender = Zotero.Utilities.debounce(this.rerender, 200); _debouncedRerender = Zotero.Utilities.debounce(this.rerender, 200);
_updateWidth() { _updateWidth() {

View file

@ -234,7 +234,7 @@
overflow: auto; overflow: auto;
.cell { .cell {
padding: 2px 5px; padding: 0 5px;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
max-height: 100%; max-height: 100%;

View file

@ -23,13 +23,10 @@
.virtualized-table-body, .drag-image-container{ .virtualized-table-body, .drag-image-container{
.cell:not(:first-child) { .cell:not(:first-child) {
border-inline-start: 1px solid #ddd; background-image: linear-gradient(#ddd, #ddd);
background-size: 1px 80%;
// A hack to make empty cells have a content, otherwise the border applied background-position: left;
// above has a height of a few pixels in empty cells. background-repeat: no-repeat;
&::after { height: 100%;
content: " ";
border-inline-start: 1px solid transparent;
}
} }
} }