cinera.web: Fix issues (on mobile) with new layout
Both pages: Derive reliable window dimensions ourselves Set the orientation from the window dimensions Use "box-sizing: content-box" on the help keys, to fix sizing Search page: Support irregular (i.e. non-square) grids General sizing fixes Fix text fitting when toggling back from List to Grid view Fix text fitting when textNode would overflow container Correctly compute optimal grid size after orientation change Rename .text to .cineraText to avoid CSS selector clash Only add click events for the main set of buttons (not its clone) Player page: Size the video and timestamps bar more sensibly
This commit is contained in:
parent
2cf8739a60
commit
545938d766
|
@ -23,7 +23,7 @@ typedef struct
|
|||
version CINERA_APP_VERSION = {
|
||||
.Major = 0,
|
||||
.Minor = 8,
|
||||
.Patch = 1
|
||||
.Patch = 2
|
||||
};
|
||||
|
||||
#include <stdarg.h> // NOTE(matt): varargs
|
||||
|
@ -13507,6 +13507,7 @@ SearchToBuffer(buffers *CollationBuffers, db_header_project *StoredP, project *P
|
|||
OpenNodeNewLine(B, &IndentationLevel, NODE_DIV, 0);
|
||||
AppendStringToBuffer(B, Wrap0(" class=\"key_block\">"));
|
||||
|
||||
|
||||
OpenNodeCNewLine(B, &IndentationLevel, NODE_DIV, 0);
|
||||
AppendHelpKeyToBufferNewLine(B, &IndentationLevel, Wrap0("1"), TRUE);
|
||||
AppendHelpKeyToBufferNewLine(B, &IndentationLevel, Wrap0("q"), TRUE);
|
||||
|
@ -13535,6 +13536,7 @@ SearchToBuffer(buffers *CollationBuffers, db_header_project *StoredP, project *P
|
|||
AppendHelpKeyToBuffer(B, &IndentationLevel, Wrap0("v"), TRUE);
|
||||
CloseNodeNewLine(B, &IndentationLevel, NODE_DIV);
|
||||
|
||||
|
||||
CloseNodeNewLine(B, &IndentationLevel, NODE_DIV); // key_block
|
||||
CloseNodeNewLine(B, &IndentationLevel, NODE_DIV); // help_paragraph
|
||||
|
||||
|
|
|
@ -142,20 +142,6 @@ ul.cineraNavPlain li.current > a {
|
|||
order: 2;
|
||||
}
|
||||
|
||||
#cineraIndex .cineraTraversal .cineraButton
|
||||
{
|
||||
/* TODO(matt): Do the cineraTraversal as a flex box, to auto-size these buttons? */
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#cineraIndex.anim .cineraTraversal,
|
||||
#cineraIndex.anim .cineraTraversal * p
|
||||
{
|
||||
|
@ -179,6 +165,20 @@ ul.cineraNavPlain li.current > a {
|
|||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
#cineraIndex .cineraTraversal .cineraButton
|
||||
{
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
}
|
||||
|
||||
#cineraIndex .cineraTraversal * p
|
||||
{
|
||||
transform: rotate(0deg);
|
||||
|
@ -274,6 +274,7 @@ ul.cineraNavPlain li.current > a {
|
|||
}
|
||||
|
||||
.cineraQueryContainer #query {
|
||||
width: 0px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
@ -281,6 +282,7 @@ ul.cineraNavPlain li.current > a {
|
|||
position: absolute;
|
||||
top: 2px;
|
||||
right: 5px;
|
||||
font-size: small;
|
||||
color: #000000;
|
||||
height: 100%;
|
||||
display: none;
|
||||
|
@ -345,14 +347,23 @@ ul.cineraNavPlain li.current > a {
|
|||
display: flex;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cineraIndex #cineraIndexGrid .cineraButton.subdivision .head-item,
|
||||
#cineraIndex #cineraIndexGrid .cineraButton.subdivision .tail-item
|
||||
{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#cineraIndex #cineraIndexGrid .cineraButton.subdivision .head-item p,
|
||||
#cineraIndex #cineraIndexGrid .cineraButton.subdivision .tail-item p
|
||||
{
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#cineraIndex #cineraIndexGrid .cineraButton.subdivision.leaf
|
||||
|
@ -518,7 +529,7 @@ ul.cineraNavPlain li.current > a {
|
|||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
max-height: 97%;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.cineraHelp .help_container.visible {
|
||||
|
@ -526,14 +537,15 @@ ul.cineraNavPlain li.current > a {
|
|||
}
|
||||
|
||||
.cineraHelp .help_container .help_key {
|
||||
box-sizing: content-box;
|
||||
font-family: Inconsolata;
|
||||
font-size: 16px;
|
||||
border: 1px solid;
|
||||
display: inline-block;
|
||||
background-color: #111111; /* Per project */
|
||||
border-radius: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
min-height: 1em;
|
||||
min-width: 1em;
|
||||
padding: 4px;
|
||||
line-height: 16px;
|
||||
margin: 2px;
|
||||
|
|
|
@ -21,6 +21,9 @@ var sourceMenus = null;
|
|||
var helpButton = null;
|
||||
var helpDocumentation = null;
|
||||
|
||||
// NOTE(matt): One set of markers per page. There is code to support multiple, which we may want to extend everywhere
|
||||
var MarkersContainer = cinera.querySelector(".markers_container");
|
||||
|
||||
var views = {
|
||||
REGULAR: 0,
|
||||
THEATRE: 1,
|
||||
|
@ -32,7 +35,7 @@ var devices = {
|
|||
MOBILE: 1,
|
||||
};
|
||||
|
||||
var cineraProps = {
|
||||
var CineraProps = {
|
||||
C: null,
|
||||
V: views.REGULAR,
|
||||
Z: null,
|
||||
|
@ -46,11 +49,12 @@ var cineraProps = {
|
|||
Display: null,
|
||||
FlexDirection: null,
|
||||
JustifyContent: null,
|
||||
O: window.orientation,
|
||||
O: null,
|
||||
D: IsMobile() ? devices.MOBILE : devices.DESKTOP,
|
||||
ScrollX: null,
|
||||
ScrollY: null,
|
||||
};
|
||||
CineraProps.O = GetRealOrientation(CineraProps.IsMobile);
|
||||
|
||||
if(titleBar)
|
||||
{
|
||||
|
@ -169,7 +173,7 @@ if(titleBar)
|
|||
}
|
||||
|
||||
viewsMenu = titleBar.querySelector(".views");
|
||||
if(viewsMenu && cineraProps.D !== devices.MOBILE)
|
||||
if(viewsMenu && CineraProps.D !== devices.MOBILE)
|
||||
{
|
||||
menuState.push(viewsMenu);
|
||||
var viewsContainer = viewsMenu.querySelector(".views_container");
|
||||
|
@ -276,7 +280,7 @@ var MobileCineraContentRule = GetOrSetRule(MobileCineraContentRuleSelector);
|
|||
var MenuContainerRuleSelector = ".cineraMenus > .menu .quotes_container, .cineraMenus > .menu .references_container, .cineraMenus > .menu .filter_container, .cineraMenus > .menu .views_container, .cineraMenus > .menu .link_container, .cineraMenus > .menu .credits_container";
|
||||
var MenuContainerRule = GetOrSetRule(MenuContainerRuleSelector);
|
||||
|
||||
if(cineraProps.D == devices.MOBILE)
|
||||
if(CineraProps.D == devices.MOBILE)
|
||||
{
|
||||
InitMobileStyle();
|
||||
}
|
||||
|
@ -288,7 +292,7 @@ else
|
|||
|
||||
var player = new Player(playerContainer, onRefChanged);
|
||||
|
||||
if(cineraProps.D == devices.MOBILE)
|
||||
if(CineraProps.D == devices.MOBILE)
|
||||
{
|
||||
ConnectMobileControls(player);
|
||||
}
|
||||
|
@ -302,7 +306,28 @@ if(viewsMenu && localStorage.getItem(cineraViewStorageItem))
|
|||
|
||||
InitScrollEventListener(cinera);
|
||||
|
||||
window.addEventListener("resize", function() { player.updateSize(); });
|
||||
window.addEventListener("resize", function() {
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
setTimeout(player.updateSize, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.updateSize();
|
||||
}
|
||||
});
|
||||
|
||||
window.onorientationchange = function() {
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
setTimeout(player.updateSize, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.updateSize();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", function(ev) {
|
||||
var key = ev.key;
|
||||
if(ev.getModifierState("Shift") && key == " ")
|
||||
|
@ -350,9 +375,3 @@ else if(lastAnnotation = localStorage.getItem(lastAnnotationStorageItem))
|
|||
{
|
||||
player.setTime(lastAnnotation);
|
||||
}
|
||||
|
||||
window.onorientationchange = function()
|
||||
{
|
||||
cineraProps.O = window.orientation;
|
||||
player.updateSize();
|
||||
};
|
||||
|
|
|
@ -207,7 +207,7 @@ function sizeAndPositionMenuContainer(TitleBar, SizerElement, Menu)
|
|||
var ContainerDimX = SizerElementDimX;
|
||||
var ContainerDimY = SizerElementDimY;
|
||||
|
||||
switch(cineraProps.O)
|
||||
switch(CineraProps.O)
|
||||
{
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
|
@ -286,14 +286,18 @@ ComputeTallest(Elements, UnhidingClass)
|
|||
function
|
||||
ComputeAndSetTallest(Selector, Elements, UnhidingClass)
|
||||
{
|
||||
var Result;
|
||||
Selector.style.height = "unset";
|
||||
Selector.style.height = ComputeTallest(Elements, UnhidingClass) + "px";
|
||||
Result = ComputeTallest(Elements, UnhidingClass);
|
||||
Selector.style.height = Result + "px";
|
||||
return Result;
|
||||
}
|
||||
|
||||
function ApplyMobileStyle(player)
|
||||
{
|
||||
var MaxWidth = MaxWidthOfElement(cinera);
|
||||
var MaxHeight = MaxHeightOfElement(cinera);
|
||||
var WindowDim = DeriveReliableWindowDimensions();
|
||||
var MaxWidth = cinera.offsetWidth;
|
||||
var MaxHeight = MaxHeightOfElement(cinera, WindowDim);
|
||||
|
||||
var IndicesBar = playerContainer.querySelector(".markers_container");
|
||||
var Markers = IndicesBar.querySelector(".markers");
|
||||
|
@ -305,7 +309,7 @@ function ApplyMobileStyle(player)
|
|||
CineraContentWidth -= EpisodeMarkers[i].offsetWidth;
|
||||
}
|
||||
|
||||
switch(cineraProps.O)
|
||||
switch(CineraProps.O)
|
||||
{
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
|
@ -326,28 +330,29 @@ function ApplyMobileStyle(player)
|
|||
} break;
|
||||
}
|
||||
|
||||
var HeightOfTallestIndex;
|
||||
if(MobileCineraContentRule !== undefined)
|
||||
{
|
||||
MobileCineraContentRule.style.width = CineraContentWidth + "px";
|
||||
var MarkerList = Markers.querySelectorAll(".marker");
|
||||
ComputeAndSetTallest(MobileCineraContentRule, MarkerList, "current");
|
||||
HeightOfTallestIndex = ComputeAndSetTallest(MobileCineraContentRule, MarkerList, "current");
|
||||
IndicesBar.style.height = HeightOfTallestIndex + "px";
|
||||
Markers.style.width = CineraContentWidth + "px";
|
||||
}
|
||||
|
||||
var VideoMaxDimX = null;
|
||||
var VideoMaxDimY = null;
|
||||
var VideoMaxDimX = CineraContentWidth;
|
||||
var VideoMaxDimY = MaxHeight - HeightOfTallestIndex;
|
||||
|
||||
switch(cineraProps.O)
|
||||
switch(CineraProps.O)
|
||||
{
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
VideoMaxDimX = MaxWidth;
|
||||
VideoMaxDimY = MaxHeight - IndicesBar.offsetHeight - titleBar.offsetHeight;
|
||||
VideoMaxDimY -= titleBar.offsetHeight;
|
||||
} break;
|
||||
case orientations.LANDSCAPE_LEFT:
|
||||
case orientations.LANDSCAPE_RIGHT:
|
||||
{
|
||||
VideoMaxDimX = MaxWidth - titleBar.offsetWidth;
|
||||
VideoMaxDimY = MaxHeight - IndicesBar.offsetHeight;
|
||||
VideoMaxDimX -= titleBar.offsetWidth;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
@ -477,7 +482,8 @@ ConnectMobileControls(player)
|
|||
Player.prototype.updateSize = function() {
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
if(cineraProps.D === devices.DESKTOP)
|
||||
CineraProps.O = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
if(CineraProps.D === devices.DESKTOP)
|
||||
{
|
||||
width = this.videoContainer.offsetWidth;
|
||||
height = width / 16 * 9; // TODO(matt): Get the aspect ratio from the video itself?
|
||||
|
@ -862,7 +868,7 @@ function toggleMenuVisibility(element) {
|
|||
|
||||
function handleMouseOverViewsMenu()
|
||||
{
|
||||
switch(cineraProps.V)
|
||||
switch(CineraProps.V)
|
||||
{
|
||||
case views.REGULAR:
|
||||
case views.THEATRE:
|
||||
|
@ -904,24 +910,24 @@ function leaveFullScreen_()
|
|||
}
|
||||
|
||||
function toggleTheatreMode() {
|
||||
switch(cineraProps.V)
|
||||
switch(CineraProps.V)
|
||||
{
|
||||
case views.REGULAR:
|
||||
{
|
||||
cineraProps.C = cinera.style.backgroundColor;
|
||||
cineraProps.Z = cinera.style.zIndex;
|
||||
cineraProps.X = cinera.style.left;
|
||||
cineraProps.Y = cinera.style.top;
|
||||
cineraProps.W = cinera.style.width;
|
||||
cineraProps.mW = cinera.style.maxWidth;
|
||||
cineraProps.H = cinera.style.height;
|
||||
cineraProps.mH = cinera.style.maxHeight;
|
||||
cineraProps.P = cinera.style.position;
|
||||
cineraProps.Display = cinera.style.display;
|
||||
cineraProps.FlexDirection = cinera.style.flexDirection;
|
||||
cineraProps.JustifyContent = cinera.style.justifyContent;
|
||||
cineraProps.ScrollX = window.scrollX;
|
||||
cineraProps.ScrollY = window.scrollY;
|
||||
CineraProps.C = cinera.style.backgroundColor;
|
||||
CineraProps.Z = cinera.style.zIndex;
|
||||
CineraProps.X = cinera.style.left;
|
||||
CineraProps.Y = cinera.style.top;
|
||||
CineraProps.W = cinera.style.width;
|
||||
CineraProps.mW = cinera.style.maxWidth;
|
||||
CineraProps.H = cinera.style.height;
|
||||
CineraProps.mH = cinera.style.maxHeight;
|
||||
CineraProps.P = cinera.style.position;
|
||||
CineraProps.Display = cinera.style.display;
|
||||
CineraProps.FlexDirection = cinera.style.flexDirection;
|
||||
CineraProps.JustifyContent = cinera.style.justifyContent;
|
||||
CineraProps.ScrollX = window.scrollX;
|
||||
CineraProps.ScrollY = window.scrollY;
|
||||
|
||||
cinera.style.backgroundColor = "#000";
|
||||
cinera.style.zIndex = 64;
|
||||
|
@ -939,43 +945,43 @@ function toggleTheatreMode() {
|
|||
viewItems[0].setAttribute("data-id", "regular");
|
||||
viewItems[0].setAttribute("title", "Regular mode");
|
||||
viewItems[0].firstChild.nodeValue = "📺";
|
||||
} cineraProps.V = views.THEATRE; localStorage.setItem(cineraViewStorageItem, views.THEATRE); break;
|
||||
} CineraProps.V = views.THEATRE; localStorage.setItem(cineraViewStorageItem, views.THEATRE); break;
|
||||
case views.SUPERTHEATRE:
|
||||
{
|
||||
leaveFullScreen_();
|
||||
}
|
||||
case views.THEATRE:
|
||||
{
|
||||
cinera.style.backgroundColor = cineraProps.C;
|
||||
cinera.style.zIndex = cineraProps.Z;
|
||||
cinera.style.left = cineraProps.X;
|
||||
cinera.style.top = cineraProps.Y;
|
||||
cinera.style.width = cineraProps.W;
|
||||
cinera.style.maxWidth = cineraProps.mW;
|
||||
cinera.style.height = cineraProps.H;
|
||||
cinera.style.maxHeight = cineraProps.mH;
|
||||
cinera.style.position = cineraProps.P;
|
||||
cinera.style.display = cineraProps.Display;
|
||||
cinera.style.flexDirection = cineraProps.FlexDirection;
|
||||
cinera.style.justifyContent = cineraProps.JustifyContent;
|
||||
cinera.style.backgroundColor = CineraProps.C;
|
||||
cinera.style.zIndex = CineraProps.Z;
|
||||
cinera.style.left = CineraProps.X;
|
||||
cinera.style.top = CineraProps.Y;
|
||||
cinera.style.width = CineraProps.W;
|
||||
cinera.style.maxWidth = CineraProps.mW;
|
||||
cinera.style.height = CineraProps.H;
|
||||
cinera.style.maxHeight = CineraProps.mH;
|
||||
cinera.style.position = CineraProps.P;
|
||||
cinera.style.display = CineraProps.Display;
|
||||
cinera.style.flexDirection = CineraProps.FlexDirection;
|
||||
cinera.style.justifyContent = CineraProps.JustifyContent;
|
||||
window.scroll(
|
||||
{
|
||||
top: cineraProps.ScrollY,
|
||||
left: cineraProps.ScrollX
|
||||
top: CineraProps.ScrollY,
|
||||
left: CineraProps.ScrollX
|
||||
}
|
||||
);
|
||||
|
||||
viewItems[0].setAttribute("data-id", "theatre");
|
||||
viewItems[0].setAttribute("title", "Theatre mode");
|
||||
viewItems[0].firstChild.nodeValue = "🎭";
|
||||
} cineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||
} CineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||
}
|
||||
player.updateSize();
|
||||
}
|
||||
|
||||
function toggleSuperTheatreMode()
|
||||
{
|
||||
switch(cineraProps.V)
|
||||
switch(CineraProps.V)
|
||||
{
|
||||
case views.REGULAR:
|
||||
{
|
||||
|
@ -984,12 +990,12 @@ function toggleSuperTheatreMode()
|
|||
case views.THEATRE:
|
||||
{
|
||||
enterFullScreen_();
|
||||
} cineraProps.V = views.SUPERTHEATRE; localStorage.setItem(cineraViewStorageItem, views.SUPERTHEATRE); break;
|
||||
} CineraProps.V = views.SUPERTHEATRE; localStorage.setItem(cineraViewStorageItem, views.SUPERTHEATRE); break;
|
||||
case views.SUPERTHEATRE:
|
||||
{
|
||||
leaveFullScreen_();
|
||||
toggleTheatreMode();
|
||||
} cineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||
} CineraProps.V = views.REGULAR; localStorage.removeItem(cineraViewStorageItem); break;
|
||||
}
|
||||
player.updateSize();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,73 @@ var orientations = {
|
|||
LANDSCAPE_RIGHT: -90,
|
||||
};
|
||||
|
||||
function
|
||||
DeriveReliableWindowDimensions()
|
||||
{
|
||||
// https://www.howtocreate.co.uk/tutorials/javascript/browserwindow
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
|
||||
var DisplaySettings = [];
|
||||
for(var i = 0; i < document.body.children.length; ++i)
|
||||
{
|
||||
var Child = document.body.children[i];
|
||||
DisplaySettings.push(Child.style.display);
|
||||
Child.style.display = "none";
|
||||
}
|
||||
|
||||
var Element = document.createElement("div");
|
||||
Element.style.position = "fixed";
|
||||
Element.style.top = 0;
|
||||
Element.style.right = 0;
|
||||
Element.style.bottom = 0;
|
||||
Element.style.left = 0;
|
||||
Element.style.zOffset = -1;
|
||||
Element.style.opacity = 0;
|
||||
var ElementInPlace = document.body.appendChild(Element);
|
||||
Result.X = ElementInPlace.offsetWidth;
|
||||
Result.Y = ElementInPlace.offsetHeight;
|
||||
ElementInPlace.remove();
|
||||
|
||||
for(var i = 0; i < document.body.children.length; ++i)
|
||||
{
|
||||
var Child = document.body.children[i];
|
||||
Child.style.display = DisplaySettings.shift();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GetRealOrientation(PreferredLandscape, IsMobile)
|
||||
{
|
||||
var Result = window.orientation;
|
||||
var WindowDim = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
if(IsMobile)
|
||||
{
|
||||
WindowDim = DeriveReliableWindowDimensions();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowDim.X = document.body.clientWidth;
|
||||
WindowDim.Y = document.body.clientHeight;
|
||||
}
|
||||
if(WindowDim.Y > WindowDim.X)
|
||||
{
|
||||
Result = orientations.PORTRAIT;
|
||||
}
|
||||
else if(Result == undefined || Result == orientations.PORTRAIT)
|
||||
{
|
||||
Result = PreferredLandscape;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
var DebugConsoleMessageCount = 0;
|
||||
function Say(Message)
|
||||
{
|
||||
|
@ -275,7 +342,7 @@ function getElementYOffsetFromPage(el) {
|
|||
}
|
||||
|
||||
function
|
||||
MaxWidthOfElement(Element)
|
||||
MaxWidthOfElement(Element, WindowDim)
|
||||
{
|
||||
var Result = 0;
|
||||
var OriginalWidth = Element.style.width;
|
||||
|
@ -283,21 +350,31 @@ MaxWidthOfElement(Element)
|
|||
var Max = parseInt(window.getComputedStyle(Element).width);
|
||||
Element.style.width = "unset";
|
||||
var Default = parseInt(window.getComputedStyle(Element).width);
|
||||
Element.style.width = OriginalWidth;
|
||||
|
||||
if(Max > window.innerWidth || Max == Default)
|
||||
var InnerWidth = WindowDim ? WindowDim.X : document.body.clientWidth;
|
||||
|
||||
if(Max > InnerWidth || Max == Default)
|
||||
{
|
||||
Result = window.innerWidth;
|
||||
Result = InnerWidth;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = Max;
|
||||
}
|
||||
|
||||
Element.style.width = Result + "px";
|
||||
if(Element.scrollWidth > Element.clientWidth)
|
||||
{
|
||||
Result = Element.clientWidth;
|
||||
}
|
||||
|
||||
Element.style.width = OriginalWidth;
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
MaxHeightOfElement(Element)
|
||||
MaxHeightOfElement(Element, WindowDim)
|
||||
{
|
||||
var Result = 0;
|
||||
var OriginalHeight = Element.style.height;
|
||||
|
@ -305,16 +382,25 @@ MaxHeightOfElement(Element)
|
|||
var Max = parseInt(window.getComputedStyle(Element).height);
|
||||
Element.style.height = "unset";
|
||||
var Default = parseInt(window.getComputedStyle(Element).height);
|
||||
Element.style.height = OriginalHeight;
|
||||
|
||||
if(Max > window.innerHeight || Max == Default)
|
||||
var InnerHeight = WindowDim ? WindowDim.Y : document.body.clientHeight;
|
||||
|
||||
if(Max > InnerHeight || Max == Default)
|
||||
{
|
||||
Result = window.innerHeight;
|
||||
Result = InnerHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = Max;
|
||||
}
|
||||
|
||||
Element.style.height = Result + "px";
|
||||
if(Element.scrollHeight > Element.clientHeight)
|
||||
{
|
||||
Result = Element.clientHeight;
|
||||
}
|
||||
|
||||
Element.style.height = OriginalHeight;
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
document.body.style.overflowY = "scroll";
|
||||
CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
|
||||
// Element Selection
|
||||
//
|
||||
|
@ -48,10 +49,12 @@ SyncNavState();
|
|||
|
||||
// NOTE(matt): Listeners
|
||||
//
|
||||
BindControlKeys();
|
||||
BindGridKeys(Nav.GridSize);
|
||||
BindControls();
|
||||
InitResizeEventListener();
|
||||
InitOrientationChangeListener();
|
||||
InitScrollEventListener(Nav.Nexus);
|
||||
InitScrollEventListener(Nav.Grid);
|
||||
//
|
||||
////
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
//
|
||||
var CineraProps = {
|
||||
IsMobile: IsMobile(),
|
||||
Orientation: window.orientation,
|
||||
|
||||
Orientation: null,
|
||||
};
|
||||
|
||||
var Search = {
|
||||
|
@ -680,8 +679,17 @@ var Nav = {
|
|||
Nexus: null,
|
||||
GridContainer: null,
|
||||
ButtonsContainer: null,
|
||||
GridSize: null,
|
||||
GridWidth: null,
|
||||
GridSize: {
|
||||
X: null,
|
||||
Y: null,
|
||||
},
|
||||
GridMinCellsPerDimension: 1,
|
||||
GridMaxCellsPerDimension: 4,
|
||||
GridDim: {
|
||||
X: null,
|
||||
Y: null,
|
||||
},
|
||||
MinButtonDim: 100,
|
||||
ButtonDim: null,
|
||||
GridColumnGap: null,
|
||||
GridRowGap: null,
|
||||
|
@ -855,23 +863,74 @@ SetHelpKeyAvailability(GridSize)
|
|||
Nav.Controls.HelpKeys[i].classList.remove("unavailable");
|
||||
}
|
||||
|
||||
if(GridSize < 4)
|
||||
/* NOTE(matt): Key layout:
|
||||
0 4 8 12
|
||||
1 5 9 13
|
||||
2 6 10 14
|
||||
3 7 11 15
|
||||
*/
|
||||
|
||||
if(GridSize.X < 4)
|
||||
{
|
||||
Nav.Controls.HelpKeys[3].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[7].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[11].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[12].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[13].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[14].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[15].classList.add("unavailable");
|
||||
|
||||
if(GridSize < 3)
|
||||
if(GridSize.X < 3)
|
||||
{
|
||||
Nav.Controls.HelpKeys[2].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[6].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[8].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[9].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[10].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[11].classList.add("unavailable");
|
||||
|
||||
if(GridSize.X < 2)
|
||||
{
|
||||
Nav.Controls.HelpKeys[4].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[5].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[6].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[7].classList.add("unavailable");
|
||||
|
||||
if(GridSize.X < 1)
|
||||
{
|
||||
Nav.Controls.HelpKeys[0].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[1].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[2].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[3].classList.add("unavailable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(GridSize.Y < 4)
|
||||
{
|
||||
Nav.Controls.HelpKeys[3].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[7].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[11].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[15].classList.add("unavailable");
|
||||
|
||||
if(GridSize.Y < 3)
|
||||
{
|
||||
Nav.Controls.HelpKeys[2].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[6].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[10].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[14].classList.add("unavailable");
|
||||
|
||||
if(GridSize.Y < 2)
|
||||
{
|
||||
Nav.Controls.HelpKeys[1].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[5].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[9].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[13].classList.add("unavailable");
|
||||
|
||||
if(GridSize.Y < 1)
|
||||
{
|
||||
Nav.Controls.HelpKeys[0].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[4].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[8].classList.add("unavailable");
|
||||
Nav.Controls.HelpKeys[12].classList.add("unavailable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -895,17 +954,29 @@ SyncNavState()
|
|||
if(StateBitIsSet(state_bit.SORT_REVERSED)) { Sort(true); }
|
||||
|
||||
// Nav.ViewType is initialised to view_type.GRID, so we needn't do anything if the Nav.State is also on Grid
|
||||
if(StateBitIsSet(state_bit.VIEW_LIST)) { ToggleView(); }
|
||||
if(StateBitIsSet(state_bit.VIEW_LIST) || !GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
ToggleView();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Nav.Controls.Save.textContent = "Save Settings: ✘";
|
||||
// Nav.ViewType was initialised to view_type.GRID
|
||||
if(!GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
ToggleView();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Nav.State = 0;
|
||||
SetStateBit(state_bit.VIEW_GRID); // NOTE(matt): Nav.ViewType was initialised to view_type.GRID
|
||||
if(!GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
ToggleView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,7 +1007,6 @@ InitTraversalStack()
|
|||
}
|
||||
|
||||
Nav.TraversalStack.push(Level);
|
||||
console.log(Level);
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -951,6 +1021,13 @@ EmptyElement(Element)
|
|||
while(Element.firstChild) { Element.removeChild(Element.firstChild); }
|
||||
}
|
||||
|
||||
function
|
||||
SetDim(Element, X, Y)
|
||||
{
|
||||
Element.style.width = X;
|
||||
Element.style.height = Y;
|
||||
}
|
||||
|
||||
function
|
||||
EmptyAndResetButton(Button)
|
||||
{
|
||||
|
@ -958,17 +1035,7 @@ EmptyAndResetButton(Button)
|
|||
Button.Element.style.fontSize = null;
|
||||
Button.Element.style.fontWeight = null;
|
||||
|
||||
Button.Element.style.width = Nav.ButtonDim + "px";
|
||||
Button.Element.style.height = Nav.ButtonDim + "px";
|
||||
|
||||
for(var i = 0; i < Button.Element.children.length; ++i)
|
||||
{
|
||||
Button.Element.children[i].style.fontSize = null;
|
||||
Button.Element.children[i].style.fontWeight = null;
|
||||
|
||||
Button.Element.children[i].style.width = null;
|
||||
Button.Element.children[i].style.height = null;
|
||||
}
|
||||
SetDim(Button.Element, null, null);
|
||||
|
||||
for(var i = 0; i < Button.Element.classList.length;)
|
||||
{
|
||||
|
@ -1074,8 +1141,11 @@ ComputeItemDistribution(Level)
|
|||
FullButtonEntryCount: 0,
|
||||
};
|
||||
|
||||
// NOTE(matt): Assuming a square grid, reserving the top row for projects
|
||||
Result.ButtonsForProjects = Math.min(Math.sqrt(Nav.Buttons.length), Result.ProjectsToPlace);
|
||||
// NOTE(matt): Reserving the top row for projects
|
||||
if(Result.ProjectsToPlace > 0 && Result.EntriesToPlace > 0)
|
||||
{
|
||||
Result.ButtonsForProjects = Math.min(Nav.GridSize.X, Result.ProjectsToPlace);
|
||||
}
|
||||
Result.ButtonsForEntries = Nav.Buttons.length - Result.ButtonsForProjects;
|
||||
if(Result.EntriesToPlace < Result.ButtonsForEntries)
|
||||
{
|
||||
|
@ -1126,8 +1196,6 @@ ResetButtonsContainerClone()
|
|||
ResetTransform(Nav.Transition.Transforms.ButtonsContainerClone.Initial);
|
||||
ApplyTransform(Nav.Transition.ButtonsContainerCloneElement, Nav.Transition.Transforms.ButtonsContainerClone.Current);
|
||||
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.width = Nav.ButtonsContainer.style.width;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.height = Nav.ButtonsContainer.style.height;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.gridTemplateColumns = Nav.ButtonsContainer.style.gridTemplateColumns;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.gridTemplateRows = Nav.ButtonsContainer.style.gridTemplateRows;
|
||||
|
||||
|
@ -1146,6 +1214,7 @@ ResetButtonsContainerClone()
|
|||
Nav.ButtonsContainer.style.zIndex = 1;
|
||||
Nav.ButtonsContainer.style.order = 1;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.order = 0;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.display = "none";
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -1161,6 +1230,7 @@ CloneButtonsContainer()
|
|||
CopyTransform(Nav.Transition.Transforms.ButtonsContainerClone.Current, Nav.Transition.Transforms.ButtonsContainer.Current);
|
||||
ApplyTransform(Nav.Transition.ButtonsContainerCloneElement, Nav.Transition.Transforms.ButtonsContainerClone.Current);
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.zIndex = 1;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.display = "grid";
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -1556,8 +1626,8 @@ ComputeButtonGeometryRelativeToGrid(Button)
|
|||
|
||||
var ButtonStyle = window.getComputedStyle(Button);
|
||||
|
||||
var GridDimX = Nav.GridWidth;
|
||||
var GridDimY = Nav.GridWidth;
|
||||
var GridDimX = Nav.GridDim.X;
|
||||
var GridDimY = Nav.GridDim.Y;
|
||||
|
||||
var ButtonDimX = parseInt(ButtonStyle.width);
|
||||
var ButtonDimY = parseInt(ButtonStyle.height);
|
||||
|
@ -1620,31 +1690,23 @@ GetTraversalLevelBundle()
|
|||
function
|
||||
FitText(Element)
|
||||
{
|
||||
if(Element.textContent.includes("Day 068") || Element.textContent.includes("Day 136"))
|
||||
{
|
||||
if(Element.textContent.includes("Day 068"))
|
||||
{
|
||||
Say("FitText(068)");
|
||||
}
|
||||
else
|
||||
{
|
||||
Say("FitText(136)");
|
||||
}
|
||||
var Style = window.getComputedStyle(Element);
|
||||
Say("Height: " + Style.height);
|
||||
var ParentStyle = window.getComputedStyle(Element.parentElement);
|
||||
Say("Parent Height: " + ParentStyle.height);
|
||||
}
|
||||
var Paragraph = Element.firstElementChild;
|
||||
var ParagraphStyle = window.getComputedStyle(Paragraph);
|
||||
var ElementStyle = window.getComputedStyle(Element);
|
||||
var Width = parseInt(ElementStyle.width);
|
||||
var Height = parseInt(ElementStyle.height);
|
||||
|
||||
Element.style.alignItems = "flex-start";
|
||||
var FontSize = parseInt(window.getComputedStyle(Element).fontSize);
|
||||
while(FontSize > 10 && IsOverflowed(Element))
|
||||
while(FontSize > 10 && (IsOverflowed(Element) || parseInt(ParagraphStyle.width) > Width || parseInt(ParagraphStyle.height) > Height))
|
||||
{
|
||||
FontSize -= 0.2;
|
||||
Element.style.fontSize = FontSize + "px";
|
||||
ParagraphStyle = window.getComputedStyle(Paragraph);
|
||||
}
|
||||
|
||||
if(IsOverflowed(Element))
|
||||
ParagraphStyle = window.getComputedStyle(Paragraph);
|
||||
if(IsOverflowed(Element) || parseInt(ParagraphStyle.width) > Width || parseInt(ParagraphStyle.height) > Height)
|
||||
{
|
||||
Element.style.fontWeight = "normal";
|
||||
}
|
||||
|
@ -1654,16 +1716,21 @@ FitText(Element)
|
|||
function
|
||||
AppendItemToButton(Button, Text, ItemEnd)
|
||||
{
|
||||
var ButtonElementStyle = window.getComputedStyle(Button.Element);
|
||||
var VerticalBorderAllowance = parseInt(ButtonElementStyle.borderLeftWidth) + parseInt(ButtonElementStyle.borderRightWidth);
|
||||
var HorizontalBorderAllowance;
|
||||
var ItemElement = document.createElement("div");
|
||||
ItemElement.classList.add("text");
|
||||
ItemElement.classList.add("cineraText");
|
||||
switch(ItemEnd)
|
||||
{
|
||||
case item_end.HEAD:
|
||||
{
|
||||
HorizonalBorderAllowance = parseInt(ButtonElementStyle.borderTopWidth);
|
||||
ItemElement.classList.add("head-item");
|
||||
} break;
|
||||
case item_end.TAIL:
|
||||
{
|
||||
HorizonalBorderAllowance = parseInt(ButtonElementStyle.borderBottomWidth);
|
||||
ItemElement.classList.add("tail-item");
|
||||
} break;
|
||||
}
|
||||
|
@ -1673,16 +1740,25 @@ AppendItemToButton(Button, Text, ItemEnd)
|
|||
ItemElement.style.transform = "rotate3d(0, 0, 1, 180deg)";
|
||||
}
|
||||
|
||||
var ParagraphNode = document.createElement("p");
|
||||
ParagraphNode.textContent = Text;
|
||||
ItemElement.appendChild(ParagraphNode);
|
||||
var Item = Button.Element.appendChild(ItemElement);
|
||||
Item.textContent = Text;
|
||||
Item.style.width = Nav.ButtonDim + "px";
|
||||
Item.style.height = (Nav.ButtonDim / 2) + "px";
|
||||
|
||||
// NOTE(matt): This enables Safari to apply height 50% to the head / tail items
|
||||
var ButtonWidth = parseInt(ButtonElementStyle.width);
|
||||
var ButtonHeight = parseInt(ButtonElementStyle.height);
|
||||
SetDim(Button.Element, ButtonWidth + "px", ButtonHeight + "px");
|
||||
////
|
||||
|
||||
FitText(Item);
|
||||
}
|
||||
|
||||
function
|
||||
UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
||||
{
|
||||
if(GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
var LevelBundle = GetTraversalLevelBundle();
|
||||
|
||||
Nav.Controls.GridTraversal.Prev.children[0].textContent = "←";
|
||||
|
@ -1708,7 +1784,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
else if(SiblingIsLeaf(siblings.PREV))
|
||||
{
|
||||
Nav.Controls.GridTraversal.PrevAscends = true;
|
||||
Nav.Controls.GridTraversal.Prev.children[0].textContent = "↰";
|
||||
Nav.Controls.GridTraversal.Prev.children[0].textContent = Nav.SortChronological ? "↰" : "↲";
|
||||
}
|
||||
|
||||
if(!HasNextSibling(LevelBundle.This))
|
||||
|
@ -1777,7 +1853,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
{
|
||||
This.Element.classList.add("leaf");
|
||||
var TextElement = document.createElement("p");
|
||||
TextElement.classList.add("text");
|
||||
TextElement.classList.add("cineraText");
|
||||
if(!Nav.SortChronological)
|
||||
{
|
||||
TextElement.style.transform = "rotate3d(0, 0, 1, 180deg)";
|
||||
|
@ -1822,7 +1898,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
{
|
||||
This.Element.classList.add("leaf");
|
||||
var ButtonLink = document.createElement("a");
|
||||
ButtonLink.classList.add("text");
|
||||
ButtonLink.classList.add("cineraText");
|
||||
if(!Nav.SortChronological)
|
||||
{
|
||||
ButtonLink.style.transform = "rotate3d(0, 0, 1, 180deg)";
|
||||
|
@ -1875,7 +1951,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
}
|
||||
else
|
||||
{
|
||||
TargetA0.ScrollX = Nav.GridWidth + Padding;
|
||||
TargetA0.ScrollX = Nav.GridDim.X + Padding;
|
||||
}
|
||||
|
||||
Nav.Transition.StageDurations.push(320);
|
||||
|
@ -1889,7 +1965,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
{
|
||||
Nav.ButtonsContainer.style.order = 0;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.order = 1;
|
||||
ScrollX = Nav.GridWidth + Padding;
|
||||
ScrollX = Nav.GridDim.X + Padding;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1911,7 +1987,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
var Padding = Nav.GridColumnGap;
|
||||
if(Nav.SortChronological)
|
||||
{
|
||||
TargetA0.ScrollX = Nav.GridWidth + Padding;
|
||||
TargetA0.ScrollX = Nav.GridDim.X + Padding;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1936,7 +2012,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
{
|
||||
Nav.ButtonsContainer.style.order = 0;
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.order = 1;
|
||||
ScrollX = Nav.GridWidth + Padding;
|
||||
ScrollX = Nav.GridDim.X + Padding;
|
||||
}
|
||||
|
||||
Nav.Transition.ButtonsContainerCloneElement.style.paddingRight = Padding + "px";
|
||||
|
@ -2195,6 +2271,7 @@ UpdateButtons(TransitionType, RelevantButton, PoppedLevel)
|
|||
}
|
||||
DoTransition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -2438,7 +2515,7 @@ ShouldFireGridEvents()
|
|||
}
|
||||
|
||||
function
|
||||
ModifyButtonKeybinding(Event)
|
||||
ModifyControlKeybinding(Event)
|
||||
{
|
||||
// TODO(matt): Settle on the final sets of bindings
|
||||
var Chron = Nav.SortChronological;
|
||||
|
@ -2456,79 +2533,102 @@ ModifyButtonKeybinding(Event)
|
|||
case "k": if(ShouldFireGridEvents()) { EnqueueInteraction(interaction_type.ASCEND); } break;
|
||||
case "l": if(ShouldFireGridEvents()) { EnqueueInteraction(Chron ? interaction_type.SIBLING_SHIFT_NEXT : interaction_type.SIBLING_SHIFT_PREV); } break;
|
||||
}
|
||||
}
|
||||
|
||||
if(Nav.GridSize == 2)
|
||||
{
|
||||
switch(Key)
|
||||
{
|
||||
case "1": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 0 : 3].Element; ID.Button = Nav.Buttons[Chron ? 0 : 3]; EnqueueInteraction(IT, ID); } break;
|
||||
case "2": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 1 : 2].Element; ID.Button = Nav.Buttons[Chron ? 1 : 2]; EnqueueInteraction(IT, ID); } break;
|
||||
function
|
||||
BindControlKeys()
|
||||
{
|
||||
document.addEventListener("keydown", ModifyControlKeybinding);
|
||||
}
|
||||
|
||||
case "q": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 2 : 1].Element; ID.Button = Nav.Buttons[Chron ? 2 : 1]; EnqueueInteraction(IT, ID); } break;
|
||||
case "w": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 3 : 0].Element; ID.Button = Nav.Buttons[Chron ? 3 : 0]; EnqueueInteraction(IT, ID); } break;
|
||||
function
|
||||
UnbindControlKeys()
|
||||
{
|
||||
document.removeEventListener("keydown", ModifyControlKeybinding);
|
||||
}
|
||||
|
||||
function
|
||||
RebindControlKeys()
|
||||
{
|
||||
UnbindControlKeys();
|
||||
BindControlKeys();
|
||||
}
|
||||
|
||||
function
|
||||
KeyIsInGrid(GridSize, KeyPos)
|
||||
{
|
||||
return GridSize.X > KeyPos.X && GridSize.Y > KeyPos.Y;
|
||||
}
|
||||
|
||||
function
|
||||
ComputeNaturalKeyIndex(GridSize, KeyPos)
|
||||
{
|
||||
return KeyPos.Y * GridSize.X + KeyPos.X;
|
||||
}
|
||||
|
||||
function
|
||||
EnqueueGridInteraction(GridSize, KeyPos)
|
||||
{
|
||||
var Chron = Nav.SortChronological;
|
||||
var LastButtonIndex = Nav.Buttons.length - 1;
|
||||
var NaturalIndex = ComputeNaturalKeyIndex(GridSize, KeyPos);
|
||||
var IT = interaction_type.PUSH_BUTTON;
|
||||
var ID = { Element: null, Button: null, }; // NOTE(matt): InteractionData
|
||||
ID.Element = Nav.Buttons[Chron ? NaturalIndex : LastButtonIndex - NaturalIndex].Element;
|
||||
ID.Button = Nav.Buttons[Chron ? NaturalIndex : LastButtonIndex - NaturalIndex];
|
||||
EnqueueInteraction(IT, ID);
|
||||
}
|
||||
|
||||
function
|
||||
Get2DPosFromIndex(Layout, Index)
|
||||
{
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
|
||||
Result.X = Index % Layout.X;
|
||||
Result.Y = (Index - Result.X) / Layout.Y;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
ModifyGridKeybinding(Event)
|
||||
{
|
||||
var Key = Event.key;
|
||||
// TODO(matt): With this, we could probably easily add a setting for keyboard layout: e.g. Dvorak
|
||||
var PhysicalKeys = [
|
||||
"1", "2", "3", "4",
|
||||
"q", "w", "e", "r",
|
||||
"a", "s", "d", "f",
|
||||
"z", "x", "c", "v"
|
||||
];
|
||||
|
||||
var KeyLayout = { X: 4, Y: 4 };
|
||||
for(var i = 0; i < PhysicalKeys.length; ++i)
|
||||
{
|
||||
if(Key == PhysicalKeys[i])
|
||||
{
|
||||
var KeyPos = Get2DPosFromIndex(KeyLayout, i);
|
||||
if(KeyIsInGrid(Nav.GridSize, KeyPos) && ShouldFireGridEvents())
|
||||
{
|
||||
EnqueueGridInteraction(Nav.GridSize, KeyPos);
|
||||
}
|
||||
}
|
||||
else if(Nav.GridSize == 3)
|
||||
{
|
||||
switch(Key)
|
||||
{
|
||||
case "1": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 0 : 8].Element; ID.Button = Nav.Buttons[Chron ? 0 : 8]; EnqueueInteraction(IT, ID); } break;
|
||||
case "2": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 1 : 7].Element; ID.Button = Nav.Buttons[Chron ? 1 : 7]; EnqueueInteraction(IT, ID); } break;
|
||||
case "3": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 2 : 6].Element; ID.Button = Nav.Buttons[Chron ? 2 : 6]; EnqueueInteraction(IT, ID); } break;
|
||||
|
||||
case "q": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 3 : 5].Element; ID.Button = Nav.Buttons[Chron ? 3 : 5]; EnqueueInteraction(IT, ID); } break;
|
||||
case "w": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 4 : 4].Element; ID.Button = Nav.Buttons[Chron ? 4 : 4]; EnqueueInteraction(IT, ID); } break;
|
||||
case "e": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 5 : 3].Element; ID.Button = Nav.Buttons[Chron ? 5 : 3]; EnqueueInteraction(IT, ID); } break;
|
||||
|
||||
case "a": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 6 : 2].Element; ID.Button = Nav.Buttons[Chron ? 6 : 2]; EnqueueInteraction(IT, ID); } break;
|
||||
case "s": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 7 : 1].Element; ID.Button = Nav.Buttons[Chron ? 7 : 1]; EnqueueInteraction(IT, ID); } break;
|
||||
case "d": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 8 : 0].Element; ID.Button = Nav.Buttons[Chron ? 8 : 0]; EnqueueInteraction(IT, ID); } break;
|
||||
}
|
||||
}
|
||||
else if(Nav.GridSize == 4)
|
||||
{
|
||||
switch(Key)
|
||||
{
|
||||
case "1": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 0 : 15].Element; ID.Button = Nav.Buttons[Chron ? 0 : 15]; EnqueueInteraction(IT, ID); } break;
|
||||
case "2": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 1 : 14].Element; ID.Button = Nav.Buttons[Chron ? 1 : 14]; EnqueueInteraction(IT, ID); } break;
|
||||
case "3": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 2 : 13].Element; ID.Button = Nav.Buttons[Chron ? 2 : 13]; EnqueueInteraction(IT, ID); } break;
|
||||
case "4": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 3 : 12].Element; ID.Button = Nav.Buttons[Chron ? 3 : 12]; EnqueueInteraction(IT, ID); } break;
|
||||
|
||||
case "q": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 4 : 11].Element; ID.Button = Nav.Buttons[Chron ? 4 : 11]; EnqueueInteraction(IT, ID); } break;
|
||||
case "w": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 5 : 10].Element; ID.Button = Nav.Buttons[Chron ? 5 : 10]; EnqueueInteraction(IT, ID); } break;
|
||||
case "e": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 6 : 9].Element; ID.Button = Nav.Buttons[Chron ? 6 : 9]; EnqueueInteraction(IT, ID); } break;
|
||||
case "r": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 7 : 8].Element; ID.Button = Nav.Buttons[Chron ? 7 : 8]; EnqueueInteraction(IT, ID); } break;
|
||||
|
||||
case "a": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 8 : 7].Element; ID.Button = Nav.Buttons[Chron ? 8 : 7]; EnqueueInteraction(IT, ID); } break;
|
||||
case "s": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 9 : 6].Element; ID.Button = Nav.Buttons[Chron ? 9 : 6]; EnqueueInteraction(IT, ID); } break;
|
||||
case "d": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 10 : 5].Element; ID.Button = Nav.Buttons[Chron ? 10 : 5]; EnqueueInteraction(IT, ID); } break;
|
||||
case "f": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 11 : 4].Element; ID.Button = Nav.Buttons[Chron ? 11 : 4]; EnqueueInteraction(IT, ID); } break;
|
||||
|
||||
case "z": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 12 : 3].Element; ID.Button = Nav.Buttons[Chron ? 12 : 3]; EnqueueInteraction(IT, ID); } break;
|
||||
case "x": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 13 : 2].Element; ID.Button = Nav.Buttons[Chron ? 13 : 2]; EnqueueInteraction(IT, ID); } break;
|
||||
case "c": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 14 : 1].Element; ID.Button = Nav.Buttons[Chron ? 14 : 1]; EnqueueInteraction(IT, ID); } break;
|
||||
case "v": if(ShouldFireGridEvents()) { ID.Element = Nav.Buttons[Chron ? 15 : 0].Element; ID.Button = Nav.Buttons[Chron ? 15 : 0]; EnqueueInteraction(IT, ID); } break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
BindKeys()
|
||||
BindGridKeys()
|
||||
{
|
||||
document.addEventListener("keydown", ModifyButtonKeybinding);
|
||||
document.addEventListener("keydown", ModifyGridKeybinding);
|
||||
}
|
||||
|
||||
function
|
||||
UnbindKeys()
|
||||
UnbindGridKeys()
|
||||
{
|
||||
document.removeEventListener("keydown", ModifyButtonKeybinding);
|
||||
}
|
||||
|
||||
function
|
||||
RebindKeys()
|
||||
{
|
||||
UnbindKeys();
|
||||
BindKeys();
|
||||
document.removeEventListener("keydown", ModifyGridKeybinding);
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -2564,7 +2664,7 @@ DoRotationStage(Now)
|
|||
for(var i = 0; i < Nav.ButtonsContainer.children.length; ++i)
|
||||
{
|
||||
var This = Nav.ButtonsContainer.children[i];
|
||||
var ThisTexts = This.querySelectorAll(".text");
|
||||
var ThisTexts = This.querySelectorAll(".cineraText");
|
||||
for(var j = 0; j < ThisTexts.length; ++j)
|
||||
{
|
||||
ThisTexts[j].style.transform = "rotate3d(0, 0, 1, " + -Nav.Transition.Transforms.ButtonsContainer.Current.Rotation.Z + "deg)";
|
||||
|
@ -2589,7 +2689,7 @@ DoRotationStage(Now)
|
|||
function
|
||||
RotateButtons(Initialising)
|
||||
{
|
||||
// TODO(matt): Consider pushing this through DoTransition(), aware that it'd need to transform ".text" children
|
||||
// TODO(matt): Consider pushing this through DoTransition(), aware that it'd need to transform ".cineraText" children
|
||||
CopyTransform(Nav.Transition.Transforms.ButtonsContainer.Initial, Nav.Transition.Transforms.ButtonsContainer.Current);
|
||||
Nav.Transition.StartTime = undefined;
|
||||
if(!Initialising && Nav.Transition.Enabled)
|
||||
|
@ -2654,15 +2754,27 @@ Sort(Initialising)
|
|||
}
|
||||
if(Initialising && Nav.Transition.Enabled) { setTimeout(AddAnimationClass, 320); }
|
||||
|
||||
UnbindKeys();
|
||||
UnbindGridKeys(Nav.GridSize);
|
||||
Nav.SortChronological = !Nav.SortChronological;
|
||||
if(Nav.Controls.GridTraversal.PrevAscends)
|
||||
{
|
||||
if(Nav.SortChronological)
|
||||
{
|
||||
Nav.Controls.GridTraversal.Prev.children[0].textContent = "↰";
|
||||
}
|
||||
else
|
||||
{
|
||||
Nav.Controls.GridTraversal.Prev.children[0].textContent = "↲";
|
||||
}
|
||||
}
|
||||
|
||||
if(MaintainingState())
|
||||
{
|
||||
if(Nav.SortChronological) { ClearStateBit(state_bit.SORT_REVERSED); }
|
||||
else { SetStateBit(state_bit.SORT_REVERSED); }
|
||||
}
|
||||
RotateButtons(Initialising);
|
||||
RebindKeys();
|
||||
BindGridKeys();
|
||||
runSearch(true);
|
||||
}
|
||||
|
||||
|
@ -2715,6 +2827,29 @@ EnqueueInteraction(InteractionType, Data)
|
|||
}
|
||||
}
|
||||
|
||||
function
|
||||
UseOrientation(Orientation)
|
||||
{
|
||||
Nav.GridContainer.classList.remove("Portrait", "Landscape", "Left", "Right");
|
||||
switch(Orientation)
|
||||
{
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Portrait");
|
||||
} break;
|
||||
|
||||
case orientations.LANDSCAPE_LEFT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Left");
|
||||
} break;
|
||||
|
||||
case orientations.LANDSCAPE_RIGHT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Right");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
InitNexus()
|
||||
{
|
||||
|
@ -2749,91 +2884,151 @@ InitNexus()
|
|||
ScrollCondition = true; // NOTE(matt): Variable in cinera_pre.js, we init with the Grid which is the view we want to auto-scroll
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
switch(CineraProps.Orientation)
|
||||
{
|
||||
case orientations.LANDSCAPE_LEFT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Left");
|
||||
} break;
|
||||
case orientations.LANDSCAPE_RIGHT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Right");
|
||||
} break;
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Portrait");
|
||||
} break;
|
||||
CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
UseOrientation(CineraProps.Orientation);
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
ComputePossibleCellsInDimension(AvailableSpaceInPixels, GridGap)
|
||||
{
|
||||
var Result = 0;
|
||||
var SpaceToFill = AvailableSpaceInPixels;
|
||||
if(SpaceToFill >= Nav.MinButtonDim)
|
||||
{
|
||||
SpaceToFill -= Nav.MinButtonDim;
|
||||
++Result;
|
||||
}
|
||||
|
||||
for(; SpaceToFill >= (Nav.MinButtonDim + GridGap); )
|
||||
{
|
||||
SpaceToFill -= (Nav.MinButtonDim + GridGap);
|
||||
++Result;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GridSizeMeetsMinimumSupported(GridSize)
|
||||
{
|
||||
return GridSize.X * GridSize.Y >= 2;
|
||||
}
|
||||
|
||||
function
|
||||
GridSizeIsSupported(GridSize)
|
||||
{
|
||||
return (GridSize.X >= Nav.GridMinCellsPerDimension && GridSize.X <= Nav.GridMaxCellsPerDimension) &&
|
||||
(GridSize.Y >= Nav.GridMinCellsPerDimension && GridSize.Y <= Nav.GridMaxCellsPerDimension) &&
|
||||
GridSizeMeetsMinimumSupported(GridSize);
|
||||
}
|
||||
|
||||
function
|
||||
ComputeOptimalGridSize()
|
||||
{
|
||||
var Result = null;
|
||||
var DimOffset = {
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
|
||||
var WindowDim;
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
WindowDim = DeriveReliableWindowDimensions();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowDim.X = document.body.clientWidth;
|
||||
WindowDim.Y = document.body.clientHeight;
|
||||
}
|
||||
var DimReduction = {
|
||||
X: 0,
|
||||
Y: Nav.Controls.Header.offsetHeight,
|
||||
};
|
||||
|
||||
if(CineraProps.Orientation == orientations.LANDSCAPE_LEFT || CineraProps.Orientation == orientations.LANDSCAPE_RIGHT)
|
||||
Nav.Transition.ButtonsTransitionContainerElement.style = null;
|
||||
Nav.ButtonsContainer.style = null;
|
||||
Nav.Controls.GridTraversal.Header.style = null;
|
||||
Nav.Controls.GridTraversal.Ascend.style = null;
|
||||
Nav.Controls.GridTraversal.Prev.style = null;
|
||||
Nav.Controls.GridTraversal.Next.style = null;
|
||||
|
||||
// TODO(matt): Maybe structure it such that the grid is always not hidden at this point?
|
||||
var GridWasHidden = Nav.GridContainer.classList.contains("hidden");
|
||||
if(GridWasHidden)
|
||||
{
|
||||
DimOffset.X += Nav.Controls.GridTraversal.Header.offsetWidth;
|
||||
Nav.GridContainer.classList.remove("hidden");
|
||||
}
|
||||
if(CineraProps.IsMobile && (CineraProps.Orientation == orientations.LANDSCAPE_LEFT || CineraProps.Orientation == orientations.LANDSCAPE_RIGHT))
|
||||
{
|
||||
DimReduction.X += Nav.Controls.GridTraversal.Header.offsetWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
DimOffset.Y += Nav.Controls.GridTraversal.Header.offsetHeight;
|
||||
DimReduction.Y += Nav.Controls.GridTraversal.Header.offsetHeight;
|
||||
}
|
||||
if(GridWasHidden)
|
||||
{
|
||||
Nav.GridContainer.classList.add("hidden");
|
||||
}
|
||||
|
||||
var MaxWidth = MaxWidthOfElement(Nav.Nexus) - DimOffset.X;
|
||||
var MaxHeight = MaxHeightOfElement(Nav.Nexus) - DimOffset.Y;
|
||||
var MaxWidth = MaxWidthOfElement(Nav.Nexus, WindowDim) - DimReduction.X;
|
||||
var MaxHeight = MaxHeightOfElement(Nav.Nexus, WindowDim) - DimReduction.Y;
|
||||
|
||||
var BodyStyle = window.getComputedStyle(document.body);
|
||||
if(Nav.Nexus.parentNode == document.body)
|
||||
{
|
||||
// TODO(matt): Robustify this
|
||||
var BodyStyle = window.getComputedStyle(document.body);
|
||||
MaxWidth -= parseInt(BodyStyle.marginRight);
|
||||
MaxHeight -= parseInt(BodyStyle.marginBottom);
|
||||
}
|
||||
|
||||
if(MaxWidth > MaxHeight)
|
||||
Result.X = ComputePossibleCellsInDimension(MaxWidth, Nav.GridColumnGap);
|
||||
Result.Y = ComputePossibleCellsInDimension(MaxHeight, Nav.GridRowGap);
|
||||
|
||||
if(GridSizeMeetsMinimumSupported(Result))
|
||||
{
|
||||
MaxWidth = MaxHeight;
|
||||
}
|
||||
else if(MaxHeight > MaxWidth)
|
||||
{
|
||||
MaxHeight = MaxWidth;
|
||||
}
|
||||
Result.X = Clamp(Nav.GridMinCellsPerDimension, Result.X, Nav.GridMaxCellsPerDimension);
|
||||
Result.Y = Clamp(Nav.GridMinCellsPerDimension, Result.Y, Nav.GridMaxCellsPerDimension);
|
||||
|
||||
var MinButtonSize = 100;
|
||||
var ButtonDimBasedOnX = Math.floor((MaxWidth - Nav.GridColumnGap * (Result.X - 1)) / Result.X);
|
||||
var ButtonDimBasedOnY = Math.floor((MaxHeight - Nav.GridRowGap * (Result.Y - 1)) / Result.Y);
|
||||
|
||||
var MinGridSize = 2;
|
||||
var MaxGridSize = 4;
|
||||
Nav.ButtonDim = Math.min(ButtonDimBasedOnX, ButtonDimBasedOnY);
|
||||
Nav.ButtonDim -= Nav.ButtonDim % 2; // NOTE(matt): Even-length helps CSS keep the head & tail's correct size when rotated 180 degrees
|
||||
|
||||
Result = Clamp(MinGridSize, Math.floor(MaxWidth / MinButtonSize), MaxGridSize);
|
||||
Nav.ButtonDim = (MaxWidth - Nav.GridRowGap * (Result - 1)) / Result;
|
||||
|
||||
// TODO(matt): If Safari's head-item sizing bug proves to be a problem, use this:
|
||||
/*
|
||||
var ButtonStyleRuleSelector = "#cineraIndex #cineraIndexGrid .cineraButton.subdivision";
|
||||
var ButtonStyleRule = GetOrSetRule(ButtonStyleRuleSelector);
|
||||
|
||||
ButtonStyleRule.style.width = Nav.ButtonDim + "px";
|
||||
ButtonStyleRule.style.height = Nav.ButtonDim + "px";
|
||||
*/
|
||||
|
||||
var GridTemplateColumnsStyle = "repeat(" + Result + ", 1fr)";
|
||||
var GridTemplateColumnsStyle = "repeat(" + Result.X + ", minmax(" + Nav.ButtonDim + "px, " + Nav.ButtonDim + "px))";
|
||||
Nav.ButtonsContainer.style.gridTemplateColumns = GridTemplateColumnsStyle;
|
||||
|
||||
var GridTemplateRowsStyle = "repeat(" + Result + ", " + Nav.ButtonDim + "px)";
|
||||
var GridTemplateRowsStyle = "repeat(" + Result.Y + ", " + Nav.ButtonDim + "px)";
|
||||
Nav.ButtonsContainer.style.gridTemplateRows = GridTemplateRowsStyle;
|
||||
|
||||
Nav.ButtonsContainer.style.width = MaxWidth + "px";
|
||||
Nav.ButtonsContainer.style.height = MaxHeight + "px";
|
||||
Nav.GridDim.X = Nav.ButtonDim * Result.X + Nav.GridColumnGap * (Result.X - 1);
|
||||
Nav.GridDim.Y = Nav.ButtonDim * Result.Y + Nav.GridRowGap * (Result.Y - 1);
|
||||
|
||||
Nav.Transition.ButtonsTransitionContainerElement.style.width = MaxWidth + "px";
|
||||
Nav.Transition.ButtonsTransitionContainerElement.style.height = MaxHeight + "px";
|
||||
SetDim(Nav.Transition.ButtonsTransitionContainerElement, Nav.GridDim.X + "px", Nav.GridDim.Y + "px");
|
||||
|
||||
Nav.GridWidth = MaxWidth;
|
||||
Nav.Controls.GridTraversal.Header.style.maxWidth = Nav.GridDim.X + "px";
|
||||
Nav.Controls.GridTraversal.Header.style.maxHeight = Nav.GridDim.Y + "px";
|
||||
|
||||
var TraversalButtonCount = 3;
|
||||
if(Nav.Controls.GridTraversal.Header.scrollWidth > Nav.Controls.GridTraversal.Header.clientWidth)
|
||||
{
|
||||
var TraversalButtonDim = Nav.Controls.GridTraversal.Header.clientWidth / TraversalButtonCount;
|
||||
SetDim(Nav.Controls.GridTraversal.Ascend, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
SetDim(Nav.Controls.GridTraversal.Prev, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
SetDim(Nav.Controls.GridTraversal.Next, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
}
|
||||
if(Nav.Controls.GridTraversal.Header.scrollHeight > Nav.Controls.GridTraversal.Header.clientHeight)
|
||||
{
|
||||
var TraversalButtonDim = Nav.Controls.GridTraversal.Header.clientHeight / TraversalButtonCount;
|
||||
SetDim(Nav.Controls.GridTraversal.Ascend, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
SetDim(Nav.Controls.GridTraversal.Prev, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
SetDim(Nav.Controls.GridTraversal.Next, TraversalButtonDim + "px", TraversalButtonDim + "px");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ResetButtonsContainerClone(); // NOTE(matt): This reapplies the sorting Z-rotation
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -3273,6 +3468,8 @@ ToggleView()
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
Nav.Controls.View.textContent = "View: Grid";
|
||||
Nav.ViewType = view_type.GRID;
|
||||
|
@ -3291,14 +3488,19 @@ ToggleView()
|
|||
var ProjectsStack = BuildProjectsStack(TargetLevel);
|
||||
DeriveTraversalStack(ProjectsStack, TargetLevel);
|
||||
}
|
||||
UpdateButtons();
|
||||
|
||||
Nav.List.classList.add("hidden");
|
||||
Nav.GridContainer.classList.remove("hidden");
|
||||
|
||||
UpdateButtons();
|
||||
|
||||
ScrollToWithOffset(Nav.Controls.GridTraversal.Header, Nav.Controls.Header.offsetHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(matt): Inform user that grid view is unavailable
|
||||
}
|
||||
}
|
||||
ScrollCondition = Nav.ViewType == view_type.GRID;
|
||||
}
|
||||
|
||||
|
@ -3431,14 +3633,16 @@ BindControls()
|
|||
function
|
||||
InitButtons()
|
||||
{
|
||||
if(GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
var ButtonPrototype = document.createElement("div");
|
||||
ButtonPrototype.classList.add("cineraButton", "subdivision");
|
||||
for(var i = 0; i < Math.pow(Nav.GridSize, 2); ++i)
|
||||
for(var i = 0; i < Nav.GridSize.X * Nav.GridSize.Y; ++i)
|
||||
{
|
||||
Nav.ButtonsContainer.appendChild(ButtonPrototype.cloneNode());
|
||||
}
|
||||
|
||||
var Buttons = Nav.Nexus.querySelectorAll(".cineraButton.subdivision");
|
||||
var Buttons = Nav.ButtonsContainer.querySelectorAll(".cineraButton.subdivision");
|
||||
for(let j = 0; j < Buttons.length; ++j)
|
||||
{
|
||||
let Button = {
|
||||
|
@ -3459,8 +3663,7 @@ InitButtons()
|
|||
|
||||
Nav.Buttons.push(Button);
|
||||
}
|
||||
|
||||
BindKeys();
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -3471,9 +3674,7 @@ ReinitButtons()
|
|||
Nav.Buttons[0].Element.remove();
|
||||
Nav.Buttons.shift();
|
||||
}
|
||||
RebindKeys();
|
||||
InitButtons();
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
function
|
||||
|
@ -3600,20 +3801,48 @@ PseudoPushButton(Button)
|
|||
}
|
||||
|
||||
function
|
||||
InitResizeEventListener()
|
||||
ResizeFunction()
|
||||
{
|
||||
window.addEventListener("resize", function() {
|
||||
CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
UseOrientation(CineraProps.Orientation);
|
||||
}
|
||||
var NewGridSize = ComputeOptimalGridSize();
|
||||
if(Nav.GridSize !== NewGridSize)
|
||||
{
|
||||
UnbindGridKeys();
|
||||
Nav.GridSize = NewGridSize;
|
||||
ReinitButtons();
|
||||
BindGridKeys();
|
||||
SetHelpKeyAvailability(Nav.GridSize)
|
||||
if(GridSizeIsSupported(Nav.GridSize))
|
||||
{
|
||||
var TargetLevel = Nav.TraversalStack[Nav.TraversalStack.length - 1];
|
||||
var ProjectsStack = EmptyTraversalStackIntoProjectsStack();
|
||||
DeriveTraversalStack(ProjectsStack, TargetLevel);
|
||||
SetHelpKeyAvailability(Nav.GridSize)
|
||||
}
|
||||
else if(Nav.ViewType == view_type.GRID)
|
||||
{
|
||||
ToggleView();
|
||||
// TODO(matt): Inform user that we've switched to the list view
|
||||
}
|
||||
ScrollToWithOffset(Nav.Nexus, 0);
|
||||
}
|
||||
UpdateButtons();
|
||||
}
|
||||
function
|
||||
InitResizeEventListener()
|
||||
{
|
||||
window.addEventListener("resize", function() {
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
window.setTimeout(ResizeFunction, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
ResizeFunction();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3624,35 +3853,11 @@ InitOrientationChangeListener()
|
|||
{
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
CineraProps.Orientation = window.orientation;
|
||||
Nav.GridContainer.classList.remove("Portrait", "Landscape", "Left", "Right");
|
||||
switch(CineraProps.Orientation)
|
||||
{
|
||||
case orientations.LANDSCAPE_LEFT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Left");
|
||||
} break;
|
||||
case orientations.LANDSCAPE_RIGHT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Landscape", "Right");
|
||||
} break;
|
||||
case orientations.PORTRAIT:
|
||||
{
|
||||
Nav.GridContainer.classList.add("Portrait");
|
||||
} break;
|
||||
window.setTimeout(ResizeFunction, 512);
|
||||
}
|
||||
|
||||
var NewGridSize = ComputeOptimalGridSize();
|
||||
if(Nav.GridSize !== NewGridSize)
|
||||
else
|
||||
{
|
||||
Nav.GridSize = NewGridSize;
|
||||
ReinitButtons();
|
||||
var TargetLevel = Nav.TraversalStack[Nav.TraversalStack.length - 1];
|
||||
var ProjectsStack = EmptyTraversalStackIntoProjectsStack();
|
||||
DeriveTraversalStack(ProjectsStack, TargetLevel);
|
||||
SetHelpKeyAvailability(Nav.GridSize)
|
||||
}
|
||||
UpdateButtons();
|
||||
ResizeFunction();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue