添加窗口显示。宫格行啊是
This commit is contained in:
parent
ff030f8b6b
commit
be4f57530e
|
@ -6,7 +6,7 @@
|
|||
// Configuration for your app
|
||||
// https://v2.quasar.dev/quasar-cli/quasar-conf-js
|
||||
|
||||
const { configure } = require('quasar/wrappers');
|
||||
const { configure } = require("quasar/wrappers");
|
||||
|
||||
module.exports = configure(function (ctx) {
|
||||
return {
|
||||
|
@ -19,15 +19,10 @@ module.exports = configure(function (ctx) {
|
|||
// app boot file (/src/boot)
|
||||
// --> boot files are part of "main.js"
|
||||
// https://v2.quasar.dev/quasar-cli/boot-files
|
||||
boot: [
|
||||
'i18n',
|
||||
'axios',
|
||||
],
|
||||
boot: ["i18n", "axios"],
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
|
||||
css: [
|
||||
'app.scss'
|
||||
],
|
||||
css: ["app.scss"],
|
||||
|
||||
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||
extras: [
|
||||
|
@ -39,13 +34,13 @@ module.exports = configure(function (ctx) {
|
|||
// 'line-awesome',
|
||||
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
|
||||
|
||||
'roboto-font', // optional, you are not bound to it
|
||||
'material-icons', // optional, you are not bound to it
|
||||
"roboto-font", // optional, you are not bound to it
|
||||
"material-icons", // optional, you are not bound to it
|
||||
],
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
|
||||
build: {
|
||||
vueRouterMode: 'hash', // available values: 'hash', 'history'
|
||||
vueRouterMode: "hash", // available values: 'hash', 'history'
|
||||
|
||||
// transpile: false,
|
||||
|
||||
|
@ -65,7 +60,7 @@ module.exports = configure(function (ctx) {
|
|||
|
||||
// https://v2.quasar.dev/quasar-cli/handling-webpack
|
||||
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
|
||||
chainWebpack (/* chain */) {
|
||||
chainWebpack(/* chain */) {
|
||||
//
|
||||
},
|
||||
},
|
||||
|
@ -74,7 +69,7 @@ module.exports = configure(function (ctx) {
|
|||
devServer: {
|
||||
https: false,
|
||||
port: 8080,
|
||||
open: true // opens browser window automatically
|
||||
open: true, // opens browser window automatically
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
|
||||
|
@ -92,7 +87,7 @@ module.exports = configure(function (ctx) {
|
|||
// directives: [],
|
||||
|
||||
// Quasar plugins
|
||||
plugins: []
|
||||
plugins: ["Notify", "Dialog", "Loading", "AppFullscreen"],
|
||||
},
|
||||
|
||||
// animations: 'all', // --- includes all animations
|
||||
|
@ -112,24 +107,24 @@ module.exports = configure(function (ctx) {
|
|||
maxAge: 1000 * 60 * 60 * 24 * 30,
|
||||
// Tell browser when a file from the server should expire from cache (in ms)
|
||||
|
||||
chainWebpackWebserver (/* chain */) {
|
||||
chainWebpackWebserver(/* chain */) {
|
||||
//
|
||||
},
|
||||
|
||||
middlewares: [
|
||||
ctx.prod ? 'compression' : '',
|
||||
'render' // keep this as last one
|
||||
]
|
||||
ctx.prod ? "compression" : "",
|
||||
"render", // keep this as last one
|
||||
],
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
|
||||
pwa: {
|
||||
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
|
||||
workboxPluginMode: "GenerateSW", // 'GenerateSW' or 'InjectManifest'
|
||||
workboxOptions: {}, // only for GenerateSW
|
||||
|
||||
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
|
||||
// if using workbox in InjectManifest mode
|
||||
chainWebpackCustomSW (/* chain */) {
|
||||
chainWebpackCustomSW(/* chain */) {
|
||||
//
|
||||
},
|
||||
|
||||
|
@ -137,38 +132,38 @@ module.exports = configure(function (ctx) {
|
|||
name: `Quasar App`,
|
||||
short_name: `Quasar App`,
|
||||
description: `A Quasar Framework app`,
|
||||
display: 'standalone',
|
||||
orientation: 'portrait',
|
||||
background_color: '#ffffff',
|
||||
theme_color: '#027be3',
|
||||
display: "standalone",
|
||||
orientation: "portrait",
|
||||
background_color: "#ffffff",
|
||||
theme_color: "#027be3",
|
||||
icons: [
|
||||
{
|
||||
src: 'icons/icon-128x128.png',
|
||||
sizes: '128x128',
|
||||
type: 'image/png'
|
||||
src: "icons/icon-128x128.png",
|
||||
sizes: "128x128",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: 'icons/icon-192x192.png',
|
||||
sizes: '192x192',
|
||||
type: 'image/png'
|
||||
src: "icons/icon-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: 'icons/icon-256x256.png',
|
||||
sizes: '256x256',
|
||||
type: 'image/png'
|
||||
src: "icons/icon-256x256.png",
|
||||
sizes: "256x256",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: 'icons/icon-384x384.png',
|
||||
sizes: '384x384',
|
||||
type: 'image/png'
|
||||
src: "icons/icon-384x384.png",
|
||||
sizes: "384x384",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: 'icons/icon-512x512.png',
|
||||
sizes: '512x512',
|
||||
type: 'image/png'
|
||||
}
|
||||
]
|
||||
}
|
||||
src: "icons/icon-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
|
||||
|
@ -178,22 +173,20 @@ module.exports = configure(function (ctx) {
|
|||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
|
||||
capacitor: {
|
||||
hideSplashscreen: true
|
||||
hideSplashscreen: true,
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
|
||||
electron: {
|
||||
bundler: 'packager', // 'packager' or 'builder'
|
||||
bundler: "packager", // 'packager' or 'builder'
|
||||
|
||||
packager: {
|
||||
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
|
||||
|
||||
// OS X / Mac App Store
|
||||
// appBundleId: '',
|
||||
// appCategoryType: '',
|
||||
// osxSign: '',
|
||||
// protocol: 'myapp://path',
|
||||
|
||||
// Windows only
|
||||
// win32metadata: { ... }
|
||||
},
|
||||
|
@ -201,20 +194,20 @@ module.exports = configure(function (ctx) {
|
|||
builder: {
|
||||
// https://www.electron.build/configuration/configuration
|
||||
|
||||
appId: 'media_player_web'
|
||||
appId: "media_player_web",
|
||||
},
|
||||
|
||||
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
|
||||
chainWebpack (/* chain */) {
|
||||
chainWebpack(/* chain */) {
|
||||
// do something with the Electron main process Webpack cfg
|
||||
// extendWebpackMain also available besides this chainWebpackMain
|
||||
},
|
||||
|
||||
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
|
||||
chainWebpackPreload (/* chain */) {
|
||||
chainWebpackPreload(/* chain */) {
|
||||
// do something with the Electron main process Webpack cfg
|
||||
// extendWebpackPreload also available besides this chainWebpackPreload
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
12
src/App.vue
12
src/App.vue
|
@ -3,15 +3,19 @@
|
|||
<router-view />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import EventBus from "src/common/EventBus";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
name: "App",
|
||||
|
||||
setup() {
|
||||
const $t = useI18n();
|
||||
document.title = $t.t('title');
|
||||
document.title = $t.t("title");
|
||||
|
||||
window.onresize = (evt: any) =>
|
||||
EventBus.getInstance().emit("windowResize", evt);
|
||||
return {};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -144,11 +144,10 @@ export default class ClientConnection {
|
|||
}
|
||||
}
|
||||
|
||||
public async doRpc(reuqest: any | Protocol.PacketEntity) {
|
||||
public async doRpc<_RequestType extends Protocol.PacketEntity, _ResponseType>(
|
||||
RequestType: new () => _RequestType
|
||||
): Promise<_ResponseType | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!reuqest) {
|
||||
reject();
|
||||
}
|
||||
const rpc_id = ++this._rpc_id_counter;
|
||||
if (this.rpc_map.has(rpc_id)) {
|
||||
const f = this.rpc_map.get(rpc_id);
|
||||
|
@ -157,8 +156,9 @@ export default class ClientConnection {
|
|||
this.rpc_map.delete(rpc_id);
|
||||
}
|
||||
}
|
||||
reuqest.rpc_id = rpc_id;
|
||||
this.ws?.send(JSON.stringify(reuqest));
|
||||
let request: _RequestType = new RequestType();
|
||||
request.rpc_id = rpc_id;
|
||||
this.ws?.send(JSON.stringify(request));
|
||||
this.rpc_map.set(
|
||||
rpc_id,
|
||||
(is_fail: boolean, packet: Protocol.Commands, data: string) => {
|
||||
|
@ -166,9 +166,7 @@ export default class ClientConnection {
|
|||
reject();
|
||||
} else {
|
||||
try {
|
||||
const response = JSON.parse(
|
||||
data
|
||||
) as Protocol.GetApplicationConfigResponseEntity;
|
||||
const response = JSON.parse(data) as _ResponseType;
|
||||
if (response) {
|
||||
resolve(response);
|
||||
} else {
|
||||
|
@ -186,49 +184,33 @@ export default class ClientConnection {
|
|||
}
|
||||
|
||||
public async getSignalSources() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rpc_id = ++this._rpc_id_counter;
|
||||
if (this.rpc_map.has(rpc_id)) {
|
||||
const f = this.rpc_map.get(rpc_id);
|
||||
if (f && typeof f == "function") {
|
||||
f(true, new Protocol.Commands(), "");
|
||||
this.rpc_map.delete(rpc_id);
|
||||
}
|
||||
}
|
||||
this.ws?.send(
|
||||
JSON.stringify(new Protocol.GetSignalSourcesRequest(rpc_id))
|
||||
);
|
||||
this.rpc_map.set(
|
||||
rpc_id,
|
||||
(is_fail: boolean, packet: Protocol.Commands, data: string) => {
|
||||
if (is_fail) {
|
||||
reject();
|
||||
} else {
|
||||
try {
|
||||
const response = JSON.parse(
|
||||
data
|
||||
) as Protocol.GetSignalSourcesResponse;
|
||||
if (response) {
|
||||
resolve(response);
|
||||
} else {
|
||||
reject();
|
||||
console.log("reject");
|
||||
return await this.doRpc<
|
||||
Protocol.GetSignalSourcesRequest,
|
||||
Protocol.GetSignalSourcesResponse
|
||||
>(Protocol.GetSignalSourcesRequest);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} catch {
|
||||
reject();
|
||||
console.log("reject");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async getApplicationSettins() {
|
||||
try {
|
||||
return (await this.doRpc(
|
||||
new Protocol.GetApplicationConfigRequestEntity()
|
||||
)) as Protocol.GetApplicationConfigResponseEntity;
|
||||
return await this.doRpc<
|
||||
Protocol.GetApplicationConfigRequestEntity,
|
||||
Protocol.GetApplicationConfigResponseEntity
|
||||
>(Protocol.GetApplicationConfigRequestEntity);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public async getWindows() {
|
||||
try {
|
||||
return await this.doRpc<
|
||||
Protocol.GetWindowsRequestEntity,
|
||||
Protocol.GetWindowsResponseEntity
|
||||
>(Protocol.GetWindowsRequestEntity);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import EventEmitter from "events";
|
||||
|
||||
export default class EventBus extends EventEmitter {
|
||||
private static _instance: EventBus | null = null;
|
||||
|
||||
public static getInstance() {
|
||||
if (!EventBus._instance) {
|
||||
EventBus._instance = new EventBus();
|
||||
}
|
||||
return EventBus._instance;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { SignalSourceEntity } from "./SignalSourceEntity";
|
||||
import ApplicationConfigEntity from "./ApplicationConfigEntity";
|
||||
import MultimediaWindowEntity from "./MultimediaWindowEntity";
|
||||
|
||||
export namespace Protocol {
|
||||
export class Commands {
|
||||
|
@ -139,4 +140,23 @@ export namespace Protocol {
|
|||
this.command = Commands.kRpcGetApplicationConfig;
|
||||
}
|
||||
}
|
||||
|
||||
export class GetWindowsRequestEntity extends PacketEntity {
|
||||
timestamp: number = new Date().getMilliseconds();
|
||||
|
||||
constructor(rpcid?: number) {
|
||||
super();
|
||||
this.rpc_id = rpcid ?? 0;
|
||||
this.command = Commands.kRpcGetWindows;
|
||||
}
|
||||
}
|
||||
|
||||
export class GetWindowsResponseEntity extends PacketEntity {
|
||||
windows: MultimediaWindowEntity[] = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.command = Commands.kRpcGetWindows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,25 @@
|
|||
// so you can safely delete all default props below
|
||||
|
||||
export default {
|
||||
title: 'MediaPlayerWebAPP',
|
||||
failed: '失败',
|
||||
success: '成功',
|
||||
login: '登录',
|
||||
'user name': '用户名',
|
||||
password: '密码',
|
||||
'please input user name': '请输入用户',
|
||||
'please input password': '请输入密码',
|
||||
'login fail!': '登陆失败',
|
||||
'Please type something': '请输入内容',
|
||||
title: "MediaPlayerWebAPP",
|
||||
failed: "失败",
|
||||
success: "成功",
|
||||
login: "登录",
|
||||
"user name": "用户名",
|
||||
password: "密码",
|
||||
"please input user name": "请输入用户",
|
||||
"please input password": "请输入密码",
|
||||
"login fail!": "登陆失败",
|
||||
"Please type something": "请输入内容",
|
||||
|
||||
'grid setting': '宫格设置',
|
||||
'background image': '底图设置',
|
||||
'data import': '数据导入',
|
||||
'data export': '数据导出',
|
||||
"grid setting": "宫格设置",
|
||||
"background image": "底图设置",
|
||||
"data import": "数据导入",
|
||||
"data export": "数据导出",
|
||||
|
||||
root: '根节点',
|
||||
root: "根节点",
|
||||
|
||||
"close all windwos": "关闭所有窗口",
|
||||
"close this window": "关闭当前窗口",
|
||||
"close other windows": "关闭其它窗口",
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
icon="img:icons/favicon-32x32.png"
|
||||
label="电视机拼接盒"
|
||||
class="q-mr-sm"
|
||||
@click="test"
|
||||
/>
|
||||
<q-separator vertical inset />
|
||||
<q-btn
|
||||
|
@ -60,15 +61,22 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent } from "vue";
|
||||
import { useStore } from "src/store";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageTopToolBar',
|
||||
name: "PageTopToolBar",
|
||||
|
||||
components: {},
|
||||
|
||||
setup() {
|
||||
return {};
|
||||
let $store = useStore();
|
||||
|
||||
return {
|
||||
test() {
|
||||
$store.commit("setWallCol", 2);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -18,6 +18,24 @@
|
|||
</q-item>
|
||||
</q-list>
|
||||
</q-popup-proxy>
|
||||
<div id="windows" style="position: absolute">
|
||||
<div
|
||||
:ref="'window_' + index"
|
||||
v-for="(item, index) in windows"
|
||||
:key="index"
|
||||
class="window"
|
||||
:style="{
|
||||
top: item.y / wall_height_scaler + 'px',
|
||||
left: item.x / wall_width_scaler + 'px',
|
||||
width: item.width / wall_width_scaler + 'px',
|
||||
height: item.height / wall_height_scaler + 'px',
|
||||
}"
|
||||
>
|
||||
{{ wall_height_scaler }}
|
||||
{{ wall_width_scaler }}
|
||||
</div>
|
||||
</div>
|
||||
<div ref="wall_grids">
|
||||
<div
|
||||
v-for="row in wall_rows"
|
||||
:key="row"
|
||||
|
@ -35,6 +53,7 @@
|
|||
width: item_witdh + 'px',
|
||||
height: item_height + 'px',
|
||||
}"
|
||||
@resize="(evt) => loga(evt)"
|
||||
>
|
||||
<q-popup-proxy context-menu no-parent-event>
|
||||
<q-popup-proxy context-menu />
|
||||
|
@ -49,7 +68,9 @@
|
|||
<q-item-section avatar>
|
||||
<q-icon name="close" color="red" />
|
||||
</q-item-section>
|
||||
<q-item-section> {{ $t("close other windwos") }} </q-item-section>
|
||||
<q-item-section>
|
||||
{{ $t("close other windwos") }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup>
|
||||
<q-item-section avatar>
|
||||
|
@ -62,6 +83,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -72,16 +94,22 @@
|
|||
.wall_item {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.window {
|
||||
border: 1px solid rebeccapurple;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import GlobalData from "src/common/GlobalData";
|
||||
import { defineComponent, ref, Ref, computed } from "vue";
|
||||
import { defineComponent, ref, Ref, computed, watch, onMounted } from "vue";
|
||||
import { Common } from "src/common/Common";
|
||||
import { Protocol } from "src/entities/WSProtocol";
|
||||
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useStore } from "src/store";
|
||||
import EventBus from "src/common/EventBus";
|
||||
|
||||
interface _OptionsType {
|
||||
$t: any;
|
||||
|
@ -131,6 +159,15 @@ const _getApplicationConfig = async (options: _OptionsType) => {
|
|||
}
|
||||
};
|
||||
|
||||
const _getWindows = async (options: _OptionsType) => {
|
||||
const global_data = GlobalData.getInstance();
|
||||
let windows = (await global_data.getCurrentClient()?.getWindows())?.windows;
|
||||
let $store = options.$store;
|
||||
if (windows && $store) {
|
||||
$store.commit("setWindows", windows);
|
||||
}
|
||||
};
|
||||
|
||||
const _initialize = async (options: _OptionsType) => {
|
||||
const global_data = GlobalData.getInstance();
|
||||
let client = global_data.getCurrentClient();
|
||||
|
@ -139,7 +176,9 @@ const _initialize = async (options: _OptionsType) => {
|
|||
await Common.waitFor(100);
|
||||
}
|
||||
|
||||
_initSignalSourceTree(options);
|
||||
_initSignalSourceTree(options).then(() => {
|
||||
_getWindows(options);
|
||||
});
|
||||
_getApplicationConfig(options);
|
||||
}
|
||||
};
|
||||
|
@ -157,6 +196,11 @@ export default defineComponent({
|
|||
$store,
|
||||
});
|
||||
|
||||
const windows = computed({
|
||||
get: () => $store.state.windows,
|
||||
set: (val) => $store.commit("setWindows", val),
|
||||
});
|
||||
|
||||
const wall_rows = computed({
|
||||
get: () => $store.state.wall_row,
|
||||
set: (val) => $store.commit("setWallRow", val),
|
||||
|
@ -195,13 +239,40 @@ export default defineComponent({
|
|||
set: (val) => $store.commit("setWallCol", val),
|
||||
});
|
||||
|
||||
const wall_width_scaler = ref(0);
|
||||
const wall_height_scaler = ref(0);
|
||||
|
||||
const calcWallVWScaler = () => {
|
||||
if (wall.value && wall.value.parentElement) {
|
||||
wall_height_scaler.value =
|
||||
$store.state.device_screen_height /
|
||||
(item_height.value * wall_rows.value);
|
||||
wall_width_scaler.value =
|
||||
$store.state.device_screen_width /
|
||||
wall.value.parentElement.offsetWidth;
|
||||
|
||||
wall_height_scaler.value += 0.1;
|
||||
wall_width_scaler.value += 0.05;
|
||||
}
|
||||
};
|
||||
|
||||
EventBus.getInstance().on("windowResize", () => {
|
||||
calcWallVWScaler();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
calcWallVWScaler();
|
||||
});
|
||||
|
||||
return {
|
||||
windows,
|
||||
wall,
|
||||
wall_rows,
|
||||
wall_cols,
|
||||
item_witdh,
|
||||
item_height,
|
||||
|
||||
wall_width_scaler,
|
||||
wall_height_scaler,
|
||||
loga(a: any) {
|
||||
console.log(a);
|
||||
},
|
||||
|
|
|
@ -62,6 +62,12 @@ export default store(function (/* { ssrContext } */) {
|
|||
},
|
||||
|
||||
mutations: {
|
||||
setWindows(state: StateInterface, playload?: any) {
|
||||
let windows = playload as MultimediaWindowEntity[];
|
||||
if (windows) {
|
||||
state.windows = windows;
|
||||
}
|
||||
},
|
||||
clearWindows(state: StateInterface, playload?: any) {
|
||||
state.windows = [];
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue