Item Tree: Attempt to fix OS font scaling (#2488)
This commit is contained in:
parent
2af7275968
commit
4c445554a3
3 changed files with 36 additions and 20 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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%;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue