New concept MainMenu is now loosely ready for testing.

This is a functional mainmenu which can be tested in-game.
This commit is contained in:
Starystars67 2023-05-08 22:31:07 +01:00
parent cdb9ae9afe
commit 011769d0b6
64 changed files with 7874 additions and 0 deletions

View File

@ -0,0 +1,124 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>BeamNG Main UI</title>
<!-- *** Wondering where all the JS files have gone? Look in resources.js! *** -->
<script type="module" src="./resourceLoader.js"></script>
<!-- These need to be outside the resource loader for... reasons -->
<link type="text/css" rel="stylesheet" href="/ui/lib/ext/angular-material/angular-material-no-animate.min.css">
<link type="text/css" rel="stylesheet" href="/ui/entrypoints/main/main.css">
</head>
<body ng-controller="AppCtrl as app" ng-show="app.uiVisible" use-lang-font="1" class="container">
<md-content ng-cloak ng-if="app.uitest" layout="row" style="border:2px solid #aaa;position:absolute;width:{{app.uitestshow?'400px':'1.6em'}};height:200px;top:50%;right:0; transform:translateY(-50%); z-index:var(--zorder_index_mdcontent); padding:2px;font-family:monospace;border-radius:5px; overflow:hidden;">
<div style="width: 1.2em; padding: 2.5em 0;" ng-click="app.uitestshow = !app.uitestshow">
<span style="display: block; white-space: nowrap; transform-origin: 50% 50%; transform: rotate(90deg);">UI Debug Show/Hide</span>
</div>
<div layout="column" ng-show="app.uitestshow" style="flex-grow: 1;">
<div layout="row" style="background-color:rgb(102, 35, 35);">
<p flex=35>Current UI state:</p>
<md-select ng-model="app.currentStateName" ng-change="app.switchState(app.currentStateName)" flex>
<md-option ng-repeat="(idx, state) in app.states track by $index" ng-value="state.name">{{state.name}}</md-option>
</md-select>
</div>
<div layout="row" style="background-color:rgb(102, 35, 35);">
<md-button flex md-no-ink style="display:block; z-index:var(--zorder_index_prevnext)" class="md-button" ng-click="app.prevState()">&lt; previous</md-button>
<md-button flex md-no-ink style="display:block; z-index:var(--zorder_index_prevnext)" class="md-button" ng-click="app.nextState()">next &gt;</md-button>
</div>
<div layout="row" layout-align="start center" style="background-color:rgb(36, 35, 102);">
<md-checkbox ng-model="app.showApps">Show apps</md-checkbox>
<div>Gamestate: <span style="color:rgb(68, 207, 68)">{{app.gameState}}</span></div>
<md-button ng-click="app.reloadUI()">reload</md-button>
</div>
<div layout="row" layout-align="start center" style="background-color:rgb(102, 102, 35);">
UI sound:
<input id="bng-test-sound" type="text" value="event:>UI>Generic>Select" style="font-size: 0.8em; width: 18em;"/>
<md-button bng-test-sound="bng-test-sound" style="min-width: unset;">test</md-button>
</div>
Gamepad Emulation: use the numpad keys 4862
</div>
</md-content>
<div ng-cloak id="reconnectScreen" ng-if="!$root.ingame && $root.connectionState != 'open'">
<div class="reconnectScreenText">
<center>
<div style="font-size:2vh;margin:3vh;">... reconnecting ...</div>
</center>
</div>
</div>
<!-- UI LOADING - broken UI fallback only -->
<div ng-if="!app.uiReady" style="z-index:var(--zorder_index_broken_ui_loading); position: absolute; top:0;left:0;right:0;bottom:0;background: black; color:white; font-family: Roboto Bold;" layout="column" layout-align="end center">
<h1 style="">
Loading UI...
</h1>
<div style="">
Mods can slow down this process or may have broken the game (<a href="http-external://go.beamng.com/uibroken" style="color:var(--bng-orange)">click here for help</a>)
<br>
&nbsp;
</div>
</div>
<!-- .............. waiting screen overlay .............. -->
<div ng-cloak ng-if="app.isWaiting" style="width:100%; height:100%; background: rgba(0, 0, 0, 0.6); position: absolute; z-index: var(--zorder_index_waiting_screen);" layout="row" layout-align="center center">
<ng-md-icon class="material-icons" style="font-size: 20rem; color: white; text-shadow: -1px 1px 8px #DB7B00, 1px -1px 8px #DB7B00; z-index:var(--zorder_index_waiting_screen_icon);">
access_time
</ng-md-icon>
</div>
<!-- pause indicator (show only while paused), not to be confused with the pause button (shown only while not paused). see menu.html -->
<div ng-cloak ng-if="!app.mainmenu && app.showPauseIcon && app.uiVisible" class="dashBrdButtonEnd dashMenuHeight" style="var(--zorder_index_waiting_screen_icon);">
<div class="dashBrdButton dashBrdButtonPaused" ng-click="app.unpause()">
<span style="padding:0; margin:0" bng-translate="ui.inputActions.general.pause.binding" class="bng-binding dashBrdSvgIcon"></span>
<span class="dashBrdText">{{:: 'ui.inputActions.general.pause.title' | translate}}</span>
</div>
</div>
<game-indicators-layer></game-indicators-layer>
<mission-popups>
<mission-info></mission-info>
</mission-popups>
<!--<game-context-mini-info></game-context-mini-info>-->
<!-- fullscreen LOADING view, covers the real view -->
<div ng-cloak style="position:absolute;top:0;left:0;right:0;bottom:0;z-index: var(--zorder_index_fullscreen_loading)" ng-class="app.transitionAnimation" ui-view="loader" ng-show="$state.current.loaderVisible"></div>
<!-- fullscreen DEFAULT view -->
<div ng-cloak class="UI-Flex-Wrapper" style="position: absolute; top:0; left:0; right:0; bottom:0; z-index: var(--zorder_index_fullscreen_default); display: flex; flex-direction: column; align-items: stretch; justify-content: start;">
<!-- Menu Dashbar goes here -->
<dash-menu ng-controller="MenuController as menuCtrl" ng-if="('menu' | includedByState) && (($state.current.name !== 'menu.mainmenu') || !app.mainmenu)">Dash menu goes here</dash-menu>
<div class="fullscreencontent" style="flex: 1 1 auto; position: relative; pointer-events: none;" ng-class="app.transitionAnimation">
<bng-career-banner></bng-career-banner>
<!-- All the useful content goes here to cover up all the apps without window resize -->
<!-- in theory this line: '!app.mainmenu &&' should be added to the ng-show, but apparently that breaks displaying of some apps (old nav, radial1,2) -->
<app-container id="mainContainer" ng-class="{ 'uiapps-hidden': !app.showApps }" style="position:absolute !important;top:0;right:0;bottom:0;left:0; z-index: var(--zorder_apps_default);">
<canvas id="alignment-canvas" width="1" height="1"></canvas>
<bng-app style="display:none"></bng-app>
</app-container>
<menu-content style="position:absolute !important;top:0;right:0;bottom:0;left:0; z-index: var(--zorder_index_menucontent);" ui-view></menu-content>
</div>
<div class="navbar" ng-if="app.ingame && 'menu' | includedByState">
<!-- menuNavBar contents -->
<menu-navbar></menu-navbar>
</div>
</div>
<fancy-background class="fancyBackgroundFill" ng-if="app.mainmenu"></fancy-background>
<!-- .............. popups overlay .............. -->
<bng-intro-popup></bng-intro-popup>
<bng-dialog></bng-dialog>
<div class="ui-sheet" ng-if="app.uiSheetActive" bng-blur="true"></div>
<div id="vue-app"></div>
</body>
</html>

3110
ui/entrypoints/main/main.css Normal file

File diff suppressed because it is too large Load Diff

2335
ui/entrypoints/main/main.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
import { onCondition, inPath } from "./resourceLoader.js"
const paths = {
MAIN_ENTRYPOINT: '/ui/entrypoints/main',
EXTERNAL_LIBS: '/ui/lib/ext',
INTERNAL_LIBS: '/ui/lib/int',
VUE_DIST: '/ui/ui-vue/dist',
ANGULAR_MODULES: '/ui/modules',
}
const conditions = {
VUE_DEV: env => env.isVueDev,
NOT_VUE_DEV : env => !env.isVueDev
}
export default [
// for external clients: emulation over websocket
`${paths.MAIN_ENTRYPOINT}/comms.js`,
// Vue START
...onCondition(conditions.NOT_VUE_DEV,
inPath(paths.VUE_DIST, [
{ type: "module", src: '/index.js' },
'/index.css'
])
),
...onCondition(conditions.VUE_DEV,
{src:'http://localhost:9000/src/main.js', type: 'module'}
),
{src: `${paths.EXTERNAL_LIBS}/vue-i18n-next/vue-i18n.global.prod.js`, defer: true},
{src: `${paths.EXTERNAL_LIBS}/tiny-emitter/tinyemitter.js`, defer: true},
{src: `${paths.INTERNAL_LIBS}/vueService.js`}, //, defer: true},
{src: `${paths.MAIN_ENTRYPOINT}/angularModules.js`, defer: true},
// 3rd party includes
...inPath(paths.EXTERNAL_LIBS, [
'/angular/angular.js',
'/angular/angular-animate.js',
'/angular/angular-aria.js',
'/angular/angular-sanitize.js',
'/angular-ui-router.min.js',
'/angular-material/angular-material.js',
'/smoothie.min.js',
'/angular-translate/angular-translate-beamng.js',
'/angular-translate/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'/angular-translate/angular-translate-handler-log/angular-translate-handler-log.js',
'/ocLazyLoad.min.js',
'/angular-toastr.tpls.min.js',
'/spine-canvas.js',
'/angular-material-paging.js',
'/jk-rating-stars.min.js',
'/chartist.min.js',
'/hu.js',
'/qrcode.min.js',
// LottieJS
'/lottie.min.js',
// 3rd party test
'/ng-FitText.js',
'/angular-toastr.min.css',
'/angular-material-paging.css',
'/jk-rating-stars.min.css',
'/chartist.min.css',
]),
// BeamNG UI
`${paths.MAIN_ENTRYPOINT}/main.js`,
...inPath(paths.INTERNAL_LIBS, [
'/beamng-core.js',
'/utilities.js',
'/beamng-data.js'
]),
...inPath(paths.EXTERNAL_LIBS, [
'/mdx.js',
'/crossfire-chrome.js',
]),
// Controls
...inPath(paths.INTERNAL_LIBS, [
'/beamng.controls.js',
'/beamng.controls.css',
]),
// Angular Modules
...inPath(paths.ANGULAR_MODULES, [
'/levelselect/levelselect.js',
'/photomode/photomode.js',
'/replay/replay.js',
'/environment/environment.js',
'/scenarioselect/scenarioselect.js',
'/scenariocontrol/scenariocontrol.js',
'/comic/comic.js',
'/vehicleselect/vehicleselect.js',
'/options/options.js',
'/startScreen/startScreen.js',
'/vehicleconfig/vehicleconfig.js',
'/loading/loading.js',
'/repository/repository.js',
'/automation/automation.js',
'/quickrace/quickrace.js',
'/lightrunner/lightrunner.js',
'/dragrace/dragrace.js',
'/mapview/mapview.js',
'/gameContext/gameContext.js',
'/bigmap/bigmap.js',
'/mainmenu/mainmenu.js',
'/menu/menu.js',
'/onlineFeatures/online.js',
'/career/career.js',
'/careerPause/careerPause.js',
'/introPopup/intro.js',
'/careerQuests/quests.js',
'/careerTasklist/tasklist.js',
'/careerVehicleSelect/careerVehicleSelect.js',
'/threeElementSelect/threeElementSelect.js',
'/careerLogBook/logBook.js',
'/appselect/appselect.js',
'/appedit/appedit.js',
'/modmanager/modmanager.js',
'/play/play.js',
'/garage/garage.js',
'/refueling/refueling.js',
'/partInventory/partInventory.js',
'/apps/app-service.js',
'/apps/app-container.js',
'/apps/app.js',
'/campaignselect/campaignselect.js',
'/busRoute/busRoute.js',
'/iconView/icons.js',
'/fadeScreen/fadeScreen.js',
'/atom/title/title.js',
'/atom/card/card.js',
'/atom/tabs/tabs.js',
'/mainmenu/mainmenu.css',
'/menu/menu.css',
'/introPopup/intro.css',
]),
...inPath(paths.INTERNAL_LIBS, [
'/mission-popups/mission-popups.js',
'/colorpicker/color.js',
'/ui-components/bng-components.js',
'/ui-components/bng-components.css'
]),
`${paths.EXTERNAL_LIBS}/keys.css`
]

View File

@ -0,0 +1,7 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M52.7793 16C50.2796 16 48.1153 17.7361 47.573 20.1763L44.9453 32H84.0564L81.4291 20.1764C80.8869 17.7362 78.7226 16 76.2228 16H68.2186L68.3802 26.6667H60.6223L60.784 16H52.7793Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.6087 105.51L39.019 58.6667H89.9819L100.391 105.51C101.131 108.841 98.5964 112 95.1844 112H69.6728L69.4304 96H59.5718L59.3293 112H33.815C30.403 112 27.8685 108.84 28.6087 105.51ZM59.9758 69.3333H69.0265L69.2689 85.3333H59.7334L59.9758 69.3333Z" fill="white"/>
<path d="M27.167 37.3333H101.834V53.3333H27.167V37.3333Z" fill="white"/>
<path d="M21.8337 42.6667H11.167V90.6667H27.167V69.3333H21.8337V42.6667Z" fill="white"/>
<path d="M101.834 69.3333H107.167V42.6667H117.834V90.6667H101.834V69.3333Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 875 B

View File

@ -0,0 +1,3 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.3333 37.3333C21.3333 25.5513 30.8846 16 42.6667 16H85.3333C97.1154 16 106.667 25.5513 106.667 37.3333V42.6664H112V63.9997H106.667V104C106.667 108.418 103.085 112 98.6667 112H93.3333C88.9151 112 85.3333 108.418 85.3333 104V95.9997H42.6667V104C42.6667 108.418 39.0849 112 34.6667 112H29.3333C24.9151 112 21.3333 108.418 21.3333 104V63.9997H16V42.6664H21.3333V37.3333ZM32 58.6664H96V37.3333C96 31.4423 91.2244 26.6667 85.3333 26.6667H74.6667V32C74.6667 34.9455 72.2789 37.3333 69.3333 37.3333H58.6667C55.7211 37.3333 53.3333 34.9455 53.3333 32V26.6667H42.6667C36.7756 26.6667 32 31.4423 32 37.3333V58.6664ZM32 74.6664C32 71.7209 34.3878 69.333 37.3333 69.333H48C50.9455 69.333 53.3333 71.7209 53.3333 74.6664C53.3333 77.6119 50.9455 79.9997 48 79.9997H37.3333C34.3878 79.9997 32 77.6119 32 74.6664ZM80 69.333C77.0545 69.333 74.6667 71.7209 74.6667 74.6664C74.6667 77.6119 77.0545 79.9997 80 79.9997H90.6667C93.6122 79.9997 96 77.6119 96 74.6664C96 71.7209 93.6122 69.333 90.6667 69.333H80Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M64.5 12L78.8655 44.2276L113.955 47.9311L87.7438 71.5524L95.0648 106.069L64.5 88.44L33.9352 106.069L41.2562 71.5524L15.0451 47.9311L50.1345 44.2276L64.5 12Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 289 B

View File

@ -0,0 +1,3 @@
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M27.306 11.8474C28.8641 12.6788 33.2185 14.3911 40.369 12.5985C46.2321 11.1287 50.2152 11.0727 52.3185 11.2217C53.3647 11.2958 54.0833 12.1903 54.0833 13.2421V29.1451C54.0833 30.6362 52.6629 31.8287 51.1761 31.7992C48.9047 31.7541 45.3024 31.9899 40.369 33.2266C31.2262 35.5186 27.4167 32.4993 27.4167 32.4993V55.2382C29.469 55.5986 31.7211 55.7976 34.0836 55.7976C43.6567 55.7976 51.4173 52.53 51.4173 48.4992C51.4173 44.4684 43.6567 41.2008 34.0836 41.2008C33.9136 41.2008 33.5528 41.1988 33.1461 41.1971C32.2001 41.193 31.4167 40.4175 31.4167 39.4714C31.4167 38.5606 32.1446 37.8273 33.0554 37.8298C33.4986 37.8311 33.9013 37.8327 34.0833 37.8327C48.0746 37.8327 59.4167 42.6083 59.4167 48.4994C59.4167 54.3904 48.0746 59.166 34.0833 59.166C20.0921 59.166 8.75 54.3904 8.75 48.4994C8.75 46.2491 10.405 44.1615 13.2304 42.4407C14.8376 41.4619 16.75 42.7596 16.75 44.6414V48.4992C16.7501 50.5689 18.7963 52.4375 22.0833 53.7657V13.8327C22.0833 12.5668 23.1067 11.4525 24.369 11.4525H25.8928C26.3874 11.4525 26.8694 11.6145 27.306 11.8474Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M67.945 20.002L52.2676 40.3903L65.4737 57.6072L58.0597 63.0441C50.2287 52.8499 37.208 35.8596 37.208 35.8596L12.8058 67.6728C20.914 66.5871 27.0342 67.0208 32.8871 68.4054C36.4544 69.2493 39.8357 70.4265 43.3213 71.6859C43.8448 71.8751 44.3713 72.0663 44.903 72.2595L44.9043 72.26L44.9046 72.26L44.9048 72.2601C47.9552 73.3682 51.1732 74.5371 54.9289 75.7108C65.6693 79.0672 75.756 80.8551 84.3091 80.0125C92.6845 79.1874 99.4528 75.8757 104.217 68.9679L104.826 68.0842L67.945 20.002ZM4.87195 73.8056L3.73926 77.77C17.8979 74.9383 25.8266 76.071 43.9496 86.2652C71.6476 101.845 111.345 103.256 125.503 80.0354C123.834 78.6234 120.515 76.5291 118.707 75.5046C113.044 82.8671 103.416 87.9643 94.3542 89.6633V88.5306C103.982 85.6988 111.911 78.3364 114.743 73.2393C111.911 71.5402 109.079 70.4076 109.079 70.4076C97.7524 87.3224 75.5478 86.9011 53.5774 80.0354C50.7109 79.1396 48.0853 78.258 45.6086 77.4264C32.427 73.0004 23.4658 69.9915 4.87195 73.8056Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.8336 5.05873C11.9413 5.02073 12.0587 5.02073 12.1664 5.05873L20.1063 7.86104C20.3342 7.9415 20.5871 7.84733 20.7069 7.63736L20.9799 7.15903C21.1266 6.902 21.0191 6.57451 20.7487 6.45432L12.8631 2.94963C12.3137 2.70543 11.6865 2.70543 11.137 2.94963L3.25142 6.45433C2.981 6.57452 2.87355 6.90199 3.02021 7.15902L3.29307 7.6373C3.41288 7.8473 3.66578 7.94149 3.89377 7.86102L11.8336 5.05873Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.1875 11.7254C6.25991 11.4535 6.43768 11.2166 6.68609 11.0612L6.88987 10.9336C7.09188 10.8072 7.2483 10.6262 7.33846 10.4145L8.19333 8.40777C8.32442 8.10005 8.59196 7.85767 8.93568 7.78226C10.651 7.40592 13.349 7.4059 15.0644 7.78226C15.4081 7.85767 15.6756 8.10004 15.8067 8.40776L16.6616 10.4145C16.7518 10.6262 16.9082 10.8072 17.1102 10.9336L17.314 11.0612C17.5624 11.2166 17.7401 11.4535 17.8126 11.7254L17.9642 12.295C17.988 12.3844 18 12.4761 18 12.5683V14.0265C18 14.0886 17.9946 14.1505 17.9837 14.2117L17.8671 14.8684C17.8145 15.1648 17.6416 15.418 17.4 15.587V16.9366C17.4 17.2478 17.1314 17.5 16.8 17.5H16.2C15.8687 17.5 15.6 17.2478 15.6 16.9366V15.8099L14.4 15.8099L13.8 15.5282H10.2L9.60003 15.8099L8.40003 15.8099V16.9366C8.40003 17.2478 8.1314 17.5 7.80003 17.5H7.20003C6.86866 17.5 6.60003 17.2478 6.60003 16.9366V15.587C6.35846 15.418 6.18552 15.1648 6.13291 14.8684L6.01636 14.2117C6.00549 14.1505 6.00003 14.0886 6.00003 14.0265V12.5683C6.00003 12.4761 6.01206 12.3844 6.03586 12.295L6.1875 11.7254ZM6.95984 12.5429C7.09537 12.161 7.52115 11.9416 7.93698 12.0392L9.08964 12.3099C9.38961 12.3804 9.60003 12.6334 9.60003 12.9238C9.60003 13.2732 9.29832 13.5565 8.92614 13.5565H7.73797C7.17814 13.5565 6.78282 13.0416 6.95984 12.5429ZM16.0631 12.0392C16.4789 11.9416 16.9047 12.161 17.0402 12.5429C17.2172 13.0416 16.8219 13.5565 16.2621 13.5565H15.0739C14.7017 13.5565 14.4 13.2732 14.4 12.9238C14.4 12.6334 14.6105 12.3804 14.9104 12.3099L16.0631 12.0392ZM8.87096 8.80916C8.95016 8.61083 9.14117 8.47051 9.36559 8.44908C11.1607 8.27771 12.7633 8.27247 14.6339 8.44948C14.8586 8.47074 15.05 8.61113 15.1293 8.80966L15.9 10.7396C12.883 10.63 11.1861 10.5734 8.10003 10.7395L8.87096 8.80916Z" fill="white"/>
<path d="M4.38597 17.1209C4.46716 17.0837 4.4334 16.958 4.34548 16.9738C3.4925 17.1266 3.00003 17.3069 3.00003 17.5V20.5C3.00003 21.0523 7.02947 21.5 12 21.5C16.9706 21.5 21 21.0523 21 20.5V17.5C21 17.3069 20.5076 17.1266 19.6546 16.9738C19.5667 16.958 19.5329 17.0837 19.6141 17.1209C20 17.2979 20 17.372 20 17.5C20 18.0523 16.4183 18.5 12 18.5C7.58175 18.5 4.00003 18.0523 4.00003 17.5C4.00003 17.372 4.00003 17.2979 4.38597 17.1209Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,3 @@
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.4871 24.4993C15.4456 24.4993 11.4871 28.1527 11.4871 32.4993C11.4871 36.896 15.1808 40.4993 19.4871 40.4993C23.5528 40.4993 25.0578 38.1936 25.1009 38.1276L25.101 38.1274C25.1385 38.07 25.209 37.9627 25.301 37.8415L35.9255 23.8578C35.9269 23.8558 35.9284 23.8535 35.9302 23.8509C36.5402 22.9384 39.5021 19.1664 46.0847 19.1664C53.3849 19.1664 59.418 25.127 59.418 32.4997C59.418 36.2904 57.6638 39.6228 55.2141 41.9683C52.7805 44.2983 49.4762 45.833 46.0847 45.833C42.7562 45.833 40.2116 44.6346 38.537 43.4733C37.3268 42.6341 37.026 40.9727 37.8652 39.7624C38.7044 38.5522 40.3658 38.2514 41.5761 39.0906C42.5885 39.7926 44.0926 40.4997 46.0847 40.4997C47.898 40.4997 49.9271 39.6466 51.5256 38.116C53.108 36.601 54.0847 34.6 54.0847 32.4997C54.0847 28.0903 50.4571 24.4997 46.0847 24.4997C41.8985 24.4997 40.3834 26.7857 40.364 26.8149L40.3638 26.8152L40.3632 26.8162C40.3331 26.8612 40.2697 26.9559 40.1888 27.0625L29.5678 41.0416C29.5675 41.042 29.5673 41.0424 29.567 41.0427C28.9642 41.9662 26.014 45.8327 19.4871 45.8327C12.2787 45.8327 6.15381 39.8848 6.15381 32.4993C6.15381 25.064 12.6453 19.166 19.4871 19.166C23.0197 19.166 25.5974 20.3976 27.2566 21.6082C28.4464 22.4762 28.7071 24.1444 27.8391 25.3342C26.971 26.5239 25.3028 26.7847 24.1131 25.9166C23.2046 25.2537 21.7044 24.4993 19.4871 24.4993Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M59.167 5.33398L43.167 16.0007V51.4233C33.3363 57.8569 27.167 66.4938 27.167 77.334C27.167 88.4699 33.2124 96.3505 43.167 101.753V117.334H59.167V107.707C62.5405 108.554 66.1082 109.26 69.8337 109.839V117.334H85.8337V111.527C90.1397 111.797 94.5656 111.945 99.0686 111.988C100.594 112.002 101.834 110.764 101.834 109.239C101.834 107.79 100.708 106.588 99.2634 106.474C94.599 106.105 90.1116 105.648 85.8337 105.093V62.4578C79.755 63.1691 74.4506 63.9299 69.8337 64.7554V102.303C65.9854 101.421 62.4172 100.414 59.167 99.2696V67.0999C50.41 69.4996 45.5401 72.3967 43.167 76.0367V90.0395C39.7111 86.4889 37.8337 82.2869 37.8337 77.334C37.8337 61.5271 68.4286 53.3689 97.2337 52.8594C103.407 52.7503 107.449 45.7569 104.024 40.6195C102.656 38.5669 100.351 37.3215 97.8849 37.3838C93.8364 37.4859 89.8034 37.7452 85.8337 38.1617V26.6673L69.8337 16.0007V40.7962C66.1328 41.6476 62.5614 42.656 59.167 43.8215V5.33398Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,3 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.667 29.7382C26.667 25.8287 30.7339 23.2478 34.2712 24.9125L107.079 59.175C111.162 61.0965 111.162 66.9048 107.079 68.8264L34.2712 103.089C30.7339 104.753 26.667 102.173 26.667 98.2631V29.7382Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 329 B

View File

@ -0,0 +1,4 @@
<svg width="65" height="64" viewBox="0 0 65 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.7942 2.65625L49.9332 2.66311C55.9222 2.66853 60.8003 5.98595 60.8003 13.3281V50.6615C60.8003 56.5798 56.0491 61.3281 50.1336 61.3281H23.467C21.2578 61.3281 19.467 59.5373 19.467 57.3281C19.467 55.119 21.2578 53.3281 23.467 53.3281H50.1336C51.6918 53.3281 52.8003 52.2224 52.8003 50.6615V13.3281C52.8003 11.7602 51.5226 10.6651 49.9297 10.6631L23.7922 10.6563C21.5831 10.6557 19.7926 8.86439 19.7932 6.65525C19.7937 4.44611 21.5851 2.6557 23.7942 2.65625Z" fill="white"/>
<path d="M26.2954 18.4997C24.7333 16.9376 22.2006 16.9376 20.6385 18.4997L9.97186 29.1664C8.40977 30.7285 8.40977 33.2612 9.97186 34.8233L20.6385 45.4899C22.2006 47.052 24.7333 47.052 26.2954 45.4899C27.8575 43.9278 27.8575 41.3952 26.2954 39.8331L22.4571 35.9948H40.8003C43.0094 35.9948 44.8003 34.204 44.8003 31.9948C44.8003 29.7857 43.0094 27.9948 40.8003 27.9948H22.4571L26.2954 24.1566C27.8575 22.5945 27.8575 20.0618 26.2954 18.4997Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,3 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M92.7293 24L102.139 43H88.0246L78.615 24H69.2055L78.615 43H64.5007L55.0912 24H45.6817L55.0912 43H40.9769L31.5674 24H26.8626C21.6874 24 17.5002 28.275 17.5002 33.5L17.4531 90.5C17.4531 95.725 21.6874 100 26.8626 100H102.139C107.314 100 111.548 95.725 111.548 90.5V24H92.7293Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M8 40V18h7v22Zm12.5 0V8h7v32ZM33 40V26h7v14Z" fill="white"/></svg>

