move time study presets into player object

give presets optional nicknames

add context menu for them
This commit is contained in:
garnet420 2019-04-17 09:12:23 -04:00
parent 2ec730d5ff
commit 6fed4e7545
14 changed files with 336 additions and 96 deletions

View File

@ -22,7 +22,7 @@ OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0
CreationTime: 1074936349
ModificationTime: 1554774484
ModificationTime: 1555362898
PfmFamily: 17
TTFWeight: 500
TTFWidth: 5
@ -81,10 +81,16 @@ NameList: AGL For New Fonts
DisplaySize: -96
AntiAlias: 1
FitToEm: 0
WinInfo: 62416 16 8
WinInfo: 0 16 8
BeginPrivate: 0
EndPrivate
Grid
-1000 357 m 0
2000 357 l 1024
Named: "bbot"
-1000 444 m 0
2000 444 l 1024
Named: "btop"
-1000 200 m 0
2000 200 l 1024
Named: "h200"
@ -104,7 +110,7 @@ Grid
294 -700 m 1024
Named: "v293"
EndSplineSet
BeginChars: 65537 273
BeginChars: 65537 274
StartChar: .notdef
Encoding: 65536 -1 0
@ -8664,11 +8670,11 @@ Flags: W
LayerCount: 2
Fore
SplineSet
0 0 m 5
0 100 l 1
587 100 l 1
587 0 l 1
0 0 l 5
0 0 m 5,0,-1
0 100 l 1,1,-1
587 100 l 1,2,-1
587 0 l 1,3,-1
0 0 l 5,0,-1
EndSplineSet
EndChar
@ -8900,7 +8906,7 @@ StartChar: uniF430
Encoding: 62512 62512 272
Width: 587
VWidth: 0
Flags: WO
Flags: W
LayerCount: 2
Fore
SplineSet
@ -8911,5 +8917,31 @@ SplineSet
0 0 l 1,0,-1
EndSplineSet
EndChar
StartChar: uni22EF
Encoding: 8943 8943 273
Width: 880
VWidth: 0
Flags: WO
LayerCount: 2
Fore
SplineSet
799.5 318 m 1,0,-1
799.5 482 l 1,1,-1
668.5 482 l 1,2,-1
668.5 318 l 1,3,-1
799.5 318 l 1,0,-1
505.5 318 m 1,4,-1
505.5 482 l 1,5,-1
374.5 482 l 1,6,-1
374.5 318 l 1,7,-1
505.5 318 l 1,4,-1
211.5 318 m 1,8,-1
211.5 482 l 1,9,-1
80.5 482 l 1,10,-1
80.5 318 l 1,11,-1
211.5 318 l 1,8,-1
EndSplineSet
EndChar
EndChars
EndSplineFont

View File

@ -468,6 +468,7 @@
<script type="text/javascript" src="javascripts/components/plus-minus-button.js"></script>
<script type="text/javascript" src="javascripts/components/ad-slider-component.js"></script>
<script type="text/javascript" src="javascripts/components/expanding-control-box.js"></script>
<script type="text/javascript" src="javascripts/components/hover-menu.js"></script>
<script type="text/javascript" src="javascripts/components/header/game-header.js"></script>
<script type="text/javascript" src="javascripts/components/header/game-header-amounts-line.js"></script>

View File

@ -0,0 +1,86 @@
"use strict";
/**
* This slotted component manages a context menu that is accessible both
* by right clicking and by hovering; this is mostly about wrangling timers.
*/
Vue.component("hover-menu", {
props: {
saveslot: Number
},
data: () => ({
componentID: UIID.next(),
contextMenuHideTimer: null,
contextMenuShowTimer: null,
}),
computed: {
contextMenuIsVisible() {
return this.$viewModel.currentContextMenu === this.componentID;
},
listeners() {
return Object.assign({}, this.$listeners, {
touchstart: () => this.startShowTimer(),
mouseenter: () => this.startShowTimer(),
mouseleave: () => this.startHideTimer(),
});
}
},
methods: {
startShowTimer() {
this.stopHideTimer();
if (this.contextMenuIsVisible || this.contextMenuShowTimer) return;
this.contextMenuShowTimer = setTimeout(() => {
this.contextMenuShowTimer = null;
this.showContextMenu();
}, 250);
},
showContextMenu() {
this.stopTimers();
this.$viewModel.currentContextMenu = this.componentID;
},
startHideTimer() {
this.stopShowTimer();
if (!this.contextMenuIsVisible || this.contextMenuHideTimer) return;
this.contextMenuHideTimer = setTimeout(() => {
this.contextMenuHideTimer = null;
this.hideContextMenu();
}, 500);
},
hideContextMenu() {
this.stopTimers();
if (this.$viewModel.currentContextMenu === this.componentID) {
this.$viewModel.currentContextMenu = null;
}
},
toggleContextMenu() {
if (this.contextMenuIsVisible) this.hideContextMenu();
else this.showContextMenu();
},
stopTimers() {
this.stopHideTimer();
this.stopShowTimer();
},
stopHideTimer() {
if (this.contextMenuHideTimer) {
clearTimeout(this.contextMenuHideTimer);
this.contextMenuHideTimer = null;
}
},
stopShowTimer() {
if (this.contextMenuShowTimer) {
clearTimeout(this.contextMenuShowTimer);
this.contextMenuShowTimer = null;
}
},
},
template: `
<div class="l-hover-menu__wrapper"
v-on="listeners"
@contextmenu.prevent="toggleContextMenu" >
<slot name="object" ref="clown">
</slot>
<slot name="menu" v-if="contextMenuIsVisible">
</slot>
</div>
`,
});

View File

@ -55,11 +55,14 @@ Vue.component("plus-minus-button", {
];
},
},
template:
`<div :style="outerStyle" v-repeating-click="{ delay: 500 }" @firstclick="$emit('click')" @repeatclick="$emit('click')">
<div :style="horizStyle"></div>
<div v-if="type==='plus'" :style="vertStyle"></div>
</div>`,
template: `
<div :style="outerStyle"
v-repeating-click="{ delay: 500 }"
@firstclick="$emit('click')"
@repeatclick="$emit('click')">
<div :style="horizStyle" />
<div v-if="type==='plus'" :style="vertStyle" />
</div>`,
mounted() {
this.color = getComputedStyle(this.$el).color;
this.computedSize = this.$el.offsetWidth;

View File

@ -1,3 +1,5 @@
"use strict";
Vue.component("tt-shop", {
data() {
return {
@ -43,8 +45,8 @@ Vue.component("tt-shop", {
width: this.minimized ? "440px" : "555px"
};
},
autobuyerText() {
return this.ttAutobuyerOn ? "Auto: ON" : "Auto: OFF";
saveLoadText() {
return this.$viewModel.shiftDown ? "save:" : "load:";
}
},
methods: {
@ -88,38 +90,38 @@ Vue.component("tt-shop", {
player.ttbuyer = !player.ttbuyer;
}
},
template:
`<div id="TTbuttons">
template: `
<div id="TTbuttons">
<div id="theorembuybackground" class="ttshop-container" :style="containerStyle">
<div data-role="page" class="ttbuttons-row ttbuttons-top-row">
<button
class="o-tt-buy-max-button c-tt-buy-button c-tt-buy-button--unlocked"
style="width:130px; white-space:nowrap;"
v-if="!minimized"
onclick="maxTheorems()"
>
Buy max
</button>
<button
v-if="hasTTAutobuyer"
@click="toggleTTAutobuyer"
class="o-tt-autobuyer-button c-tt-buy-button c-tt-buy-button--unlocked"
id="ttautobuyer"
>
{{autobuyerText}}
</button>
<p id="timetheorems">
<span class="c-tt-amount">{{ theoremAmountDisplay }}</span> Time {{ theoremNoun }}.
<span class="c-tt-amount">{{ theoremAmountDisplay }}</span> Time {{ theoremNoun }}
</p>
<div style="display: flex; flex-direction: row; align-items: center">
<p id="studytreeloadsavetext">{{ $viewModel.shiftDown ? 'save:' : 'load:' }}</p>
<tt-save-load-button v-for="saveslot in 3" :key="saveslot" :saveslot="saveslot"></tt-save-load-button>
<div style="display: flex; flex-direction: row; align-items: center;">
<span class="c-ttshop__save-load-text">{{ saveLoadText }}</span>
<tt-save-load-button v-for="saveslot in 6" :key="saveslot" :saveslot="saveslot"></tt-save-load-button>
</div>
</div>
<div class="ttbuttons-row" v-if="!minimized">
<tt-buy-button :budget="budget.am" :cost="costs.am" :format="formatAM" :action="buyWithAM"/>
<tt-buy-button :budget="budget.ip" :cost="costs.ip" :format="formatIP" :action="buyWithIP"/>
<tt-buy-button :budget="budget.ep" :cost="costs.ep" :format="formatEP" :action="buyWithEP"/>
<div class="l-tt-buy-max-vbox">
<button v-if="!minimized" class="o-tt-top-row-button c-tt-buy-button c-tt-buy-button--unlocked"
onclick="maxTheorems()">
Buy max
</button>
<button v-if="!minimized" class="o-tt-autobuyer-button c-tt-buy-button c-tt-buy-button--unlocked"
onclick="maxTheorems()">
Auto: ON
</button>
<!--
<div v-if="hasTTAutobuyer" class="o-autobuyer-toggle-checkbox c-tt-autobuyer-toggle" @click="toggleTTAutobuyer">
Auto:
<input :checked="ttAutobuyerOn" type="checkbox" />
</div>
-->
</div>
</div>
</div>
<button v-if="minimizeAvailable" id="theorembuybackground" class="ttshop-minimize-btn" @click="minimize">
@ -132,52 +134,68 @@ Vue.component("tt-save-load-button", {
props: {
saveslot: Number
},
data: () => ({
msg: "Hold to save",
showTip: false,
}),
data() {
return {
name: player.timestudy.presets[this.saveslot - 1].name,
};
},
computed: {
tooltip() {
return {
content: this.msg,
placement: "top",
show: this.showTip,
trigger: "manual"
};
preset() {
return player.timestudy.presets[this.saveslot - 1];
},
listeners() {
return Object.assign({}, this.$listeners, {
touchstart: () => this.showTip = true,
mouseover: () => this.showTip = true,
mouseout: () => this.resetTip(),
touchend: () => this.resetTip(),
touchcancel: () => this.resetTip(),
touchmove: e => {
e.preventDefault();
const t = e.changedTouches[0];
if (this.$el !== document.elementFromPoint(t.pageX, t.pageY)) {
this.resetTip();
}
},
"longpress": () => {
studyTreeSaveButton(this.saveslot, true);
this.msg = "Saved";
},
"longpressclick": () => {
studyTreeSaveButton(this.saveslot, false);
}
});
displayName() {
return this.name === "" ? this.saveslot : this.name;
}
},
template:
`<button class="timetheorembtn tt-save-load-btn" v-on="listeners"
v-tooltip="tooltip" v-long-press="{ delay: 1000 }">{{saveslot}}</button>`,
methods: {
resetTip() {
this.msg = "Hold to save";
this.showTip = false;
nicknameBlur(event) {
this.preset.name = event.target.value.slice(0, 4);
this.name = this.preset.name;
},
hideContextMenu() {
this.$viewModel.currentContextMenu = null;
},
save() {
this.hideContextMenu();
this.preset.studies = studyTreeExportString();
},
load() {
this.hideContextMenu();
if (this.preset.studies !== "") importStudyTree(this.preset.studies);
},
handleExport() {
this.hideContextMenu();
copyToClipboardAndNotify(this.preset.studies);
},
edit() {
const newValue = prompt("Edit time study list", this.preset.studies);
this.hideContextMenu();
this.preset.studies = newValue;
}
},
template: `
<hover-menu class="l-tt-save-load-btn__wrapper">
<button slot="object"
class="l-tt-save-load-btn c-tt-buy-button c-tt-buy-button--unlocked"
@click.shift.exact="save"
@click.exact="load">
{{displayName}}
</button>
<div slot="menu"
class="l-tt-save-load-btn__menu c-tt-save-load-btn__menu">
<input type="text" size="4" maxlength="4"
class="l-tt-save-load-btn__menu-rename c-tt-save-load-btn__menu-rename"
:value="name"
ach-tooltip="Set a custom name (up to 4 characters)"
@keyup.esc="hideContextMenu"
@blur="nicknameBlur" />
<div class="l-tt-save-load-btn__menu-item c-tt-save-load-btn__menu-item" @click="edit">Edit</div>
<div class="l-tt-save-load-btn__menu-item c-tt-save-load-btn__menu-item" @click="handleExport">Export</div>
<div class="l-tt-save-load-btn__menu-item c-tt-save-load-btn__menu-item" @click="save">Save</div>
<div class="l-tt-save-load-btn__menu-item c-tt-save-load-btn__menu-item" @click="load">Load</div>
</div>
</hover-menu>
`,
});
Vue.component("tt-buy-button", {

View File

@ -45,6 +45,7 @@ let ui = {
bigCrunch: false,
scrollWindow: 0,
draggingUIID: -1,
currentContextMenu: null,
},
notationName: "",
};

View File

@ -553,6 +553,10 @@ dev.updateTestSave = function() {
player.options.testVersion = 33;
}
if (player.options.testVersion === 33) {
moveSavedStudyTrees();
player.options.testVersion = 34;
}
// Checks for presense of property, so no need for a version bump
convertEPMult();

View File

@ -170,6 +170,7 @@ function onLoad() {
player.options.confirmations.sacrifice = player.options.sacrificeConfirmation;
delete player.options.sacrificeConfirmation;
player.gameCreatedTime = Date.now() - player.realTimePlayed;
moveSavedStudyTrees();
}
//TODO: REMOVE THE FOLLOWING LINE BEFORE RELEASE/MERGE FROM TEST (although it won't really do anything?)
@ -225,6 +226,13 @@ function onLoad() {
}
}
function moveSavedStudyTrees() {
for (let num = 1; num <= 3; ++num) {
const tree = localStorage.getItem(`studyTree${num}`);
if (tree) player.timestudy.presets[num - 1].studies = tree;
}
}
function convertEPMult() {
if (player.epmult === undefined) return;
const mult = new Decimal(player.epmult);

View File

@ -235,7 +235,11 @@ var player = {
ipcost: new Decimal(1),
epcost: new Decimal(1),
studies: [],
shopMinimized: false
shopMinimized: false,
presets: new Array(6).fill({
name: "",
studies: [],
}),
},
eternityChalls: {},
eternityChallGoal: new Decimal(Decimal.MAX_NUMBER),

View File

@ -439,8 +439,12 @@ function respecTimeStudies() {
}
}
function studyTreeExportString() {
return `${player.timestudy.studies}|${player.eternityChallUnlocked}`;
}
function exportStudyTree() {
copyToClipboardAndNotify(player.timestudy.studies + "|" + player.eternityChallUnlocked);
copyToClipboardAndNotify(studyTreeExportString());
}
function importStudyTree(input) {

View File

@ -28,3 +28,7 @@ This file is for styles that are part of Vue components.
white-space: nowrap;
border: none !important;
}
.l-hover-menu__wrapper {
position: relative;
}

View File

@ -149,7 +149,6 @@ button {
#TTbuttons {
position: sticky;
bottom: 0;
overflow: hidden;
font-family: Typewriter, serif;
display: flex;
align-items: flex-end;
@ -165,9 +164,8 @@ button {
.l-tt-buy-button {
width: 17rem;
height: 4rem;
z-index: 1;
margin: 0.5rem;
margin: 0.3rem;
}
.c-tt-buy-button {
@ -210,28 +208,105 @@ button {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: stretch;
}
.ttbuttons-top-row {
align-items: center;
}
.o-tt-buy-max-button {
height: 3rem;
.o-tt-top-row-button {
min-height: 3rem;
font-size: 1.2rem;
margin: 0.5rem;
margin: 0.3rem;
flex-grow: 0;
flex-shrink: 0;
align-self: stretch;
padding-left: 1rem;
padding-right: 1rem;
}
.o-tt-autobuyer-button {
height: 3rem;
width: 14rem;
font-size: 0.7rem;
margin: 0.5rem;
height: 2.5rem;
font-size: 1rem;
margin: 0.3rem;
flex-grow: 0;
flex-shrink: 0;
align-self: stretch;
padding-left: 1rem;
padding-right: 1rem;
min-width: 8rem;
}
.ttbuttons-top-row .tt-save-load-btn {
width: 30px;
margin: 3px;
.l-tt-save-load-btn__wrapper {
margin: 0.3em;
position: relative;
}
.l-tt-save-load-btn {
min-width: 2em;
}
.l-tt-save-load-btn__menu {
position: absolute;
top: -0.5rem;
left: 50%;
transform: translate(-50%, -100%);
padding: 0.5rem 0rem 0.5rem 0rem;
}
.c-tt-save-load-btn__menu {
color: white;
background: black;
border-radius: 0.5rem;
text-align: left;
font-weight: bold;
font-family: Typewriter;
font-size: 1.4rem;
}
.l-tt-save-load-btn__menu::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -0.5rem;
border-width: 0.5rem;
border-style: solid;
border-color: black transparent transparent transparent;
}
.l-tt-save-load-btn__menu-rename {
margin: 0.3rem 0.5rem 0.5rem 0.7rem;
}
.c-tt-save-load-btn__menu-rename {
text-align: left;
font-weight: bold;
font-family: Typewriter;
font-size: 1.4rem;
border: none;
border-radius: 0.3rem;
padding: 0.2rem;
}
.l-tt-save-load-btn__menu-item {
padding: 0.25rem 1rem 0.25rem 1rem;
}
.c-tt-save-load-btn__menu-item:hover {
background: white;
color: black;
}
.c-tt-autobuyer-toggle {
color: initial;
}
.l-tt-buy-max-vbox {
display: inline-flex;
flex-direction: column;
align-items: center;
}
#theorembuybackground {
@ -268,7 +343,7 @@ button {
color: black;
}
#studytreeloadsavetext {
.c-ttshop__save-load-text {
color: black;
font-size: 10px;
}
@ -4499,7 +4574,7 @@ screen and (max-width: 480px) {
}
.l-modal {
position: absolute;
position: fixed;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);

View File

@ -20,7 +20,7 @@ body.t-inverted {
}
.t-inverted #timetheorems,
.t-inverted #studytreeloadsavetext,
.t-inverted .c-ttshop__save-load-text,
.t-inverted #minimizeArrow {
color: #bbb;
}

View File

@ -116,7 +116,7 @@ strong {
text-shadow: 0 0 7px #64DD17;
}
.t-s6 #timetheorems, .t-s6 #studytreeloadsavetext, .t-s6 #minimizeArrow {
.t-s6 #timetheorems, .t-s6 .c-ttshop__save-load-text, .t-s6 #minimizeArrow {
color: grey;
}