Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize panes by dragging borders #77

Merged
merged 1 commit into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions lute/static/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -915,3 +915,37 @@ table.statsWordsRead th, td { padding: 5px; }
.zoomableTermImage:hover {
transform: scale(10) translate(-10px) !important;
}

/* resize */

/* border */
#read_pane_right::after {
content: '';
background-color: #dbefff;
position: absolute;
left: 0;
top: 0;
transform: translateX(-50%);
width: 4px;
height: 100%;
cursor: col-resize;
}

/* border */
.dictframecontainer::after {
content: '';
background-color: #dbefff;
/* background-image: linear-gradient(to right, #dbefff 50%, #dbefff 50%); */
position: absolute;
top: 0;
left: 0;
height: 4px;
width: 100%;
cursor: row-resize;
}

.dictframecontainer {
position: relative;
overflow: hidden; /* contents overflow (over audio player) if height is too small*/
opacity: 0; /*to hide the after element. easier this way */
}
162 changes: 162 additions & 0 deletions lute/static/js/resize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"use strict";

let mouse_pos;
let widthDefault;
let trHeightDefault;
const borderWidth = 4;
const wordFrame = document.getElementById("wordframeid");
const dictFrame = document.getElementById("dictframeid");
const dictFrameCont = document.querySelector(".dictframecontainer");
const readPaneRight = document.querySelector("#read_pane_right");

applyInitialPaneSizes();

function resizeCol(e){
const dx = mouse_pos - e.x;
mouse_pos = e.x;
// getting the width with computedStyle doesn't seem to be working correctly.
// getting width directly, but for this initial width must be set via javascript
// so the style is inline for this code to work
const currentWidthLeft = readPaneLeft.style.width;
const readPaneWidth = parseFloat(window.getComputedStyle(readPaneContainer).getPropertyValue("width"));
// const currentWidthLeft = parseFloat(window.getComputedStyle(readPaneLeft).getPropertyValue("width"));

let lfWidthPct = parseFloat(currentWidthLeft) - (dx / readPaneWidth * 100);
lfWidthPct = clamp(lfWidthPct, 25, 95);
const rtWidthPct = (100 - lfWidthPct) * getReadPaneWidthRatio();

readPaneLeft.style.width = `${lfWidthPct}%`;
readPaneRight.style.width = `${rtWidthPct}%`;

localStorage.setItem("textWidth", lfWidthPct);
}

function resizeRow(e){
const dx = mouse_pos - e.y;
mouse_pos = e.y;
// const currentWidth = getFromLocalStorage("textWidth", widthDefault);
const currentHeightWordFrame = parseFloat(window.getComputedStyle(readPaneRight).gridTemplateRows.split(" ")[0]);
const readPaneRightHeight = parseFloat(window.getComputedStyle(readPaneRight).getPropertyValue("height"));
// const currentHeightWordFrame = parseFloat(window.getComputedStyle(dictFrameCont).getPropertyValue("height"));
// const currentHeightWordFrame = parseFloat(dictFrameCont.style.height);
// console.log(currentHeightWordFrame);
let wordFrameHeight = (currentHeightWordFrame / readPaneRightHeight * 100) - (dx / readPaneRightHeight * 100);
wordFrameHeight = clamp(wordFrameHeight, 5, 95);
// const currentWidthRight = window.getComputedStyle(readPaneRight).width;
// console.log(currentHeightWord);

readPaneRight.style.gridTemplateRows = `${wordFrameHeight}% 1fr`;
// console.log(`${parseInt(currentWidthRight) - dx}px`);
// readPaneRight.style.width = `${parseInt(currentWidthRight) + dx}px`;
localStorage.setItem("trHeight", wordFrameHeight);
}

readPaneRight.addEventListener("mousedown", function(e){
if (e.offsetX < borderWidth) {
setIFrameStatus("none");
mouse_pos = e.x;
document.addEventListener("mousemove", resizeCol);
e.preventDefault(); // prevent selection
}
});

// double click -> widen to 95% temporarily (doesn't save state)
readPaneRight.addEventListener("dblclick", function(e){
if (e.offsetX < borderWidth) {
// if the width is 95% then return to the last width value
if (readPaneLeft.style.width == "95%") {
const width = getFromLocalStorage("textWidth", widthDefault);
readPaneLeft.style.width = `${width}%`;
readPaneRight.style.width = `${(100 - width) * getReadPaneWidthRatio()}%`;
} else {
readPaneLeft.style.width = "95%";
readPaneRight.style.width = `${5 * getReadPaneWidthRatio()}%`;
}
}
});

dictFrameCont.addEventListener("mousedown", function(e){
if (e.offsetY < borderWidth) {
setIFrameStatus("none");
mouse_pos = e.y;
document.addEventListener("mousemove", resizeRow);
e.preventDefault();
}
});

dictFrameCont.addEventListener("dblclick", function(e){
if (e.offsetY < borderWidth) {
if (readPaneRight.style.gridTemplateRows.split(" ")[0] == "5%") {
readPaneRight.style.gridTemplateRows = `${getFromLocalStorage("trHeight", trHeightDefault)}% 1fr`;
} else {
readPaneRight.style.gridTemplateRows = `${5}% 1fr`;
}
}
});

document.addEventListener("mouseup", function(){
document.removeEventListener("mousemove", resizeCol);
document.removeEventListener("mousemove", resizeRow);
setIFrameStatus("unset");
});

// hide horizontal line
window.addEventListener("message", function(event) {
if (event.data.event === "LuteTermFormOpened") {
dictFrameCont.style.opacity = "1";
}
});

// if the iframes are clickable mousemove doesn't work correctly
function setIFrameStatus(status) {
wordFrame.style.pointerEvents = status;
dictFrame.style.pointerEvents = status;
}

// because right side is fixed. it's width value is different. need to find ratio
// basically: when gridContainer width is 100%, this doesn't mean that it takes the whole
// viewport width. it can be less than that. but for the right side it's an absolute percentage value
function getReadPaneWidthRatio() {
return parseFloat(window.getComputedStyle(readPaneContainer).getPropertyValue("width")) / parseFloat(document.documentElement.clientWidth);
}

function clamp (num, min, max) {
return Math.min(Math.max(num, min), max);
}

function getTextWidthPercentage() {
// returns percentage value
const elementComputedStyle = window.getComputedStyle(readPaneLeft);
return (parseFloat(elementComputedStyle.getPropertyValue("width")) / parseFloat(window.getComputedStyle(readPaneContainer).getPropertyValue("width"))) * 100;
// return parseFloat(elementComputedStyle.width);
}

function getWordFrameHeightPercentage() {
// returns percentage value
// const elementComputedStyle = window.getComputedStyle(dictFrameCont);
return (parseFloat(window.getComputedStyle(readPaneRight).gridTemplateRows.split(" ")[0]) / parseFloat(window.getComputedStyle(readPaneRight).getPropertyValue("height"))) * 100;
// return parseFloat(elementComputedStyle.width);
}

function applyInitialPaneSizes() {
widthDefault = getTextWidthPercentage();
trHeightDefault = getWordFrameHeightPercentage();

const width = getFromLocalStorage("textWidth", widthDefault);
const height = getFromLocalStorage("trHeight", trHeightDefault);

readPaneLeft.style.width = `${width}%`;
readPaneRight.style.width = `${(100 - width) * getReadPaneWidthRatio()}%`;
readPaneRight.style.gridTemplateRows = `${height}% 1fr`;
}

function getFromLocalStorage(item, defaultVal) {
// return Number(localStorage.getItem(item) ?? defaultVal);
const storageVal = localStorage.getItem(item);

if ((!storageVal) || isNaN(storageVal)) {
return Number(defaultVal);
} else {
return Number(storageVal);
}
}
40 changes: 2 additions & 38 deletions lute/static/js/text-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
let textItems;
let fontDefault;
let lhDefault;
let widthDefault;
let columnDefault;

const fontPlusButton = document.querySelector(".font-plus");
Expand All @@ -19,29 +18,23 @@ const oneColButton = document.querySelector(".column-one");
const twoColButton = document.querySelector(".column-two");

const theText = document.querySelector("#thetext");
const readPaneRight = document.querySelector("#read_pane_right");
// const readPaneLeft = document.querySelector("#read_pane_left");

