Skip to content

Commit 051c32a

Browse files
authored
feat(gsoc'24): Implemented LayoutElements Panel vue component (CircuitVerse#317)
* feat(gsoc'24): Implemented LayoutElements Panel vue component * fixed syntax err * codeclimate issue fix * codeclimate issue * updated default import * updated naming for indexes * i18n and img not rendering fixed * Update LayoutElementsPanel.vue * layout image url corrected * updated * dropdown added for layoutmode
1 parent 129048f commit 051c32a

File tree

8 files changed

+144
-63
lines changed

8 files changed

+144
-63
lines changed

src/components/Extra.vue

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,7 @@
1616

1717
<!-- --------------------------------------------------------------------------------------------- -->
1818
<!-- Layout Element Panel -->
19-
<div
20-
class="noSelect defaultCursor layoutElementPanel draggable-panel draggable-panel-css"
21-
ref="layoutElementPanelRef"
22-
>
23-
<div class="panel-header">
24-
Layout Elements
25-
<span class="fas fa-minus-square minimize"></span>
26-
<span class="fas fa-external-link-square-alt maximize"></span>
27-
</div>
28-
<div class="panel-body">
29-
<div class="search-results"></div>
30-
<div id="subcircuitMenu" class="accordion"></div>
31-
</div>
32-
</div>
19+
<LayoutElementsPanel />
3320
<!-- --------------------------------------------------------------------------------------------- -->
3421

3522
<!-- --------------------------------------------------------------------------------------------- -->
@@ -173,6 +160,7 @@ import CustomShortcut from './DialogBox/CustomShortcut.vue'
173160
import InsertSubcircuit from './DialogBox/InsertSubcircuit.vue'
174161
import OpenOffline from './DialogBox/OpenOffline.vue'
175162
import ReportIssue from './ReportIssue/ReportIssue.vue'
163+
import LayoutElementsPanel from './Panels/LayoutElementsPanel/LayoutElementsPanel.vue'
176164
import TestBenchPanel from './Panels/TestBenchPanel/TestBenchPanel.vue'
177165
import TestBenchCreator from './Panels/TestBenchPanel/TestBenchCreator.vue'
178166
import TestBenchValidator from './Panels/TestBenchPanel/TestBenchValidator.vue'
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<template>
2+
<div class="noSelect defaultCursor layoutElementPanel draggable-panel draggable-panel-css"
3+
ref="layoutElementPanelRef">
4+
<div class="panel-header">
5+
{{ $t('simulator.layout.layout_elements') }}
6+
<span class="fas fa-minus-square minimize"></span>
7+
<span class="fas fa-external-link-square-alt maximize"></span>
8+
</div>
9+
<div class="panel-body">
10+
<v-expansion-panels id="menu" class="accordion" variant="accordion">
11+
<v-expansion-panel v-for="(group, groupIndex) in SimulatorState.subCircuitElementList" :key="groupIndex">
12+
<v-expansion-panel-title>
13+
{{ group.type }}s
14+
</v-expansion-panel-title>
15+
<v-expansion-panel-text eager>
16+
<div class="panel customScroll">
17+
<div v-for="(element, elementIndex) in group.elements" class="icon subcircuitModule"
18+
:key="`${groupIndex}-${elementIndex}`" :id="`${group.type}-${elementIndex}`"
19+
:data-element-id="elementIndex" :data-element-name="group.type"
20+
@mousedown="dragElement(group.type, element, elementIndex)">
21+
<div class="icon-image">
22+
<img :src="getImgUrl(group.type)" />
23+
<p class="img__description">
24+
{{ element.label !== '' ? element.label : $t('simulator.unlabeled') }}
25+
</p>
26+
</div>
27+
</div>
28+
</div>
29+
</v-expansion-panel-text>
30+
</v-expansion-panel>
31+
</v-expansion-panels>
32+
</div>
33+
</div>
34+
</template>
35+
36+
<script lang="ts" setup>
37+
import { useState } from '#/store/SimulatorStore/state'
38+
import { simulationArea } from '#/simulator/src/simulationArea'
39+
import { useLayoutStore } from '#/store/layoutStore';
40+
import { ref, onMounted } from 'vue';
41+
42+
const layoutStore = useLayoutStore()
43+
44+
const layoutElementPanelRef = ref<HTMLElement | null>(null);
45+
46+
onMounted(() => {
47+
layoutStore.layoutElementPanelRef = layoutElementPanelRef.value
48+
})
49+
50+
const SimulatorState = useState();
51+
52+
const dragElement = (groupType: string, element: any, index: number) => {
53+
element.subcircuitMetadata.showInSubcircuit = true
54+
element.newElement = true
55+
simulationArea.lastSelected = element
56+
57+
// Remove the element from subCircuitElementList
58+
SimulatorState.subCircuitElementList.forEach((typeGroup) => {
59+
typeGroup.elements = typeGroup.elements.filter(
60+
(_, elementIndex) => {
61+
if(typeGroup.type === groupType && index === elementIndex)
62+
return false
63+
64+
return true;
65+
}
66+
)
67+
})
68+
69+
// Remove the type group if its elements array is empty
70+
SimulatorState.subCircuitElementList =
71+
SimulatorState.subCircuitElementList.filter(
72+
(typeGroup) => typeGroup.elements.length > 0
73+
)
74+
}
75+
76+
function getImgUrl(elementName: string) {
77+
const elementImg = new URL(
78+
`../../../simulator/src/img/${elementName}.svg`,
79+
import.meta.url
80+
).href;
81+
return elementImg;
82+
}
83+
</script>
84+
85+
<style scoped>
86+
87+
.layoutElementPanel {
88+
width: 220px;
89+
font: inherit;
90+
display: none;
91+
top: 90px;
92+
left: 10px;
93+
}
94+
</style>

src/locales/bn.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
"report_issue": "সমস্যা রিপোর্ট করুন",
1010
"restricted_elements_used": "সীমাবদ্ধ উপাদান ব্যবহৃত:",
1111
"made_with_circuitverse": "সার্কিটভার্স দ্বারা তৈরি",
12+
"layout": {
13+
"layout_elements": "লেআউট এলিমেন্টস",
14+
"no_elements_available": "কোনো লেআউট এলিমেন্টস উপলব্ধ নেই"
15+
},
16+
"unlabeled": "অনলেবেলড",
1217
"nav": {
1318
"untitled_project": "শিরোনামহীন প্রকল্প",
1419
"sign_out": "সাইন আউট",

src/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
"report_issue": "Report an issue",
1010
"restricted_elements_used": "Restricted elements used:",
1111
"made_with_circuitverse": "Made With CircuitVerse",
12+
"layout": {
13+
"layout_elements": "Layout Elements",
14+
"no_elements_available": "No layout elements available"
15+
},
16+
"unlabeled": "Unlabeled",
1217
"nav": {
1318
"untitled_project": "Untitled",
1419
"sign_out": "Sign Out",

src/locales/hi.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
"report_issue": "मामले की रिपोर्ट करें",
1010
"restricted_elements_used": "प्रतिबंधित एलिमेंट्स जिनका इस्तेमाल किया गया:",
1111
"made_with_circuitverse": "सर्किटवर्स में बनाया गया",
12+
"layout": {
13+
"layout_elements": "लेआउट एलिमेंट्स",
14+
"no_elements_available": "कोई लेआउट एलिमेंट्स उपलब्ध नहीं हैं"
15+
},
16+
"unlabeled": "अनलेबल्ड",
1217
"nav": {
1318
"untitled_project": "शीर्षकहीन",
1419
"sign_out": "साइन आउट",

src/simulator/src/ux.js

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import logixFunction from './data'
1414
import { circuitProperty } from './circuit'
1515
import { updateRestrictedElementsInScope } from './restrictedElementDiv'
1616
import { dragging } from './drag'
17+
import { SimulatorStore } from '#/store/SimulatorStore/SimulatorStore'
18+
import { toRefs } from 'vue'
1719
import { circuitElementList } from './metadata'
1820

1921
export const uxvar = {
@@ -437,51 +439,40 @@ export function fullView() {
437439
Fills the elements that can be displayed in the subcircuit, in the subcircuit menu
438440
**/
439441
export function fillSubcircuitElements() {
440-
$('#subcircuitMenu').empty()
441-
var subCircuitElementExists = false
442+
const simulatorStore = SimulatorStore()
443+
const { subCircuitElementList, isEmptySubCircuitElementList } = toRefs(simulatorStore)
444+
subCircuitElementList.value = []
445+
isEmptySubCircuitElementList.value = true
446+
447+
const subcircuitElements = []
448+
449+
let subCircuitElementExists = false
450+
442451
for (let el of circuitElementList) {
443452
if (globalScope[el].length === 0) continue
444453
if (!globalScope[el][0].canShowInSubcircuit) continue
445-
let tempHTML = ''
446-
447-
// add a panel for each existing group
448-
tempHTML += `<div class="panelHeader">${el}s</div>`
449-
tempHTML += `<div class="panel">`
450454

451455
let available = false
452456

457+
const elementGroup = {
458+
type: el,
459+
elements: [],
460+
}
461+
453462
// add an SVG for each element
454463
for (let i = 0; i < globalScope[el].length; i++) {
455464
if (!globalScope[el][i].subcircuitMetadata.showInSubcircuit) {
456-
tempHTML += `<div class="icon subcircuitModule" id="${el}-${i}" data-element-id="${i}" data-element-name="${el}">`
457-
tempHTML += `<img src= "/img/${el}.svg">`
458-
tempHTML += `<p class="img__description">${
459-
globalScope[el][i].label !== ''
460-
? globalScope[el][i].label
461-
: 'unlabeled'
462-
}</p>`
463-
tempHTML += '</div>'
464465
available = true
466+
const element = globalScope[el][i];
467+
elementGroup.elements.push(element);
465468
}
466469
}
467-
tempHTML += '</div>'
468470
subCircuitElementExists = subCircuitElementExists || available
469-
if (available) $('#subcircuitMenu').append(tempHTML)
470-
}
471+
if (available) {
472+
subcircuitElements.push(elementGroup);
473+
}
471474

472-
if (!subCircuitElementExists) {
473-
$('#subcircuitMenu').append('<p>No layout elements available</p>')
475+
subCircuitElementList.value = subcircuitElements
476+
isEmptySubCircuitElementList.value = !subCircuitElementExists
474477
}
475-
476-
$('.subcircuitModule').mousedown(function () {
477-
let elementName = this.dataset.elementName
478-
let elementIndex = this.dataset.elementId
479-
480-
let element = globalScope[elementName][elementIndex]
481-
482-
element.subcircuitMetadata.showInSubcircuit = true
483-
element.newElement = true
484-
simulationArea.lastSelected = element
485-
this.parentElement.removeChild(this)
486-
})
487478
}

src/store/SimulatorStore/state.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ export interface State {
1717
successMessages: string[]
1818
circuit_name_clickable: boolean;
1919
dialogBox: {
20-
// create_circuit: boolean
21-
// delete_circuit: boolean
2220
combinationalanalysis_dialog: boolean
2321
hex_bin_dec_converter_dialog: boolean
2422
saveimage_dialog: boolean
@@ -31,8 +29,14 @@ export interface State {
3129
export_project_dialog: boolean
3230
import_project_dialog: boolean
3331
}
34-
// createCircuit: Object | { circuitName: string }
3532
combinationalAnalysis: Object
33+
subCircuitElementList: Array<LayoutElementGroup>
34+
isEmptySubCircuitElementList: boolean
35+
}
36+
37+
interface LayoutElementGroup {
38+
type: string
39+
elements: any[]
3640
}
3741

3842
export const useState = defineStore({
@@ -47,8 +51,6 @@ export const useState = defineStore({
4751
successMessages: [],
4852
circuit_name_clickable: false,
4953
dialogBox: {
50-
// create_circuit: false,
51-
// delete_circuit: false,
5254
combinationalanalysis_dialog: false,
5355
hex_bin_dec_converter_dialog: false,
5456
saveimage_dialog: false,
@@ -61,15 +63,14 @@ export const useState = defineStore({
6163
export_project_dialog: false,
6264
import_project_dialog: false,
6365
},
64-
// createCircuit: {
65-
// circuitName: 'Untitled Circuit',
66-
// },
6766
combinationalAnalysis: {
6867
inputNameList: 'eg. In A, In B',
6968
outputNameList: 'eg. Out X, Out Y',
7069
booleanExpression: 'Example: (AB)',
7170
decimalColumnBox: false,
7271
},
72+
subCircuitElementList: [],
73+
isEmptySubCircuitElementList: true,
7374
}
7475
},
75-
})
76+
})

src/styles/css/main.stylesheet.css

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -661,14 +661,6 @@ div.icon img {
661661
right: 10px;
662662
}
663663

664-
.layoutElementPanel {
665-
width: 220px;
666-
font: inherit;
667-
display: none;
668-
top: 90px;
669-
left: 10px;
670-
}
671-
672664
.timing-diagram-panel {
673665
border-radius: 5px;
674666
z-index: 70;

0 commit comments

Comments
 (0)