openc3-cosmos-init/plugins/packages/openc3-tool-common/src/components/widgets/BlockWidget.vue
<!--
# Copyright 2022 Ball Aerospace & Technologies Corp.
# All Rights Reserved.
#
# This program is free software; you can modify and/or redistribute it
# under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; version 3 with
# attribution addendums as found in the LICENSE.txt
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# Modified by OpenC3, Inc.
# All changes Copyright 2024, OpenC3, Inc.
# All Rights Reserved
#
# This file may also be used under the terms of a commercial license
# if purchased from OpenC3, Inc.
-->
<template>
<div class="block-widget-container">
<v-textarea
solo
dense
readonly
no-resize
hide-details
:width="width"
:height="height"
:value="_value"
:class="valueClass"
:style="[computedStyle, aging]"
data-test="valueText"
@contextmenu="showContextMenu"
/>
<v-menu
v-model="contextMenuShown"
:position-x="x"
:position-y="y"
absolute
offset-y
>
<v-list>
<v-list-item
v-for="(item, index) in contextMenuOptions"
:key="index"
@click.stop="item.action"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<details-dialog
:target-name="parameters[0]"
:packet-name="parameters[1]"
:item-name="parameters[2]"
v-model="viewDetails"
/>
</div>
</template>
<script>
import VWidget from './VWidget'
import DetailsDialog from '../../components/DetailsDialog'
import 'sprintf-js'
export default {
components: {
DetailsDialog,
},
data: function () {
return {
width: 400,
height: 400,
bytesPerWord: 4,
wordsPerRow: 4,
addrFormat: null,
formatter: '%02X',
}
},
mixins: [VWidget],
computed: {
aging() {
return {
'--aging': this.grayLevel,
}
},
},
created: function () {
this.width = this.setWidth(this.parameters[3], 'px', this.width)
this.height = this.setHeight(this.parameters[4], 'px', this.height)
if (this.parameters[5]) {
this.formatter = this.parameters[5]
}
if (this.parameters[6]) {
this.bytesPerWord = parseInt(this.parameters[6])
}
if (this.parameters[7]) {
this.wordsPerRow = parseInt(this.parameters[7])
}
if (this.parameters[8]) {
this.addrFormat = this.parameters[8]
}
// parameter[9] is the type ... see getType()
},
methods: {
getType: function () {
var type = 'RAW'
if (this.parameters[9]) {
type = this.parameters[9]
}
return type
},
formatValue: function (data) {
var text = ''
if (data && data.raw) {
var space = ' '
var newLine = '\n'
var byteCount = 0
var addr = 0
const bytesPerRow = this.bytesPerWord * this.wordsPerRow
for (const value of data.raw) {
if (this.addrFormat && byteCount === 0) {
text += sprintf(this.addrFormat, addr)
addr += bytesPerRow
}
text += sprintf(this.formatter, value)
byteCount += 1
if (byteCount % bytesPerRow === 0) {
byteCount = 0
text += newLine
} else if (byteCount % this.bytesPerWord === 0) {
text += space
}
}
} else {
text = data
}
return text
},
},
}
</script>
<style scoped>
.block-widget-container :deep(.v-input__slot) {
background: rgba(var(--aging), var(--aging), var(--aging), 1) !important;
}
.v-textarea :deep(textarea) {
font-family: 'Courier New', Courier, monospace;
}
.value :deep(div) {
min-height: 24px !important;
display: flex !important;
align-items: center !important;
}
.openc3-green :deep(input) {
color: rgb(0, 200, 0);
}
.openc3-yellow :deep(input) {
color: rgb(255, 220, 0);
}
.openc3-red :deep(input) {
color: rgb(255, 45, 45);
}
.openc3-blue :deep(input) {
color: rgb(0, 153, 255);
}
.openc3-purple :deep(input) {
color: rgb(200, 0, 200);
}
.openc3-black :deep(input) {
color: black;
}
.openc3-white :deep(input) {
color: white;
}
</style>