const domObserver = new MutationObserver((mutationList, observer) => {
textItems = document.querySelectorAll("span.textitem");

fontDefault = getFontSize(textItems[0]);
lhDefault = getLineHeight(textItems[0]);
widthDefault = getTextWidthPercentage();
columnDefault = getColumnCount();

const fontSize = getFromLocalStorage("fontSize", fontDefault);
const lhSize = getFromLocalStorage("lineHeight", lhDefault);
const width = getFromLocalStorage("textWidth", widthDefault);
const columnCount = getFromLocalStorage("columnCount", columnDefault);

textItems.forEach((item) => {
setFontSize(item, `${convertPixelsToRem(fontSize)}rem`);
setLineHeight(item, Number(lhSize.toPrecision(2)));
});

readPaneLeft.style.width = `${width}%`;
readPaneRight.style.width = `${(100 - width) * getReadPaneWidthRatio()}%`;
theText.style.columnCount = columnCount;
});

Expand Down Expand Up @@ -95,13 +88,6 @@ function getLineHeight(element) {
// return parseFloat(elementComputedStyle.marginBottom);
}

function getTextWidthPercentage() {
// returns percentage value
const elementComputedStyle = window.getComputedStyle(readPaneLeft);
return (parseFloat(elementComputedStyle.getPropertyValue("width")) / parseFloat(window.getComputedStyle(readPaneContainer).getPropertyValue("width"))) * 100;
// return parseFloat(elementComputedStyle.width);
}

function getColumnCount() {
const elementComputedStyle = window.getComputedStyle(theText);
return elementComputedStyle.columnCount;
Expand Down Expand Up @@ -148,7 +134,7 @@ function changeTextWidth(operation) {

let newWidth = add ? currentWidth + currentWidth * 0.05 : currentWidth - currentWidth * 0.05;

newWidth = clamp(newWidth, 25, 75);
newWidth = clamp(newWidth, 25, 95);

readPaneLeft.style.width = `${newWidth}%`;
readPaneRight.style.width = `${(100 - newWidth) * getReadPaneWidthRatio()}%`;
Expand All @@ -160,26 +146,4 @@ function convertPixelsToRem(sizePx) {
const bodyFontSize = window.getComputedStyle(document.querySelector("body")).fontSize;
const sizeRem = sizePx / parseFloat(bodyFontSize);
return sizeRem;
}

function getFromLocalStorage(item, defaultVal) {
// return Number(localStorage.getItem(item) ?? defaultVal);
const storageVal = localStorage.getItem(item);

if ((!storageVal) || isNaN(storageVal)) {
return Number(defaultVal);
} else {
return Number(storageVal);
}
}

function clamp (num, min, max) {
return Math.min(Math.max(num, min), max);
}

// because right side is fixed. it's width value is different. need to find ratio
// basically: when gridContainer width is 100%, this doesn't mean that it takes the whole
// viewport width. it can be less than that. but for the right side it's an absolute percentage value
function getReadPaneWidthRatio() {
return parseFloat(window.getComputedStyle(readPaneContainer).getPropertyValue("width")) / parseFloat(document.documentElement.clientWidth);
}
}
6 changes: 5 additions & 1 deletion lute/templates/read/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% block body %}

<script type="text/javascript" src="{{ url_for('static', filename='js/player.js') }}" charset="utf-8" defer></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/resize.js') }}" charset="utf-8" defer></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/text-options.js') }}" charset="utf-8" defer></script>

<div id="rendering_controls" style="display: none">
Expand Down Expand Up @@ -233,6 +234,7 @@ <h2>&#127881;</h2>
</div>

<div id="read_pane_right">
<div class="wordframecontainer">
<iframe
name="wordframe"
id="wordframeid"
Expand All @@ -244,7 +246,8 @@ <h2>&#127881;</h2>
>
Frame support required.
</iframe>

</div>
<div class="dictframecontainer">
<iframe
name="dictframe"
id="dictframeid"
Expand All @@ -256,6 +259,7 @@ <h2>&#127881;</h2>
>
Frame support required.
</iframe>
</div>
</div>

</div>
Expand Down
Loading