After

Width:  |  Height:  |  Size: 138 B

View File

@ -0,0 +1,3 @@
<svg width="129" height="128" viewBox="0 0 129 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M42.8672 36.6357C49.1664 31.5887 57.0004 28.8445 65.072 28.8573C73.471 28.8573 81.1901 31.7663 87.2769 36.6357L93.0198 30.8928L98.6085 36.4816L92.8656 42.2245C97.0461 47.4581 99.664 53.7658 100.418 60.4215C101.172 67.0773 100.031 73.8107 97.1275 79.8468C94.2236 85.8829 89.6744 90.9765 84.0035 94.5414C78.3326 98.1062 71.7703 99.9975 65.072 99.9975C58.3737 99.9975 51.8115 98.1062 46.1406 94.5414C40.4696 90.9765 35.9205 85.8829 33.0166 79.8468C30.1127 73.8107 28.9721 67.0773 29.7261 60.4215C30.48 53.7658 33.0979 47.4581 37.2784 42.2245L31.5355 36.4856L37.1243 30.8968L42.8672 36.6397V36.6357ZM69.0245 60.4769V42.6711L49.2622 68.3818H61.1196V86.1678L80.8818 60.4769H69.0245ZM49.2622 17H80.8818V24.9049H49.2622V17Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -0,0 +1,269 @@
<div ng-if="!app.shipping" style="font-weight:bold;width:420px;height:auto;position:fixed;padding-left:5px;top:5px;left:5px;font-size:60px;font-family:Roboto;margin:0;background-color:rgba(0,0,0,0.6);color:white;border-radius:0px 0px 10px 0px;"><md-icon class="material-icons">bug_report</md-icon>DEV RELEASE</div>
<div >
<div class="mainmenu menu-size menu-column">
<!-- title -->
<div class="mainmenu-title">
<div class="logo-container">
<div ng-if="mmCtrl.techLicense" class="logo-tech"></div>
<div ng-if="!mmCtrl.techLicense" class="logo-{{:: mmCtrl.product }}"></div>
</div>
<div class="user-container" ng-click="mmCtrl.handleProfileClick()">
<div class="user-container-icon"><img src="" alt=""/></div>
<div class="user-container-divider"></div>
<div class="user-container-details">
<div class="user-container-details-name">{{:: mmCtrl.steamData.playerName }}</div>
<div class="user-container-details-show-profile">Show Profile</div>
</div>
</div>
</div>
<!-- navigation -->
<div class="nav-container">
<div class="nav-container-button">
<div class="controller-button-large">LB</div>
</div>
<div class="nav-container-divider"></div>
<div class="nav-container-menu">
<div class="nav-container-menu-item" bng-blur="true" bng-nav-item="" nav-item-disabled="false" ng-disabled="card.disabled" ng-click="mmCtrl.handleClick(card)" bng-sound-class="" focus-on-hover="false" role="button" tabindex="0" aria-disabled="true" disabled="disabled">
CAREER
</div>
<div class="nav-container-menu-item" bng-sound-class>
QUICK PLAY
</div>
<div class="nav-container-menu-item" bng-sound-class>
MULTIPLAYER
</div>
<div class="nav-container-menu-item" bng-sound-class href="#/menu/mods/repository" ui-sref="menu.mods.repository">
MODS
</div>
<div class="nav-container-menu-item" bng-sound-class href="#/menu/options/graphics">
SETTINGS
</div>
</div>
<div class="nav-container-divider"></div>
<div class="nav-container-button">
<div class="controller-button-large">RB</div>
</div>
</div>
<!-- nav page items - CAREER -->
<div id="MODE-CAREER">
</div>
<!-- nav page items - QUICK PLAY -->
<div id="MODE-QUICK_PLAY">
<div class="row">
<div class="col-6">
<div class="menu-page-header-item" ng-click="mmCtrl.handleClick({targetState: 'menu.levels'})">
<div class="menu-page-header-item-title">
<div class="menu-page-header-item-title-icon">
</div>
<div class="menu-page-header-item-title-text">
FREEROAM
</div>
</div>
<div class="menu-page-header-item-body">
</div>
</div>
</div>
<div class="col-3">
<div class="menu-page-header-item" ng-click="mmCtrl.handleClick({targetState: 'menu.quickraceOverview'})">
<div class="menu-page-header-item-title">
<div class="menu-page-header-item-title-icon">
</div>
<div class="menu-page-header-item-title-text">
TIME TRIALS
</div>
</div>
<div class="menu-page-header-item-body">
</div>
</div>
</div>
<div class="col-3">
<div class="menu-page-header-item" ng-click="mmCtrl.handleClick({targetState: 'menu.busRoutes'})">
<div class="menu-page-header-item-title">
<div class="menu-page-header-item-title-icon">
</div>
<div class="menu-page-header-item-title-text">
BUS ROUTES
</div>
</div>
<div class="menu-page-header-item-body">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="menu-page-header-item" ng-click="mmCtrl.handleClick({targetState: 'menu.scenarios'})">
<div class="menu-page-header-item-title">
<div class="menu-page-header-item-title-icon">
</div>
<div class="menu-page-header-item-title-text">
SCENARIOS
</div>
</div>
<div class="menu-page-header-item-body">
</div>
</div>
</div>
<div class="col-6">
<div class="menu-page-header-item" ng-click="mmCtrl.handleClick({targetState: 'menu.lightrunnerOverview'})">
<div class="menu-page-header-item-title">
<div class="menu-page-header-item-title-icon">
</div>
<div class="menu-page-header-item-title-text">
LIGHT RUNNER
</div>
</div>
<div class="menu-page-header-item-body">
</div>
</div>
</div>
</div>
</div>
<!-- nav page items - MULTIPLAYER -->
<div id="MODE-MULTIPLAYER">
</div>
<!-- nav page items - MODS -->
<div id="MODE-MODS">
</div>
<!-- nav page items - SETTINGS -->
<div id="MODE-SETTINGS">
</div>
<!-- play modes -->
<div class="menu-row menu-row-nowrap" style="display: none;">
<!-- big button -->
<div class="menu-button menu-button-withicon menu-button-big {{ card.class }}" ng-class="{disabled: mmCtrl.buttons.big.disabled}" bng-blur="true"
bng-nav-item nav-item-disabled="{{!mmCtrl.buttons.big.disabled}}" ng-disabled="card.disabled" ng-click="mmCtrl.handleClick(mmCtrl.buttons.big)" bng-sound-class="bng_click_hover_generic"
focus-if="true"
focus-on-hover
>
<div class="menu-button-icon" ng-style="{ backgroundImage: 'url(' + mmCtrl.buttons.big.icon +')'}"></div>
<span class="menu-button-text">{{mmCtrl.buttons.big.translateid | translate}}</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- normal buttons -->
<div class="menu-column mainmenu-buttongroups">
<div ng-repeat="group in ::mmCtrl.buttons.groups" class="menu-row menu-row-stretch menu-row-nowrap mainmenu-buttons {{ group.class }}">
<div ng-repeat="card in group.list" class="menu-button menu-button-withicon menu-button-med {{ card.class }}" bng-blur="true"
bng-nav-item nav-item-disabled="{{!card.disabled}}" ng-disabled="card.disabled" ng-click="mmCtrl.handleClick(card)" bng-sound-class="{{card.disabled?'':'bng_click_hover_generic'}}"
focus-on-hover="{{!card.disabled}}"
>
<div class="menu-button-icon" style="background-image: url('{{:: card.icon }}');"></div>
<span class="menu-button-text">
{{card.translateid | translate}}
<span ng-if="card.subtranslateid"><br/>({{:: card.subtranslateid | translate}})</span>
</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
</div>
</div>
</div>
<!-- bottom buttons -->
<div class="mainmenu-buttons menu-row mainmenu-buttons-smwrap">
<!-- replays -->
<div class="menu-button menu-button-small" ui-sref="menu.replay" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic" focus-on-hover
>
<span class="menu-button-text">{{:: 'ui.dashboard.replay' | translate}}</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- mods -->
<div class="menu-button menu-button-small" ui-sref="menu.mods.local" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic"
ng-class="{'menu-button-bad': mmCtrl.settings.disableModsAfterUpdate}"
ng-if="mmCtrl.settings.onlineFeatures === 'disable' || mmCtrl.settings.disableModsAfterUpdate"
focus-on-hover
>
<span class="menu-button-text">
{{:: 'ui.mainmenu.mods' | translate}}
<small ng-if="mmCtrl.modsTotal !== 0" class="menu-button-subtext" translate="ui.modmanager.numActive" translate-values="{ all: mmCtrl.modsTotal, active: mmCtrl.modsActive}"></small>
</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- repo -->
<div class="menu-button menu-button-small" ui-sref="menu.mods.repository" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic"
ng-if="mmCtrl.settings.onlineFeatures === 'enable' && !mmCtrl.settings.disableModsAfterUpdate"
focus-on-hover
>
<span class="menu-button-text">
{{:: 'ui.mainmenu.repo' | translate}}
<small ng-if="mmCtrl.modsTotal !== 0" class="menu-button-subtext" translate="ui.modmanager.numActive" translate-values="{ all: mmCtrl.modsTotal, active: mmCtrl.modsActive}"></small>
</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- news (will open in a browser) -->
<!-- <a class="menu-button menu-button-small" href="http-external://go.beamng.com/devblog"
bng-nav-item bng-sound-class="bng_click_hover_generic"
focus-on-hover
>
<span ng-class="{'heading-long': (('ui.mainmenu.news' | translate).length) > 5}" >
{{:: 'ui.mainmenu.news' | translate}}
</span>
<small ng-if="dateShort !== undefined">
{{:: dateShort}}
</small>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</a> -->
<!-- credits -->
<div class="menu-button menu-button-small" ui-sref="credits" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic"
focus-on-hover
>
<span class="menu-button-text">{{:: 'ui.mainmenu.credits' | translate}}</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- options -->
<div class="menu-button menu-button-small" ui-sref="menu.options.graphics" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic"
focus-on-hover
>
<span class="menu-button-text">{{:: 'ui.mainmenu.options' | translate}}</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
<!-- exit -->
<div class="menu-button menu-button-small menu-button-withicon menu-button-quit" ng-click="quit();" bng-blur="true"
bng-nav-item bng-sound-class="bng_click_hover_generic"
focus-on-hover
>
<div class="menu-button-icon" style="background-image: url('/ui/modules/mainmenu/drive/icons/quit.svg');"></div>
<span class="menu-button-text">{{:: 'ui.inputActions.general.quit.title' | translate}}</span>
<div ng-if="fancyblur" class="fancy-blur">
<img-carousel sync="true"></img-carousel>
</div>
</div>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,651 @@
/*thanks to https://codepen.io/shshaw/pen/OVGWLG*/
.contentNavMainmenu .video {
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.contentNavMainmenu md-icon {
color: inherit;
}
.mainmenu {
display: flex;
flex-flow: column;
}
.menu-size {
position: relative;
margin: 0 auto; /* horizontal centering */
width: 90vw; /* we want margins here */
height: 100%; /* for vertical centering */
font-size: 0.6vw; /* this controls the scale of all elements inside */
}
.menu-size::before, .menu-size::after { /* vertical centering */
flex: 0.2 0.2 auto;
content: "";
}
@media (min-width: 1320px) { /* big screens */
.menu-size {
max-width: 90vw;
font-size: 8px;
}
}
/* medium screens are responsive */
@media (max-width: 800px) { /* small screens */
.menu-size {
max-width: 90vw;
font-size: 4.5px;
}
.mainmenu-buttons-smwrap {
flex-wrap: wrap !important;
}
.mainmenu-buttons-smwrap > .menu-button {
margin-bottom: 0.5rem !important;
}
.mainmenu-buttongroups .mainmenu-buttons-smwrap {
margin-bottom: -0.5rem;
}
.mainmenu-buttongroups .mainmenu-buttons-smwrap > .menu-button {
flex-basis: 40%;
}
.mainmenu-buttongroups .mainmenu-buttons-smwrap > .menu-button:nth-child(2n) {
margin-right: 0 !important;
}
.mainmenu-buttongroups .mainmenu-buttons-smwrap > .menu-button:nth-child(2n+1) {
margin-right: 0.5rem !important;
}
.menu-button-big {
width: 3em !important;
height: 8.5em !important;
}
.menu-button-small {
height: 1.2em !important;
}
.menu-button-quit {
flex: 0 1 9em !important;
max-width: unset !important;
}
}
.mainmenu * {
position: relative;
}
.mainmenu > *:not(:last-child) {
margin-bottom: 2em;
}
.mainmenu-title {
margin-bottom: 5em !important;
}
.logo-container {
width: 50em;
padding-top: 9em;
float: left;
}
.logo-container > * {
position: absolute;
top: 17%;
bottom: 17%;
left: 0;
right: 0;
height: unset !important;
width: unset !important;
}
.user-container {
/* width: 50em; */
/* padding-top: 9em; */
height: 100%;
float: right;
min-width: 250px;
background: var(--bng-black-6);
border-radius: 50px;
overflow: hidden;
white-space: nowrap;
display: flex;
}
/*.user-container > * {
position: absolute;
top: 17%;
bottom: 17%;
left: 0;
right: 0;
height: unset !important;
width: unset !important;
}*/
.user-container-icon {
height: 66px !important;
width: 66px;
border: solid white;
border-radius: 50px;
}
.user-container-divider {
width: 2px !important;
height: 52px !important;
background: #848484;
display: block;
position: relative;
margin: 10px 20px;
}
.user-container-details {
margin: 10px 25px 10px 0px;
color: white;
}
.user-container-details-name {
font-size: large;
font-weight: 700;
}
.user-container-details-show-profile {
font-size: large;
font-weight: 300;
}
.nav-container {
overflow: hidden;
white-space: nowrap;
font-size: x-large;
font-weight: 700;
color: white;
background: var(--bng-black-6);
border-radius: 10px;
display: flex;
}
.nav-container-menu {
display: flex;
width: 100%;
}
.nav-container-divider {
margin: 10px 15px;
background: #848484;
width: 2px !important;
}
.nav-container-menu-item {
padding: 15px 10px;
width: calc(100% / 5);
text-align: center;
}
.nav-container-menu-item[disabled] {
padding: 15px 10px;
width: calc(100% / 5);
text-align: center;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0, 0.4);
background-color: rgba(0,0,0, 0.4);
}
.nav-container-menu-item:active {
padding: 15px 10px;
width: calc(100% / 5);
background: var(--bng-orange);
border-radius: 10px;
box-shadow: 0 0 20px var(--bng-orange);
}
.nav-container-menu-item:hover {
padding: 15px 10px;
width: calc(100% / 5);
background: var(--bng-orange-shade1);
border-radius: 10px;
box-shadow: 0 0 20px var(--bng-orange);
}
.controller-button-large {
border: solid 3px var(--bng-cool-gray-300);
border-radius: 10px;
margin: 7px;
padding: 5px 10px;
background: var(--bng-cool-gray-800);
}
.col-6 {
width: calc(50%);
float: initial;
}
.row {
display: flex;
}
.col-3 {
width: calc(33.3%);
float: initial;
}
.menu-page-header-item {
border: solid black 2px;
margin: 5px;
border-radius: 10px;
min-height: 300px;
}
.menu-page-header-item-title {
height: 50px;
background-image: linear-gradient(to right, var(--bng-black-8), rgba(0,0,0,0));
color: white;
font-size: x-large;
font-weight: 700;
display: flex;
}
.menu-page-header-item-title-icon {
background: var(--bng-orange);
width: 50px;
height: 100%;
border-radius: 10px 0px 0px;
margin-right: 15px;
}
.menu-page-header-item-title-text {
padding-top: 6px;
}
.logo-tech,
.logo-drive,
.logo-research {
display: inline-block;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
.logo-tech {
background-image: url("/ui/images/tech.png");
}
.logo-drive {
background-image: url("/ui/images/logos.svg#bng-drive-white");
}
.logo-research {
background-image: url("/ui/images/research.svg");
}
.mainmenu-buttons {
margin: 0.5rem 0;
}
.mainmenu-buttons .menu-button {
margin: 0;
}
.mainmenu-buttons .menu-button:not(.menu-button-small):not(:last-child) {
margin-right: 1em;
}
.mainmenu-buttons .menu-button.menu-button-small {
margin-left: 0.5em;
margin-right: 0.5em;
}
.menu-column {
display: flex;
flex-flow: column;
justify-content: stretch;
align-items: stretch;
}
.menu-row {
display: flex;
flex-flow: row;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
}
.menu-row-nowrap {
flex-wrap: nowrap;
}
.menu-row-stretch {
justify-content: stretch;
align-items: stretch;
}
.menu-row > * {
flex: 1 1 auto;
}
.menu-button {
flex: 1 1 auto;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
margin: 0.5rem;
padding: 1rem;
line-height: 1.1em;
color: white;
background-color: rgba(0,0,0, 0.6);
/* backdrop-filter: blur(10px); -- doesn't work on old cef */
/* border: 4px solid transparent; */
border-radius: var(--bng-corners-1);
text-align: center;
text-decoration: none;
cursor: default;
}
.menu-button-big {
flex: 0.25 1 auto;
font-size: 4em;
width: 4em;
height: 4em;
margin-left: 0;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
margin-right: 0.8em;
padding: 1.75em 3em;
}
.menu-button-big .menu-button-icon {
min-height: 3em;
}
.menu-button-med {
flex: 1 0 20%;
font-size: 2.5em;
height: 5em;
padding: 0.25em;
}
.menu-button-small {
flex: 0 1 9em;
font-size: 2.5em;
height: 1.5em;
}
.menu-button-big,
.menu-button-med,
.menu-button-small {
display: flex;
justify-content: center;
align-items: center;
}
.menu-button-big,
.menu-button-med {
flex-flow: column;
}
.menu-button-small {
flex-flow: row;
flex-wrap: nowrap;
}
.menu-button small {
font-size: 0.6em;
line-height: 1em;
opacity: 0.8;
}
.menu-button-icon {
min-width: 2em;
min-height: 2em;
background-repeat: no-repeat;
background-size: contain;
background-position: 50% 50%;
margin-bottom: 0.25em;
}
.menu-button-text {
font-family: "Overpass", var(--fnt-defs);
font-style: italic;
font-weight: 900;
letter-spacing: 0.02em;
line-height: 1.2em;
}
.menu-button-subtext {
display: block;
}
.menu-button-small.menu-button-withicon .menu-button-text {
text-align: left;
}
.menu-button[disabled] {
background-color: rgba(0,0,0, 0.4);
pointer-events: none;
}
.menu-button[disabled] > *:not(.fancy-blur) {
opacity: 0.65;
}
.menu-button[disabled].semi-disabled {
pointer-events: initial;
}
.menu-button[disabled].semi-disabled:focus {
box-shadow: initial;
}
.menu-button[disabled].semi-disabled:focus::before {
content: none;
}
.menu-button-bad {
/* border-color: rgba(255,0,0, 0.6) !important; */
border: 3px solid rgba(255,0,0, 0.6);
text-shadow: 0 0 1em #000;
}
.menu-button-bad > * {
z-index: 2;
}
.menu-button-bad::after {
content: "";
position: absolute;
top: 0;
left: 45%;
width: 10%;
height: 100%;
transform: skewX(-23deg);
background-color: rgba(255,0,0, 0.6);
z-index: 1;
}
.menu-button-bad:focus {
border-color: rgba(255,0,0, 0.8) !important;
}
.menu-button-bad:focus::after {
background-color: rgba(255,0,0, 0.8) !important;
}
.menu-button-quit {
background-color: rgba(255,0,0, 0.6);
flex: 0 1 auto;
max-width: 7em;
}
.menu-button-quit .menu-button-icon {
min-height: 1.5em;
margin: 0;
}
.menuNavbar .navBtn {
cursor: pointer;
color: white;
padding: 0.5em 0.75em 0.5em 0.5em;
border-radius: var(--bng-corners-1);
}
.menuNavbar .navBtn:hover {
background-color: rgba(255,102,0, 1);
}
.menuNavbar .navBtn .bng-binding {
margin-left: 0.25em !important;
margin-right: 0.25em !important;
}
.contentNavMainmenu {
width:100%;
height: 100%;
overflow-y:hidden !important;
overflow-x:hidden !important;
position: relative;
}
.contentNavMainmenu #video-viewport {
position:absolute;
left:0;
right:0;
bottom:0;
top:0;
}
.contentNavMainmenu #shippinginfo {
position: absolute;
bottom: 0;
right: left;
color: black;
border-radius: 0 var(--bng-corners-3) 0 0;
z-index: var(--zorder_mainmenu_shippinginfo);
background-color:white;
padding:3px;
font-weight:bold;
font-family:var(--fnt-defs);
border-top: 2px solid #333;
border-right: 2px solid #333;
}
.contentNavMainmenu #infobox {
position: absolute;
bottom: 0px;
z-index: var(--zorder_mainmenu_infobox);
max-width: 700px;
}
.contentNavMainmenu #infobox p {
margin: -3px;
}
.contentNavMainmenu #account-info {
position: absolute;
top: 0px;
right: 0px;
z-index: var(--zorder_mainmenu_accountinfo);
padding: 5px;
}
#onlinestate {
/* border-bottom:2px solid #56D70B; */
color: #56D70B;
text-align:center;
padding:5px;
font-weight: 700;
}
#versioninfo a {
color: rgba(255, 103, 0, 1);;
}
.contentNavMainmenu #onlineInfo {
position: absolute;
top: 120px;
right: 0px;
z-index: var(--zorder_mainmenu_onlineinfo);
padding: 5px;
}
.contentNavMainmenu #versioninfo {
position: absolute;
bottom: 0px;
right: 0px;
z-index: var(--zorder_mainmenu_versioninfo);
}
.contentNavMainmenu .blendbox {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0,0,0,1);
z-index: var(--zorder_mainmenu_blendbox);
opacity:0;
-webkit-transition: 3s linear all;
transition: 3s linear all;
}
.new-tile {
font-size: 3vh;
font-family: 'Overpass', var(--fnt-defs);
cursor: pointer;
color: rgb(255, 255, 255);
text-shadow: -3px 3px 6px #00000050;
background-color: rgba(0, 0, 0, 0.5);
filter: brightness(0.8);
transition: filter .3s;
}
.new-tile:hover {
filter: brightness(1.1);
}
.new-tile figure {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: flex-start;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: flex-start;
height: 100%;
width: 100%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 18px;
margin: 0;
}
.new-tile figure md-grid-tile-header {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: flex-start;
height: 100%;
width: 100%;
color: #fff;
background: rgba(0,0,0,.18);
overflow: hidden;
position: absolute;
left: 0;
right: 0;
padding: 18px;
}
.new-tile figure md-grid-tile-header figcaption h2 {
margin: 0 0 0 0;
}
.new-tile figure md-grid-tile-header figcaption h3 {
margin: 0 0 0 0;
opacity: 0;
transition: opacity 0.2s;
}
.new-tile:hover figure md-grid-tile-header figcaption h3 {
opacity: 1;
}
.main-menu-image {
position: absolute;
width: 40%;
height: 20%;
top: 0%;
left: 10%;
}
.fancy-blur {
position: absolute;
overflow: hidden;
clip: rect(0,auto,auto,0);
z-index: -1;
pointer-events: none;
}
.fancy-blur > * {
position: fixed;
}
.fancy-blur,
.fancy-blur > * {
top: 0;
left: 0;
right: 0;
bottom: 0;
}

View File

@ -0,0 +1,536 @@
'use strict'
angular.module('beamng.stuff')
// no fucking clue, why this doesn't just work in the videoBackgroundDirective itself, but well you know
// idea from: http://stackoverflow.com/questions/28016476/angular-on-video-load-event
.directive('onVideoStart', function () {
return {
restrict: 'A',
scope: {
onVideoStart: '&'
},
link: function (scope, $element) {
$element[0].addEventListener('play', function () {
scope.onVideoStart()
})
}
}
})
.directive("fancyBackground", ["TechLicenseState", function (techLicenseState) {
return {
template: `
<img-carousel imageurls="files" delay="10000" slow="true" nav="false" random="true" class="filler"></img-carousel>
`,
scope: {
videoLoaded: "&",
},
link: function (scope, elem, attr) {
scope.files = [
"/ui/modules/mainmenu/drive/images/1.jpg",
"/ui/modules/mainmenu/drive/images/2.jpg",
"/ui/modules/mainmenu/drive/images/3.jpg",
"/ui/modules/mainmenu/drive/images/4.jpg",
"/ui/modules/mainmenu/drive/images/5.jpg",
"/ui/modules/mainmenu/drive/images/6.jpg",
"/ui/modules/mainmenu/drive/images/7.jpg",
"/ui/modules/mainmenu/drive/images/8.jpg",
];
bngApi.engineLua("sailingTheHighSeas", ahoy => {
if (ahoy)
scope.files = ["/ui/modules/mainmenu/unofficial_version.jpg"];
});
techLicenseState.state.then(licenseVerified => {
if (licenseVerified)
scope.files = ["/ui/modules/mainmenu/drive/tech_images/1.jpg"];
});
}
}
}])
.directive('menuNavbar', ['Utils', '$rootScope', function (Utils, $rootScope, ) {
return {
template: `
<div class="menuNavbar" layout="row" bng-blur="true" layout-align="center center" layout-wrap="">
<div layout="row" layout-align="start stretch" flex="noshrink" flex="75" flex-md="100">
<span bng-no-nav="true" class="navBtn" layout="row" layout-align="center center" style="pointer-events: none; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0.5em"><div class="binding-icon-mask icon-light" style="margin-right: 0.25em; -webkit-mask-image: url('/ui/modules/options/deviceIcons/xbox/x_dpad_default_filled.svg');"></div><span>{{ "ui.mainmenu.navbar.navigate" | translate }}</span></span>
<span bng-no-nav="true" bng-translate='ui.mainmenu.navbar.select' class="navBtn" layout="row" layout-align="center center" style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0.5em" ng-click="nav('confirm')"></span>
<span bng-no-nav="true" bng-translate='ui.mainmenu.navbar.back' class="navBtn" layout="row" layout-align="center center" style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0.5em" ng-click="nav('back')"></span>
<span bng-no-nav="true" bng-translate='ui.mainmenu.navbar.tab_left' ng-if="!mainmenu" class="navBtn" layout="row" layout-align="center center" style="margin-top: 0px; margin-bottom: 0px; margin-right: 0.5em; margin-right: 0.5em" ng-click="nav('tab-left')"></span>
<span bng-no-nav="true" bng-translate='ui.mainmenu.navbar.tab_right' ng-if="!mainmenu" class="navBtn" layout="row" layout-align="center center" style="margin-top: 0px; margin-bottom: 0px; margin-right: 0.5em; margin-right: 0.5em" ng-click="nav('tab-right')"></span>
</div>
<div layout="row" layout-align="start fill" style="margin:0;padding:0;color:white;">
<div ng-if="steamData && steamData.working && steamData.loggedin" layout="row" layout-align="start center" ng-cloak >
<img src="/ui/modules/mainmenu/steamicon.png" style="padding: 5px">
<div layout="row" style="padding: 5px">
<span>{{ ::steamData.playerName }}</span>
<span ng-if="::steamData.branch != 'public'" style="padding-left: 5px;">Branch: {{ ::steamData.branch }}</span>
</div>
</div>
<div id="onlinestate" ng-show="onlineState">
ONLINE
</div>
</div>
<div style="margin-left:16px;border-right:3px solid #333;height:100%">&nbsp;</div>
<div bng-no-nav="true" ng-click="showBuildInfo = !showBuildInfo" style="text-align:right;cursor: pointer; color:white;margin-left:16px;">
<div ng-show='!showBuildInfo'>Alpha v{{ ::versionSimpleStr }}</div>
<div ng-show='showBuildInfo' style="font-size:0.7em;">Alpha v{{ ::versionStr }} <br/> {{ ::buildInfoStr }}</div>
</div>
</div>
`,
scope: {
},
link: function (scope, $element, attr) {
// do quick check right in main menu, to ensure *some* of our UI/LUA code can work in languages with certain non-english characters
bngApi.serializeToLuaCheck("English: " + "hello")
bngApi.serializeToLuaCheck("Spanish: " + "güeñes")
bngApi.serializeToLuaCheck("French: " + "bâguéttè, garçon")
bngApi.serializeToLuaCheck("Czech: " + "Kl<03>vesnice")
bngApi.serializeToLuaCheck("Korean: " + decodeURIComponent("%0D%EF%BF%BD%EF%BF%BD%0B%EF%BF%BD%EF%BF%BD%0B%EF%BF%BD%EF%BF%BD"))
bngApi.serializeToLuaCheck("Chinese Sim: " + "欢迎来到简体中文版的")
bngApi.serializeToLuaCheck("Chinese Tr: " + "歡迎來到")
bngApi.serializeToLuaCheck("Japanese: " + "』日本語版にようこそ")
bngApi.serializeToLuaCheck("Polish: " + "źćłąóę")
bngApi.serializeToLuaCheck("Russian: " + "абвгеёьъ")
scope.nav = function(action, val) {
$rootScope.$broadcast('MenuItemNavigation', action, val)
}
scope.radialMenu = function(action, val) {
bngApi.engineLua("extensions.core_quickAccess.setEnabled(true)")
}
// VERSION INFO
scope.showBuildInfo = false
scope.versionStr = beamng.version
// convert from 1.2.3.4 to 1.2.3 as we do not want to attach the build number in the simple display
var versionSplit = scope.versionStr.split('.')
if(versionSplit.length == 5) versionSplit.pop() // remove build number (5th)
for(var i = 0; i < 3; i++) {
if(versionSplit[versionSplit.length - 1] == '0') versionSplit.pop(); // remove any '0' for simplicity reasons
}
scope.versionSimpleStr = versionSplit.join('.')
scope.buildInfoStr = beamng.buildinfo
// account info
scope.$on('SteamInfo', function (event, data) {
scope.$apply(function () {
scope.steamData = data
})
})
scope.onlineState = false
scope.$on('OnlineStateChanged', function (event, data) {
scope.$applyAsync(function () {
scope.onlineState = data
})
})
scope.$on('ShowEntertainingBackground', (ev, mainmenu) => {
scope.$evalAsync(() => {
scope.mainmenu = mainmenu
})
})
bngApi.engineLua('core_online.requestState()')
}
}
}])
.directive('onlineMessage', ['$sce', 'Utils', '$state', function ($sce, Utils, $state) {
return {
restrict: 'E',
replace: true,
template: `
<div ng-if="messageData.length > 0" layout="column" layout-align="center center" ng-style="style" >
<div>
<div style="height: 5vh; width:100%;" layout="row" layout-align="space-between center" class="loadingHint md-padding">
<div>News</div>
<div ng-click="close()" style="cursor: pointer; line-height: 50%; background-color: #FF6700">
<md-icon class="material-icons md-default-theme" style="margin: 0 auto; font-size: 1.2em; color: black;">close</md-icon>
</div>
</div>
<md-content class="filler loadingHint" style="max-height: 30vh; max-width:400px;">
<div layout="column" layout-align="center center" ng-repeat="message in messageData" >
<div ng-bind-html="message.msg" class="md-padding"></div>
<div layout="row" class="md-padding" layout-wrap layout-align="start center">
<md-button bng-nav-item ng-click="clicked(btn)" ng-repeat="btn in buttons" class="md-accent md-raised md-padding">{{btn.label | translate}}</md-button>
</div>
</div>
</md-content>
</div>
</div>
`,
link: function (scope) {
var uids = {}
scope.$on('OnlineMessage', function (ev, data) {
scope.messageData = data
scope.$evalAsync(() => {
// uid = data.uid
for (var key in scope.messageData) {
switch (scope.messageData[key].contenttype) {
case 'html':
scope.messageData[key].msg = $sce.trustAsHtml(scope.messageData[key].msg)
break
case 'bbcode':
scope.messageData[key].msg = $sce.trustAsHtml(Utils.parseBBCode(scope.messageData[key].msg))
break
default:
scope.messageData[key].msg = scope.messageData[key].msg
}
uids[key] = scope.messageData[key].uid
scope.style = scope.messageData[key].css //{position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, 'background': ' repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.75) 35px, rgba(0, 0, 0, 0.8) 35px, rgba(0, 0, 0, 0.8) 70px)'}
}
})
})
scope.close = function () {
for (var key in uids) {
bngApi.engineLua(`extensions.hook("onUIOnlineMessageHide", "${uids[key]}")`)
}
scope.messageData = undefined
}
scope.clicked = function (btn) {
switch (btn.type) {
case 'hide-temp':
scope.messageData = undefined
break
case 'hide-perm':
scope.messageData = undefined
bngApi.engineLua(`extensions.hook("onUIOnlineMessageHide", "${uid}")`)
break
case 'luacmd':
bngApi.engineLua(btn.cmd)
break
case 'url':
document.location.href = btn.url
break
case 'state':
$state.go(btn.state, btn.params || {})
break
default:
console.warn('Unknown action type in online message button')
}
}
bngApi.engineLua('extensions.hook("onUIOnlineMessageReady")')
}
}
}])
.controller('MainMenuController', ['$rootScope', '$scope', 'toastr', '$state', 'Settings', '$http', '$filter', 'Utils', 'gamepadNav', 'TechLicenseState', 'ConfirmationDialog', function($rootScope, $scope, toastr, $state, Settings, $http, $filter, Utils, gamepadNav, techLicenseState, ConfirmationDialog) {
let vm = this
vm.product = beamng.product
vm.techLicense = false
techLicenseState.state.then((licenseVerified) => {
vm.techLicense = licenseVerified
})
// account info
$scope.$on('SteamInfo', function (event, data) {
vm.steamData = data
})
// always hide apps in main menu
$scope.$parent.app.showApps = false
// settings
{
vm.settings = Settings.values
$scope.$on('SettingsChanged', (ev, data) => {
vm.settings = data.values
})
}
if (!vm.techLicense && (Settings.values.onlineFeatures === 'ask' || Settings.values.telemetry === 'ask')) {
$state.go('menu.onlineFeatures')
}
bngApi.engineLua('core_online.requestState()')
// hardwareinfo warnings, etc
{
bngApi.engineLua('core_hardwareinfo.requestInfo()')
$scope.$on('HardwareInfo', function (event, data) {
if (data.globalState !== 'ok') {
for (var key in data) {
if(data[key].warnings === undefined) continue
for (var i=0; i < data[key].warnings.length; i++) {
if(data[key].warnings[i].ack !== undefined) continue
var txt = $filter('translate')('ui.performance.warnings.' + data[key].warnings[i].msg)
var html = Utils.parseBBCode(txt)
toastr[(data.globalState === 'warn' ? 'warning' : 'error')](
$filter('translate')('ui.mainmenu.warningdetails'),//need a unique message
html,
{
positionClass: 'toast-top-right',
timeOut: 0,
extendedTimeOut: 0,
onTap: function () {
$state.go('menu.options.performance')
}
}
)
}
}
}
})
}
// repository button: X of Y mods active
{
vm.modsTotal = 0
vm.modsActive = 0
bngApi.engineLua('core_modmanager.requestState()')
$scope.$on('ModManagerModsChanged', function (event, data) {
var list = data.convertToArray()
vm.modsActive = list.filter((elem) => elem.modname != 'translations' && elem.active).length
vm.modsTotal = list.filter((elem) => elem.modname != 'translations').length
})
}
{
// navigation things
let prevCross = gamepadNav.crossfireEnabled()
let prevGame = gamepadNav.gamepadNavEnabled()
gamepadNav.enableCrossfire(true)
gamepadNav.enableGamepadNav(true)
$scope.$on('$destroy', () => {
gamepadNav.enableCrossfire(prevCross)
gamepadNav.enableGamepadNav(prevGame)
})
}
$scope.quit = function() {
// copypasted from entrypoints/main/main.js
bngApi.engineScript('quit();'); //It should work but doesn't, `Platform::postQuitMessage` is executed but nothing happens, maybe CEF catch that message
bngApi.engineLua("TorqueScript.eval('quit();')")
}
$scope.radialmenu = function() {
}
let buttonsDefault = [
// big
{
translateid: 'ui.playmodes.freeroam',
icon: '/ui/modules/mainmenu/drive/icons/play.svg',
targetState: 'menu.levels'
},
// rows with 4 elements each
{
translateid: 'ui.playmodes.campaigns',
icon: '/ui/modules/mainmenu/drive/icons/campaigns.svg',
targetState: 'menu.campaigns'
},
{
translateid: 'ui.playmodes.scenarios',
icon: '/ui/modules/mainmenu/drive/icons/scenarios.svg',
targetState: 'menu.scenarios'
},
{
translateid: 'ui.playmodes.quickrace',
icon: '/ui/modules/mainmenu/drive/icons/timetrials.svg',
targetState: 'menu.quickraceOverview'
},
{
translateid: 'ui.mainmenu.garage',
icon: '/ui/modules/mainmenu/drive/icons/garage.svg',
action: () => {
bngApi.engineLua(`gameplay_garageMode.start()`)
},
get disabled() { return $scope.$parent.app.gameState === "garage" },
},
{
translateid: 'ui.playmodes.bus',
icon: '/ui/modules/mainmenu/drive/icons/busroutes.svg',
targetState: 'menu.busRoutes'
},
{
translateid: 'ui.playmodes.lightRunner',
icon: '/ui/modules/mainmenu/drive/icons/lightrunner.svg',
targetState: 'menu.lightrunnerOverview'
},
// {
// translateid: 'ui.dashboard.trackBuilder',
// icon: '/ui/modules/mainmenu/drive/icons/autobahn.svg',
// action: () => bngApi.engineLua("extensions.trackbuilder_trackBuilder.toggleTrackBuilder()")
// },
{
translateid: 'ui.playmodes.trackBuilder',
icon: '/ui/modules/mainmenu/drive/icons/autobahn.svg',
action: () => { // TODO: toggle track builder in current level
// bngApi.engineLua("extensions.trackbuilder_trackBuilder.toggleTrackBuilder()")
bngApi.engineLua(`freeroam_freeroam.startTrackBuilder('glow_city')`)
},
get disabled() { return $scope.$parent.app.gameState === "garage" },
},
// {
// translateid: 'ui.quickrace.tracks.procedural',
// icon: '/ui/modules/mainmenu/drive/icons/infinity.svg',
// targetState: 'quickraceTrackSelect'
// },
{
translateid: 'ui.playmodes.career',
subtranslateid: 'ui.playmodes.comingSoon',
icon: '/ui/modules/mainmenu/drive/icons/career.svg',
disabled: true,
class: "semi-disabled", // semi-disabled will make the button clickable, not changing the style if it was disabled
// targetState: 'menu.career'
action: () => {
if (!$scope.inCareer) {
ConfirmationDialog.open(
"ui.career.experimentalTitle", "ui.career.experimentalPrompt",
[
{ label: "ui.common.no", key: false, isCancel: true },
// { label: "Enter and don't show this again", key: true },
{ label: "ui.career.experimentalAgree", key: true, default: true },
],
{ class: "experimental" }
).then(res => {
if (!res)
return;
$state.go("menu.career");
});
} else {
$state.go("menu.career");
}
},
},
];
let clickytmr, clickycnt = 0;
function clicky(cnt=6, timeout=300) {
clickytmr = clearInterval(clickytmr);
clickycnt++;
if (clickycnt === cnt) {
clickycnt = 0;
return true;
}
clickytmr = setInterval(() => {
clickycnt--;
if (clickycnt <= 0) {
clickycnt = 0;
clickytmr = clearInterval(clickytmr);
}
}, timeout);
return false;
}
$scope.inCareer = false;
bngApi.engineLua("career_career.isCareerActive()", data => {
$scope.inCareer = !!data;
});
vm.buttons = {
big: null,
groups: []
};
{
let buttons = [];
vm.addButton = function (button, draw=true) {
if (!vm.buttons.big) {
vm.buttons.big = button;
} else {
// add new button
buttons.push(button);
// rebuild layout
if (draw)
vm.rebuildButtons();
}
};
let max1 = 3, max2 = 4;
vm.rebuildButtons = function () {
let len = buttons.length;
// find out optimal count per row
let max = max1;
if ((len % max1 || max1) < (len % max2 || max2))
max = max2;
// calculate new layout
let top = len % max || max,
groupsmax = Math.ceil(len / max);
// clear/add rows
let groupslen = vm.buttons.groups.length;
for (let i = 0; i < groupsmax; i++) {
if (i < groupslen)
vm.buttons.groups[i].list = [];
else
vm.buttons.groups.push({ list: [] });
}
// rebuild the layout
let group = 0;
for (let button of buttons) {
if (vm.buttons.groups[group].list.length === (group === 0 ? top : max))
group++;
vm.buttons.groups[group].list.push(button);
}
// allow/disallow wrapping the buttons on even count
for (let grp of vm.buttons.groups) {
let len = grp.list.length;
grp.class = len > 2 && len / 2 % 1 === 0 ? "mainmenu-buttons-smwrap" : null;
}
// sync with fancy-background
setTimeout(fancySync, 100);
};
}
// populate menu with default buttons
for (let button of buttonsDefault)
vm.addButton(button, false);
vm.rebuildButtons();
// broadcast event for an additional buttons
$rootScope.$broadcast('MainMenuButtons', vm.addButton);
vm.openRepo = function () {
window.location.href = 'http-external://www.beamng.com/resources/?ingame=2'
}
vm.handleClick = function(card) {
if(card.action) {
card.action()
return
}
if(card.targetState) {
$state.go(card.targetState)
return
}
}
$scope.fancyblur = false;
function fancySync() {
// find fancy bg
const fancybg = document.querySelector("fancy-background > .img-carousel");
if (!fancybg) {
$scope.fancyblur = false;
return;
}
$scope.fancyblur = true;
$scope.$evalAsync(() => {
// get all target blur elements
const blurs = Array.from(document.querySelectorAll(".fancy-blur > .img-carousel"));
// and connect them to master so they will work in sync
fancybg.__connect(
blurs,
// function to modify images list for targets - function (orig_list) { return orig_list }
// here, we change images from "image.jpg" to "image_blur.jpg"
images => images.map(img => img.replace(/\.(.{3,4})$/, "_blur.$1"))
// note: blurred images are 1280x720 with gaussian blur 6.0 (resize, then blur)
);
});
}
fancySync();
}])

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="120"
height="120"
viewBox="0 0 120 120"
id="svg6300"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="offbtn.svg">
<defs
id="defs6302" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="95.859356"
inkscape:cy="48.086085"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1018"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata6305">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(328.57144,-46.647904)">
<g
transform="matrix(1.45557,0,0,1.455568,-938.13369,-1115.8476)"
style="display:inline"
id="g5082"
onmouseover="transform(rotate: 1">
<g
id="g5086"
inkscape:transform-center-y="-3.1404694">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:30.00000191;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 446.07653,808.00003 c -12.2628,5.39958 -20.8852,17.67866 -20.8852,31.87625 0,19.14186 15.6669,34.80874 34.8087,34.80874 19.1419,0 34.8087,-15.66688 34.8087,-34.80874 0,-14.19759 -8.6224,-26.47667 -20.8852,-31.87625 l 0,16.25675 c 4.2813,3.8125 6.9617,9.37496 6.9617,15.6195 0,11.61705 -9.2681,20.88523 -20.8852,20.88523 -11.617,0 -20.8852,-9.26818 -20.8852,-20.88523 0,-6.24454 2.6805,-11.807 6.9617,-15.6195 l 0,-16.25675 z"
id="path8408"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:12.45352745;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 460.00003,836.16335 0,-37.12921"
id="path8420"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 3H6V5H2V7H6V9H9V7H22V5H9V3ZM22 11H18V9H15V11H2V13H15V15H18V13H22V11ZM9 17H2V19H9V21H12V19H22V17H12V15H9V17Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.80231 3C9.33361 3 8.9278 3.32553 8.82612 3.78306L8.33343 6H15.6668L15.1742 3.78308C15.0725 3.32554 14.6667 3 14.198 3H12.6972L12.7275 5H11.2729L11.3032 3H9.80231Z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.27032 19.7831L7.22224 11H16.7778L18.7295 19.7831C18.8682 20.4076 18.393 21 17.7533 21H12.9698L12.9244 18H11.0759L11.0304 21H6.2465C5.60675 21 5.13152 20.4076 5.27032 19.7831ZM11.1517 13H12.8487L12.8941 16H11.1062L11.1517 13Z" fill="#fff"/>
<path d="M5 7H19V10H5V7Z" fill="#fff"/>
<path d="M4 8H2V17H5V13H4V8Z" fill="#fff"/>
<path d="M19 13H20V8H22V17H19V13Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 718 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 14H22V12H18V10H19C19.5304 10 20.0391 9.78929 20.4142 9.41421C20.7893 9.03914 21 8.53043 21 8V6H19V8H4.99997V6H2.99997V8C2.99997 8.53043 3.21068 9.03914 3.58576 9.41421C3.96083 9.78929 4.46954 10 4.99997 10H5.99997V12H1.99997V14H5.99997V15C6.00198 15.3353 6.03208 15.6698 6.08997 16H4.99997C4.46954 16 3.96083 16.2107 3.58576 16.5858C3.21068 16.9609 2.99997 17.4696 2.99997 18V20H4.99997V18H6.80997C6.98041 18.2945 7.19651 18.795 7.39766 19.2987C7.78188 20.2609 8.68389 20.9305 9.71949 20.9616L9.96998 20.9691C10.5338 20.986 11 20.5336 11 19.9695V10H13V19.9695C13 20.5336 13.4662 20.986 14.03 20.9691L14.2804 20.9616C15.316 20.9305 16.2181 20.2609 16.6023 19.2987C16.8034 18.795 17.0195 18.2945 17.19 18H19V20H21V18C21 17.4696 20.7893 16.9609 20.4142 16.5858C20.0391 16.2107 19.5304 16 19 16H17.91C17.9679 15.6698 17.998 15.3353 18 15V14ZM12 2C10.9391 2 9.92169 2.42143 9.17154 3.17157C8.4214 3.92172 7.99997 4.93913 7.99997 6L8.99997 8H15L16 6C16 4.93913 15.5785 3.92172 14.8284 3.17157C14.0783 2.42143 13.0608 2 12 2Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.31245 10.7501C2.43313 10.2674 2.72941 9.84702 3.14343 9.57104L3.48308 9.34464C3.81976 9.12021 4.08045 8.79894 4.23072 8.42326L5.65551 4.8613C5.87399 4.31509 6.31989 3.88487 6.89275 3.75102C9.75168 3.08302 14.2484 3.08297 17.1073 3.75101C17.6801 3.88486 18.126 4.31508 18.3445 4.86128L19.7693 8.42326C19.9195 8.79894 20.1802 9.12021 20.5169 9.34464L20.8566 9.57104C21.2706 9.84702 21.5669 10.2674 21.6875 10.7501L21.9403 11.7611C21.9799 11.9197 22 12.0826 22 12.2462V14.8345C22 14.9447 21.9909 15.0547 21.9728 15.1633L21.7785 16.3289C21.6908 16.855 21.4026 17.3045 21 17.6044V20C21 20.5523 20.5523 21 20 21H19C18.4477 21 18 20.5523 18 20V18.0001L16 18L15 17.5H9L8 18L6 18.0001V20C6 20.5523 5.55228 21 5 21H4C3.44772 21 3 20.5523 3 20V17.6044C2.59738 17.3045 2.30916 16.855 2.22147 16.3289L2.02721 15.1633C2.0091 15.0547 2 14.9447 2 14.8345V12.2462C2 12.0826 2.02005 11.9197 2.05972 11.7611L2.31245 10.7501ZM3.59968 12.2011C3.82556 11.5233 4.5352 11.1338 5.22825 11.3071L7.14935 11.7876C7.64929 11.9126 8 12.3618 8 12.8772C8 13.4975 7.49715 14.0003 6.87685 14.0003H4.89657C3.96352 14.0003 3.30466 13.0863 3.59968 12.2011ZM18.7717 11.3071C19.4648 11.1338 20.1744 11.5233 20.4003 12.2011C20.6953 13.0863 20.0365 14.0003 19.1034 14.0003H17.1232C16.5029 14.0003 16 13.4975 16 12.8772C16 12.3618 16.3507 11.9126 16.8506 11.7876L18.7717 11.3071ZM6.78488 5.57376C6.91689 5.22173 7.23523 4.97265 7.60927 4.93462C10.6012 4.63043 13.2722 4.62114 16.3898 4.93532C16.7642 4.97306 17.0832 5.22226 17.2154 5.57465L18.5 9.00029C13.4716 8.80583 10.6434 8.70521 5.5 9.0001L6.78488 5.57376Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.75 8C1.33579 8 1 8.33579 1 8.75V17.25C1 17.6642 1.33579 18 1.75 18C2.16421 18 2.5 17.6642 2.5 17.25V14H5V12H2.5V8.75C2.5 8.33579 2.16421 8 1.75 8Z" fill="#fff"/>
<path d="M21 9C20.4477 9 20 9.44772 20 10V11H17V15H20V16C20 16.5523 20.4477 17 21 17H22C22.5523 17 23 16.5523 23 16V10C23 9.44772 22.5523 9 22 9H21Z" fill="#fff"/>
<path d="M7 4C7 3.44772 7.44772 3 8 3H16C16.5523 3 17 3.44772 17 4C17 4.55228 16.5523 5 16 5H15V8H13V5H11V8H9V5H8C7.44772 5 7 4.55228 7 4Z" fill="#fff"/>
<path d="M6.74808 7.16795C6.91234 7.05844 7.10535 7 7.30278 7H15.5858C15.851 7 16.1054 7.10536 16.2929 7.29289L17.7071 8.70711C17.8946 8.89464 18 9.149 18 9.41421V16.8377C18 16.9452 17.9827 17.052 17.9487 17.1539L17.2279 19.3162C17.0918 19.7246 16.7097 20 16.2792 20H10.4142C10.149 20 9.89464 19.8946 9.70711 19.7071L7.29289 17.2929C7.10536 17.1054 6.851 17 6.58579 17H5C4.44772 17 4 16.5523 4 16V9.53518C4 9.20083 4.1671 8.8886 4.4453 8.70313L6.74808 7.16795Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
version="1.1"
id="svg4505"
sodipodi:docname="icon-exit.svg"
inkscape:version="0.92.1 r15371">
<metadata
id="metadata4511">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4509" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1724"
inkscape:window-height="901"
id="namedview4507"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg4505" />
<path
d="M 7.4362343,0.998047 17.238374,1.00062 c 2.24587,0.00203 4.07516,1.24607 4.07516,3.99938 v 14 c 0,2.2194 -1.7817,4 -4,4 H 7.3135343 c -0.8284,0 -1.5,-0.6716 -1.5,-1.5 0,-0.8284 0.6716,-1.5 1.5,-1.5 h 9.9999997 c 0.58431,0 1,-0.4146 1,-1 V 5 c 0,-0.58798 -0.47915,-0.99862 -1.07647,-0.99938 L 7.4355343,3.99805 c -0.8285,-2.1e-4 -1.4999,-0.67195 -1.4997,-1.50038 2e-4,-0.82842 0.672,-1.49983 1.5004,-1.499623 z"
id="path4501"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
d="m 8.3742343,6.93935 c -0.5858,-0.58578 -1.5356,-0.58578 -2.1214,0 l -4,4.00005 c -0.5857,0.5857 -0.5857,1.5355 0,2.1213 l 4,4 c 0.5858,0.5858 1.5356,0.5858 2.1214,0 0.5857,-0.5858 0.5857,-1.5356 0,-2.1213 L 6.9348343,13.5 h 6.8786997 c 0.82843,0 1.5,-0.6716 1.5,-1.5 0,-0.8284 -0.67157,-1.5 -1.5,-1.5 H 6.9348343 l 1.4394,-1.43932 c 0.5857,-0.58579 0.5857,-1.53554 0,-2.12133 z"
id="path4503"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.95848 4.25552C10.5428 4.56729 12.1757 5.2094 14.8571 4.53719C17.0558 3.98602 18.5495 3.96502 19.3382 4.02088C19.7305 4.04867 20 4.38412 20 4.77852V10.7421C20 11.3013 19.4673 11.7485 18.9098 11.7374C18.058 11.7205 16.7071 11.809 14.8571 12.2727C11.4286 13.1322 9.99999 12 9.99999 12V20.5271C10.7696 20.6622 11.6142 20.7368 12.5001 20.7368C16.09 20.7368 19.0002 19.5115 19.0002 18C19.0002 16.4884 16.09 15.2631 12.5001 15.2631C12.4364 15.2631 12.301 15.2623 12.1486 15.2616C11.7938 15.2601 11.5 14.9693 11.5 14.6145C11.5 14.273 11.773 13.998 12.1145 13.9989C12.2807 13.9994 12.4317 14 12.5 14C17.7467 14 22 15.7909 22 18C22 20.2091 17.7467 22 12.5 22C7.25329 22 3 20.2091 3 18C3 17.1561 3.62061 16.3733 4.68014 15.728C5.28285 15.3609 6 15.8476 6 16.5533V18C6.00003 18.7761 6.76735 19.4768 8 19.9749V5C8 4.52531 8.38375 4.10744 8.85714 4.10744H9.42857C9.61403 4.10744 9.79476 4.16816 9.95848 4.25552Z" fill="#FF6600"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.712 11.4874H10.2802V8.87268H11.7369C12.1312 8.87683 12.4425 9.00549 12.6708 9.25867C12.899 9.51184 13.0132 9.8501 13.0132 10.2734C13.0132 10.6594 12.9011 10.9583 12.677 11.1699C12.457 11.3816 12.1354 11.4874 11.712 11.4874Z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.27083 3.5C2.29283 3.5 1.5 4.29283 1.5 5.27083V7.18555H7.18604V8.87268H3.3075V10.9583H6.83118V12.6392H3.3075V16.25H1.5V18.7292C1.5 19.7072 2.29283 20.5 3.27083 20.5H20.9792C21.9572 20.5 22.75 19.7072 22.75 18.7292V15.3322C22.6393 15.4637 22.5107 15.5849 22.364 15.6959C21.7664 16.1483 20.9467 16.3745 19.9049 16.3745C19.1703 16.3745 18.5042 16.2438 17.9065 15.9823C17.313 15.7167 16.8647 15.3556 16.5618 14.899C16.2629 14.4384 16.1135 13.9092 16.1135 13.3115H18.3049C18.3049 13.7971 18.4294 14.1561 18.6785 14.3885C18.9316 14.6168 19.3405 14.731 19.9049 14.731C20.266 14.731 20.5503 14.6542 20.7578 14.5006C20.9695 14.3429 21.0753 14.1229 21.0753 13.8407C21.0753 13.5211 20.9612 13.2721 20.7329 13.0936C20.5088 12.9152 20.1124 12.7305 19.5438 12.5396C18.9752 12.3486 18.5104 12.1639 18.1493 11.9855C16.9747 11.4086 16.3875 10.6158 16.3875 9.6073C16.3875 9.1051 16.5327 8.66309 16.8232 8.28125C17.1179 7.89526 17.533 7.59644 18.0684 7.38477C18.6038 7.16895 19.2056 7.06104 19.8738 7.06104C20.5254 7.06104 21.1085 7.17725 21.6232 7.40967C22.0948 7.62097 22.4704 7.91461 22.75 8.29058V5.27083C22.75 4.29283 21.9572 3.5 20.9792 3.5H3.27083ZM10.2802 16.25V13.1746H11.6747C12.7787 13.1746 13.6461 12.911 14.277 12.3839C14.912 11.8527 15.2295 11.145 15.2295 10.261C15.2295 9.66333 15.0822 9.13 14.7875 8.66101C14.4969 8.18787 14.084 7.82471 13.5486 7.57153C13.0173 7.31421 12.4052 7.18555 11.712 7.18555H8.09497V16.25H10.2802Z" fill="#fff"/>
<path d="M22.75 9.875H21.0815C21.0815 9.50562 20.9674 9.21924 20.7391 9.01587C20.515 8.8125 20.21 8.71082 19.824 8.71082C19.4338 8.71082 19.1246 8.79797 18.8964 8.97229C18.6722 9.14246 18.5602 9.36035 18.5602 9.62598C18.5602 9.8584 18.6847 10.0701 18.9337 10.261C19.1827 10.4478 19.6206 10.6428 20.2473 10.8462C20.874 11.0454 21.3887 11.2612 21.7913 11.4937C22.1934 11.7254 22.513 11.9931 22.75 12.2969V9.875Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 4C3 3.44772 3.44772 3 4 3H14C14.5523 3 15 3.44772 15 4L15 20C15 20.5523 14.5523 21 14 21H4C3.44771 21 3 20.5523 3 20V4ZM8.81839 8.39373C8.88987 8.23876 9.11013 8.23876 9.18161 8.39373L10.0817 10.345C10.1108 10.4082 10.1706 10.4517 10.2397 10.4599L12.3736 10.7129C12.5431 10.733 12.6112 10.9425 12.4859 11.0583L10.9082 12.5173C10.8572 12.5645 10.8343 12.6349 10.8478 12.7031L11.2666 14.8108C11.2999 14.9782 11.1217 15.1076 10.9728 15.0243L9.09769 13.9747C9.03699 13.9407 8.96301 13.9407 8.90231 13.9747L7.02722 15.0243C6.87829 15.1076 6.7001 14.9782 6.73336 14.8108L7.15215 12.7031C7.16571 12.6349 7.14285 12.5645 7.09178 12.5173L5.51412 11.0583C5.38881 10.9425 5.45688 10.733 5.62636 10.7129L7.76028 10.4599C7.82935 10.4517 7.88921 10.4082 7.91834 10.345L8.81839 8.39373ZM22 4C22.5523 4 23 4.44772 23 5V10C23 10.5523 22.5523 11 22 11H18C17.4477 11 17 10.5523 17 10V5C17 4.44772 17.4477 4 18 4L22 4ZM22 13C22.5523 13 23 13.4477 23 14V19C23 19.5523 22.5523 20 22 20H18C17.4477 20 17 19.5523 17 19V14C17 13.4477 17.4477 13 18 13H22Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 2H19C20.1 2 21 2.9 21 4V18.2026C21 19.2787 20.3114 20.2295 19.2906 20.5698L12.1581 22.9473C12.0555 22.9815 11.9445 22.9815 11.8419 22.9473L4.70943 20.5698C3.68858 20.2295 3 19.2797 3 18.2036V4C3 3.46957 3.21071 2.96086 3.58579 2.58579C3.96086 2.21071 4.46957 2 5 2ZM13.0179 14.3729H10.9286V13.8702C10.9286 11.9846 11.869 11.1976 12.6936 10.5074C13.3374 9.96847 13.9107 9.48865 13.9107 8.59116C13.9107 7.67541 13.2857 6.99309 12.1607 6.99309C10.8393 6.99309 10.0893 7.83702 10.0893 9.27348H8C8 6.56215 9.71429 5 12.1607 5C14.6607 5 16 6.56216 16 8.59116C16 10.144 15.1807 10.8534 14.401 11.5285C13.6931 12.1414 13.0179 12.7261 13.0179 13.8881V14.3729ZM13.4107 16.5994C13.4107 17.3895 12.7857 18 11.9821 18C11.1607 18 10.5536 17.3895 10.5536 16.5994C10.5536 15.8273 11.1607 15.1989 11.9821 15.1989C12.7857 15.1989 13.4107 15.8273 13.4107 16.5994Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1015 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 6C1 4.89543 1.89543 4 3 4H21C22.1046 4 23 4.89543 23 6V19C23 20.1046 22.1046 21 21 21H3C1.89543 21 1 20.1046 1 19V6ZM2.5 6H5V8H2.5V6ZM16 6H8V9H16V6ZM19 6H21.5V8H19V6ZM18.9151 13.5737C19.8185 13.4824 20.7267 13.6907 21.5 14.1665L20.4969 15.7967C20.0813 15.541 19.5932 15.4291 19.1077 15.4782C18.6223 15.5272 18.1664 15.7346 17.8105 16.0684C17.4545 16.4021 17.2182 16.8436 17.1379 17.3249C17.0577 17.8062 17.138 18.3005 17.3664 18.7317L16.5207 19.1797L15.6749 19.6278C15.2499 18.8255 15.1005 17.9057 15.2499 17.0101C15.3992 16.1145 15.8389 15.2929 16.5013 14.672C17.1636 14.051 18.0118 13.6651 18.9151 13.5737ZM2.5 14.1665C3.27326 13.6907 4.18154 13.4824 5.08486 13.5737C5.98818 13.6651 6.83638 14.051 7.49872 14.672C8.16107 15.2929 8.6008 16.1145 8.75013 17.0101C8.89945 17.9057 8.75009 18.8255 8.32507 19.6278L7.32016 19.0954C7.62838 18.5136 7.73669 17.8466 7.6284 17.1971C7.52011 16.5477 7.20123 15.9519 6.72092 15.5016C6.2406 15.0513 5.62551 14.7714 4.97045 14.7052C4.31538 14.6389 3.65672 14.79 3.09597 15.135L2.5 14.1665ZM4.83639 16.0436C4.47506 16.007 4.11174 16.0903 3.80244 16.2807L4.66986 17.6903L6.13247 18.4652C6.30248 18.1442 6.36222 17.7763 6.30249 17.4181C6.24276 17.0599 6.06687 16.7312 5.80193 16.4828C5.53699 16.2345 5.19771 16.0801 4.83639 16.0436Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2806 21.5965C5.98328 13.3684 5 12.5239 5 9.5C5 5.35785 8.13399 2 12 2C15.866 2 19 5.35785 19 9.5C19 12.5239 18.0167 13.3684 12.7194 21.5965C12.3718 22.1345 11.6282 22.1345 11.2806 21.5965ZM12 12.625C13.6108 12.625 14.9167 11.2259 14.9167 9.5C14.9167 7.7741 13.6108 6.375 12 6.375C10.3892 6.375 9.08333 7.7741 9.08333 9.5C9.08333 11.2259 10.3892 12.625 12 12.625Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 494 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM8 8H11V16H8V8ZM16 8H13V16H16V8Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 314 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 4.99954H17L16.0857 4.08557C15.7107 3.71063 15.2021 3.5 14.6718 3.5H9.32825C8.79792 3.5 8.28931 3.71063 7.91425 4.08557L7 4.99954H4C2.8722 4.99954 2 5.9445 2 6.99954V16.9996C2 18.0546 2.8722 19.0008 4 19.0008L20 19.0007C21.1278 19.0007 22 18.0546 22 16.9996V6.99954C22 5.9445 21.1278 4.99954 20 4.99954ZM16 12.0003C16 14.2095 14.2091 16.0003 12 16.0003C9.79086 16.0003 8 14.2095 8 12.0003C8 9.7912 9.79086 8.00034 12 8.00034C14.2091 8.00034 16 9.7912 16 12.0003ZM17 9.00034C17.5523 9.00034 18 8.55262 18 8.00034C18 7.44805 17.5523 7.00034 17 7.00034C16.4477 7.00034 16 7.44805 16 8.00034C16 8.55262 16.4477 9.00034 17 9.00034Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 797 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 1C9.34315 1 8 2.34315 8 4V5H5C3.89543 5 3 5.89543 3 7V10.5001H4.5C5.88071 10.5001 7 11.6194 7 13.0001C7 14.3808 5.88071 15.5001 4.5 15.5001H3V19C3 20.1046 3.89543 21 5 21H8.5V19.5001C8.5 18.1194 9.61929 17.0001 11 17.0001C12.3807 17.0001 13.5 18.1194 13.5 19.5001V21H17C18.1046 21 19 20.1046 19 19V16H20C21.6569 16 23 14.6569 23 13C23 11.3431 21.6569 10 20 10H19V7C19 5.89543 18.1046 5 17 5H14V4C14 2.34315 12.6569 1 11 1Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 554 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.00018 4.5C3.96257 4.5 1.50011 6.96251 1.50018 10.0001L1.50021 11.0001C1.50028 14.0376 3.96269 16.5 7.00021 16.5H11V18.4641C11 19.2339 11.8333 19.715 12.5 19.3301L18.5 15.866C19.1666 15.4811 19.1666 14.5189 18.5 14.134L12.5 10.6699C11.8333 10.285 11 10.7661 11 11.5359V13.5H7.00021C5.61952 13.5 4.50024 12.3807 4.50021 11.0001L4.50018 10.0001C4.50015 8.61932 5.61945 7.5 7.00018 7.5H15.7887C17.6731 7.5 18.797 9.60009 17.7518 11.168L20.2479 12.8321C22.6223 9.27052 20.0692 4.5 15.7887 4.5H7.00018Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 627 B

View File

@ -0,0 +1,8 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 13C8.46419 13 8.90991 13.0791 9.32442 13.2245C10.0406 11.3396 11.8639 10 14 10C16.7614 10 19 12.2386 19 15C20.6569 15 22 16.3431 22 18C22 19.6569 20.6569 21 19 21H8C5.79086 21 4 19.2091 4 17C4 14.7909 5.79086 13 8 13Z" fill="#fff"/>
<path d="M5.53076 5.11655C5.89861 5.4844 5.83232 6.09662 5.46447 6.46447C5.09662 6.83232 4.4844 6.89861 4.11654 6.53076L3.34315 5.75736C2.95262 5.36683 2.95262 4.73367 3.34315 4.34315C3.73367 3.95262 4.36683 3.95262 4.75736 4.34315L5.53076 5.11655Z" fill="#fff"/>
<path d="M8 4.09335C8 4.61357 8.47977 5 9 5C9.52023 5 10 4.61357 10 4.09335V3C10 2.44772 9.55228 2 9 2C8.44772 2 8 2.44771 8 3V4.09335Z" fill="#fff"/>
<path d="M12.4692 5.11655C12.1014 5.4844 12.1677 6.09662 12.5355 6.46447C12.9034 6.83232 13.5156 6.89861 13.8835 6.53076L14.6569 5.75736C15.0474 5.36684 15.0474 4.73367 14.6569 4.34315C14.2663 3.95262 13.6332 3.95262 13.2426 4.34315L12.4692 5.11655Z" fill="#fff"/>
<path d="M3.09335 11C3.61357 11 4 10.5202 4 10C4 9.47977 3.61357 9 3.09335 9H2C1.44772 9 1 9.44772 1 10C1 10.5523 1.44771 11 2 11H3.09335Z" fill="#fff"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2642 8.73434C10.6919 9.16899 9.35972 10.1795 8.50746 11.5232C8.34016 11.5078 8.17088 11.5 8 11.5C7.30782 11.5 6.64551 11.6279 6.03539 11.8613C5.6962 11.3221 5.5 10.684 5.5 10C5.5 8.067 7.067 6.5 9 6.5C10.4867 6.5 11.7568 7.42691 12.2642 8.73434Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

97
ui/modules/menu/menu.css Normal file
View File

@ -0,0 +1,97 @@
/* .vertical-divider {
border-right: 2px solid var(--bng-orange);
margin: 8px 4px 8px 4px;
} */
.menuLimiterContainer {
height:100%;
}
.menuLimiter {
height:100%;
/* TODO: find sensible limits for this */
max-width:3440px; /* 1080p = 1920x1080 */
margin: 0 auto;
display: flex;
flex-direction: column;
}
/* Dashboard Menu */
#dashmenu {
flex: none;
display: flex;
flex-flow: row;
flex-wrap: nowrap;
justify-content: stretch;
align-items: stretch;
background-color:rgba(0, 0, 0, 0.6);
position: relative;
z-index: var(--zorder_menu_dashmenu);
}
/* limiters to fit all labels (both must be the same size to center the menu items) */
#dashmenu::before, #dashmenu::after {
flex: 1 0 150px;
width: 150px;
content: "";
display: inline-block;
}
.dashBrdButtonDiv::after {
content: "";
flex: 0 0 2px;
width: 2px;
height: 100%;
margin: 8px -13px 8px 12px;
border-radius: 2px;
background-color: #f60;
z-index: 2;
}
/* fix for long strings */
#dashmenu * {
box-sizing: border-box;
}
#dashmenu > * {
display: flex;
flex-wrap: nowrap;
}
#dashmenu > *:not(.dashBrdButtonActive) {
overflow: hidden;
}
#dashmenu > *:not(.dashBrdButtonActive) > .dashBrdText {
flex: 0 1 auto;
overflow: hidden;
text-overflow: ellipsis;
}
/* do not change the order of next two rules */
#dashmenu > * > *:last-child {
flex: 0 0 auto;
}
#dashmenu > * > *:first-child {
flex: 0 1 auto;
}
#dashmenu > *:not(.dashBrdButtonStart):not(.dashBrdButtonEnd) {
flex: 0 1 auto;
position: relative;
height: 100%;
}
#dashmenu .dashBrdButton {
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
/* width: 100%; */
}
#dashmenu .dashBrdSvgIcon {
flex: 0 0 auto;
}
@media (min-width: 1024px) and (max-width: 1600px) {
#dashmenu > *:not(.dashBrdButtonActive):not(.dashBrdButtonStart):not(.dashBrdButtonEnd) {
min-width: 5%;
max-width: 10%;
}
}

View File

@ -0,0 +1,3 @@
<link rel="stylesheet" type="text/css" href="/ui/modules/menu/menu.css" />
<!-- the content below the menu bar -->
<div class="contentNavMainmenu" layout="row" ui-view></div>

330
ui/modules/menu/menu.js Normal file
View File

@ -0,0 +1,330 @@
'use strict'
angular.module('beamng.stuff')
.controller('MenuController', ['$rootScope', '$scope', 'Utils', '$state', '$timeout', 'mdx', function ($rootScope, $scope, Utils, $state, $timeout, mdx) {
let vm = this
let availableMenuEntries = [
{
translateid: 'ui.inputActions.menu.menu_item_back.title',
icon: 'arrow_back',
class: "dashBrdButtonStart dashBrdButtonTopLeft",
soundClass: "bng_back_hover_generic",
targetState: '',
action: () => {
$rootScope.$broadcast('MenuToggle')
},
onlyIngame: false,
gamepadNavigateable: false,
navigationDisabled: true,
},
{
translateid: 'ui.dashboard.menu',
iconSVG: '/ui/modules/menu/icon-gamemodes.svg',
targetState: 'menu.mainmenu',
onlyIngame: false,
},
{
translateid: 'ui.playmodes.career',
iconSVG: '/ui/modules/menu/icon-gamemodes.svg',
targetState: 'menu.careerPause',
onlyIngame: true,
isVisible: () => $scope.inCareer,
},
{
translateid: 'ui.mainmenu.garage',
iconSVG: '/ui/modules/mainmenu/drive/icons/garage.svg',
targetState: '',
action: () => {
bngApi.engineLua("career_modules_playerDriving.onResetGameplay()");
},
onlyIngame: true,
isVisible: () => $scope.inCareer,
blackListStates: ['scenario','mission','garage'],
},
{
translateid: 'ui.dashboard.bigmap',
//iconSVG: '/ui/modules/menu/icon-map.svg',
icon: 'map',
targetState: 'menu.bigmap',
blackListStates: ['scenario','mission','garage'],
onlyIngame: true,
isVisible: () => !$scope.inCareer || ($scope.inCareer && $state.gamestate.name!=='garage')
},
{
translateid: 'ui.dashboard.gameContext',
iconSVG: '/ui/modules/menu/icon-flag.svg',
targetState: 'menu.careermission',
isVisible: () => vm.missionEnabled,
blackListStates: ['scenario','garage'],
onlyIngame: true,
},
{
translateid: 'ui.dashboard.mods',
iconSVG: '/ui/modules/menu/icon-puzzle.svg',
targetState: 'menu.mods.local',
blackListStates: ['scenario','mission','garage'],
substate: 'menu.mods',
onlyIngame: true,
},
{
translateid: 'ui.dashboard.vehicles',
iconSVG: '/ui/modules/menu/icon-car.svg',
targetState: 'menu.vehicles',
blackListStates: ['scenario','mission','garage','career'],
substate: 'menu.vehicles',
onlyIngame: true,
},
{
translateid: 'ui.dashboard.vehicleconfig',
iconSVG: '/ui/modules/menu/icon-engine.svg',
targetState: 'menu.vehicleconfig.parts',
blackListStates: ['scenario','mission','garage','career'],
substate: 'menu.vehicleconfig',
onlyIngame: true,
},
{
translateid: 'ui.dashboard.environment',
iconSVG: '/ui/modules/menu/icon-weather.svg',
targetState: 'menu.environment',
blackListStates: ['scenario','mission','garage'],
onlyIngame: true,
},
{
translateid: 'ui.dashboard.photomode',
iconSVG: '/ui/modules/menu/icon-photo.svg',
targetState: 'menu.photomode',
onlyIngame: true,
blackListStates: ['garage'],
},
{
translateid: 'ui.dashboard.appedit',
iconSVG: '/ui/modules/menu/icon-hud.svg',
targetState: 'menu.appedit',
onlyIngame: true,
blackListStates: ['scenario'],
},
{
translateid: 'ui.dashboard.options',
iconSVG: '/ui/modules/menu/icon-adjust.svg',
targetState: 'menu.options.graphics',
substate: 'menu.options',
onlyIngame: true,
},
]
for(let m of availableMenuEntries) {
if(!m.action && m.targetState) {
// if no action is defined, toggle the states
m.action = () => {
if ($state.current.name !== m.targetState) {
$state.go(m.targetState);
}
else
$scope.$emit("MenuToggle");
}
}
if(!m.action) {
console.error('state is missing action or targetState')
}
}
// Mission Menu and Career Stuff
vm.missionEnabled = false
$scope.inCareer = false;
bngApi.engineLua(`{
gameContext = core_gameContext.getGameContext(),
isCareerActive = career_career.isCareerActive()
}`, data => {
$scope.$evalAsync(() => {
vm.missionEnabled = data.gameContext && data.gameContext.context && data.gameContext.context !== "empty";
$scope.inCareer = !!data.isCareerActive;
if ($state.current && $state.current.name === "menu") {
if (vm.missionEnabled)
$state.go("menu.careermission");
else if ($scope.inCareer)
$state.go("menu.careerPause");
}
updateMenu();
})
});
$scope.$on("onMissionAvailabilityChanged", (event, res) => {
if(res && res.missionCount !== undefined) {
vm.missionEnabled = res.missionCount > 0
updateMenu()
if($state.current && $state.current.name === "menu.careermission" && !vm.missionEnabled) {
$state.go("menu");
}
}
})
vm.pause = function() {
bngApi.engineLua(`bullettime.pause(true)`)
}
$rootScope.$broadcast("TopMenuButtons", (button, index=-1) => {
if (typeof index !== "number" && index < availableMenuEntries.length)
index = -1;
if (index > 0)
availableMenuEntries.splice(index, 0, button);
else
availableMenuEntries.push(button);
updateMenu();
});
function updateMenu() {
let entries = [];
const app = $scope.$parent && $scope.$parent.app ? $scope.$parent.app : {};
if ($state.current.name !== 'menu.mainmenu' || !app.mainmenu) {
// TODO: revert to normal gamestate when it will be implemented for career (but don't forget about career's garage)
if ($scope.inCareer && ["freeroam", "garage"].includes(app.gameState))
$scope.gameState = "career";
else
$scope.gameState = app.gameState;
for(let entry of availableMenuEntries) {
// visibility
if(entry.blackListStates && entry.blackListStates.includes($scope.gameState)) {
continue;
}
if(entry.isVisible && !entry.isVisible()) {
continue;
}
if($scope.$parent && app.mainmenu && entry.onlyIngame) {
//console.log('ignored menu entry in main menu: ', entry)
continue
}
if (entry.navigationDisabled === undefined) {
entry.navigationDisabled = false
}
// determine if the thing is 'active' as in 'used / switched on'
entry.active = false
if (entry.isActive) {
entry.active = entry.isActive()
} else {
let isInSubState = false
if(entry.substate) {
isInSubState = $state.current.name.startsWith(entry.substate)
}
entry.active = ($state.includes(entry.targetState) | isInSubState) && entry.targetState != '.' && entry.targetState != ''
}
entries.push(entry)
}
//console.log('updateMenu = ', entries)
}
if(entries.length > 0) {
entries[entries.length-1].isLastItem = true
}
$scope.$applyAsync(() => {
for (let i = 0; i < entries.length; i++)
entries[i].id = `top-menu-${i}`;
vm.entries = entries;
})
}
$scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
updateMenu()
})
updateMenu()
// Angular material theme palette tests
let palettes = ['primary', 'accent', 'warn', 'background']
let types = ['default', 'hue-1', 'hue-2', 'hue-3']
let colors = {}
let theme = mdx.mdxThemeColors.theme('default')
for(let pIdx in palettes) {
let p = palettes[pIdx]
for(let tIdx in types) {
let t = types[tIdx]
let paletteName = 'custom' + p.substr(0, 1).toUpperCase() + p.substr(1)
let ref = theme.colors[p]['hues'][t]
if(paletteName in mdx.mdxThemeColors._PALETTES) {
let col = 'rgb(' + (mdx.mdxThemeColors._PALETTES[paletteName][ref].value.toString()) + ')'
let colContrast = 'rgb(' + (mdx.mdxThemeColors._PALETTES[paletteName][ref].contrast.toString()) + ')'
colors[paletteName + "/" + t] = [ref, col, colContrast]
}
}
}
//vm.colorDebug = colors
// switches to the next or previous visible menu entry (increment +1 or -1 respectively)
vm.selectVisibleMenuEntry = function(increment) {
if ($scope.$parent && $scope.$parent.app && $scope.$parent.app.mainmenu)
return; // tab navigation shouldn't work while in the Main Menu
// first, find the current active element
let currMenuEntryIndex = 0
for (let i in vm.entries) {
if (!vm.entries[i].active) continue
currMenuEntryIndex = Number(i)
break
}
// then find the next suitable one
let newIndex = currMenuEntryIndex
for(let i = 0; i < 5; i++) {
newIndex = newIndex + increment
if (newIndex >= vm.entries.length) newIndex = 0
if (newIndex < 0) newIndex = vm.entries.length - 1
if (vm.entries[newIndex].gamepadNavigateable === false || vm.entries[newIndex].targetState === undefined)
continue;
if (!vm.entries[newIndex].targetState && !vm.entries[newIndex].action)
continue;
// found a suitable element ...
break
}
// navigate left (increment -1) or right (increment +1), wrapping around when reaching the menu borders
//console.log('newIndex = ', newIndex, 'vm.entries = ', vm.entries)
if (vm.entries[newIndex].targetState) {
$state.go(vm.entries[newIndex].targetState)
} else if (vm.entries[newIndex].action && vm.entries[newIndex].id) {
try {
document.getElementById(vm.entries[newIndex].id).focus();
for (let i = 0; i < vm.entries.length; i++)
vm.entries[i].active = i === newIndex;
vm.entries[newIndex].activeSilent = true;
} catch (err) { }
}
}
$scope.$on('$tabLeft', () => { vm.selectVisibleMenuEntry(-1) })
$scope.$on('$tabRight', () => { vm.selectVisibleMenuEntry( 1) })
}])
.directive('dashMenu', ['Utils', '$rootScope', function (Utils, $rootScope, ) {
return {
restrict: 'E',
// controller: 'MenuController',
// controllerAs: 'menuCtrl',
replace: true,
template: `
<div id="dashmenu" class="dashMenuHeight" bng-blur="true">
<div ng-repeat="entry in menuCtrl.entries"
class="dashBrdButton {{ entry.class }}"
ng-class="{'dashBrdButtonActive': entry.active && !entry.activeSilent, 'dashBrdButtonDiv': !entry.isLastItem && entry.targetState && app.sections[app.gameState].indexOf(entry.targetState) > -1 }"
ng-click="entry.action($event); $event.preventDefault();"
bng-sound-class="{{ entry.soundClass || 'bng_click_hover_generic' }}"
bng-no-nav="{{entry.navigationDisabled}}"
id="{{entry.id}}"
>
<div class="dashBrdSvgIcon" ng-if="entry.translateidIcon" bng-translate="{{entry.translateidIcon}}"></div>
<img class="dashBrdSvgIcon" ng-if="entry.iconSVG" ng-src="{{entry.iconSVG}}" />
<md-icon class="dashBrdSvgIcon material-icons" ng-if="entry.icon">{{entry.icon}}</md-icon>
<span class="dashBrdText" bng-translate="{{entry.translateid}}"></span>
<md-tooltip md-direction="bottom">{{ entry.translateid | translate}}</md-tooltip>
</div>
<!-- pause button (shown only while not paused), not to be confused with the pause indicator (show only while paused). see index.html -->
<div ng-if="!app.showPauseIcon && !app.mainmenu && app.gameState !== 'garage'" class="dashMenuHeight dashBrdButton dashBrdButtonEnd dashBrdButtonPause" ng-click="menuCtrl.pause()" bng-sound-class="bng_hover_generic">
<span style="padding:0; margin:0" bng-translate="ui.inputActions.general.pause.binding" class="bng-binding dashBrdSvgIcon"></span>
<span class="dashBrdText">{{ 'ui.inputActions.general.pause.title' | translate }}</span>
<md-tooltip md-direction="bottom">{{ 'ui.inputActions.general.pause.title' | translate}}</md-tooltip>
</div>
</div>
`,
}
}])