Quick Sign In:  

Forum: Greek Forum

Topic: ΔΗΜΙΟΥΡΓΙΑ SKIN - Page: 4

This part of topic is old and might contain outdated or incorrect information

djdadPRO InfinityDevelopment ManagerMember since 2005
Μια παρατήρηση. Το σωστό είναι στο action="" να μην χρησιμοπιείς back-tilt ( ` ) . Αυτό είναι χρήσιμο στο color="", όπου το VDJ περιμένει text/color, οπότε με το ` του λες ότι ακολουθεί action που πρέπει να εκτελέσεις για να πάρεις την τιμή του χρώματος.
Άρα
action="vinyl_mode ? get_text 'Vinyl' : get_text 'Cd'"
 

Posted Fri 18 Jan 19 @ 3:50 pm
Ευχαριστώ πολύ, για μία ακόμη φορά...

@ Phantom...

Δεν κατάλαβα ακριβώς το σκεπτικό σου περί group και panel. Όμως, τελειώνοντας το βασικό κώδικα, θα σου στείλω το xml για να έχουμε αμφότεροι ποιο συγκεκριμένες αναφορές.

Μία επιπλέον βοήθεια...

1. Εντολή για να εμφανίζει την τιμή Gain του κομματιού, ως αυτή εμφανίζεται στα tags του, με την ίδια μορφή:
action="param_equal gain 0.5 ? get_text '+0.0' : param_smaller gain 0.5 ? get_text '+%Plevel' : get_text '%Plevel db'"
Πέραν αυτής, δεν βρήκα κάτι άλλο. Είναι "φρέσκια" ή όχι?

2. Εντολή για να εμφανίζει την τιμή (+/-db) του trim (gain), το οποίο έχει μεταβληθεί αυτόματα κατά το AutoGain?

3. Υπάρχει τρόπος απόδοσης της εντολής: action="get_text '`get_vu_meter_peak & param_cast percentage & param_cast int_trunc`%'" σε "πραγματικά" db?

4. Υπάρχει η δυνατότητα να εμφανίζονται (μέσω σχετικών εντολών) οι τιμές των settings?
Παράδειγμα 1: action="autogain ? get_text 'On' : get_text 'Off'"
Παράδειγμα 2: action="get_equalizerLowFrequency"

5. Επέλεξα εξαρχής να σχεδιάσω το png σε 16bit βάθος χρώματος, ώστε να έχω καλύτερη απεικόνιση χρωματικών διαβαθμίσεων? Έπραξα καλώς ή "βαραίνει" το skin?
Σημειώνω ότι μέχρι τώρα, δεν ξεπερνάει τα 2MB...
 

Posted Thu 24 Jan 19 @ 6:26 pm
Προσωπικά δεν χρησιμοποιώ groups ιδιαίτερα (σχεδόν καθόλου) και ούτε αναφέρθηκα σε αυτά (ακριβώς γιατί δεν τα χρησιμοποιώ)

Tώρα: Ένα panel χρησιμοποιείται ως η "κόλλα" μεταξύ διάφορων στοιχείων. Κολλώντας λοιπόν κουμπιά, sliders, κείμενα κτλ μεταξύ τους φτιάχνεις ένα panel που αντιπροσωπεύει ένα deck. Όταν κατασκευάζεις αυτή την απεικόνιση καλό είναι να μην ορίζεις deck στα αντικείμενα. Δηλαδή ένα κουμπί θα έχει action=play αλλά δεν θα έχει deck.
Το XML Node <deck deck="1">...</deck> ορίζει σε ποιο deck θα εκτελούνται οι εντολές μέσα σε αυτό node
Έτσι λοιπόν γράφοντας <deck deck="1"><panel name="MyDeck"/></deck> ορίζεις οτι θες όλες οι εντολές του panel να εκτελούνται στο deck 1

Με τον τρόπο αυτό γλυτώνεις το να πληκτρολογείς τα ίδια και τα ίδια πολλές φορές.

Φτιάχνεις ΜΙΑ πρόσοψη/απεικόνιση ενός deck (κολλάς τα αντικείμενα μία φορά), και μετά "καλείς" αυτή την πρόσοψη όσες φορές θέλεις για κάθε deck χωριστά.

Τώρα ας πούμε οτι έχεις φτιάξει 3 διαφορετικές απεικονίσεις για τo ίδιο deck.
Μία απεικόνιση για video, μία για όταν ο χρήστης παίζει με εξωτερικό μίκτη, και μία για όταν παίζει με εσωτερικό (τα παραδείγματα είναι τυχαία)

Έχεις λοιπόν 3 διαφορετικά panels:
<panel name="DeckVideo" visible="video ? on : off">... (αντικείμενα του panel)</panel>
<panel name="DeckAudioInternalMixer" visible="video ? off : mixermode ? on : off">... (αντικείμενα του panel)</panel>
<panel name="DeckAudioExternalMixer" visible="video ? off : mixermode ? off : on">... (αντικείμενα του panel)</panel>


Αν τα panels τα γράψεις απευθείας στον κώδικα XML αυτά θα ζωγραφιστούν στο skin. Γι αυτό και θα τα μετατρέψουμε σε definitions:
<define class="MyDeckVideo" name="DeckVideo" visible="video ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioInt" name="DeckAudioInternalMixer" visible="video ? off : mixermode ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioExt" name="DeckAudioExternalMixer" visible="video ? off : mixermode ? off : on">... (αντικείμενα του panel)</define>


Μέχρι εδώ ελπίζω να είναι όλα κατανοητά. Έχεις κάνει define 3 διαφορετικά panels, 1 για κάθε πρόσοψη/απεικόνιση του ίδιου deck.

Τώρα πάμε να τα ζωγραφίσουμε στο skin:

Α) Θέλουμε να ζωγραφίσουμε τα panels
Β) Θέλουμε να ορίσουμε το deck το οποίο θα απεικονίζεται στην οθόνη από το panel
Γ) Θέλουμε το deck να αλλάζει αυτόματα με βάση ποιο είναι το επιλεγμένο deck από τον χρήστη.

Ξεκινάμε ανάποδα, δηλαδή πρώτα ελέγχουμε ποιο είναι το επιλεγμένο deck, ώστε να ζωγραφίσουμε το αντίστοιχο deck στην οθόνη.
Για να το κάνουμε αυτό ο πιο εύκολος τρόπος είναι με panels:
<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">...</panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck">...</panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck">...</panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck">...</panel>

Με αυτές τις 4 γραμμές θα ζωγραφίσουμε κάθε φορά μόνο ΕΝΑ deck δεξιά και ΕΝΑ αριστερά με βάση τις επιλογές του χρήστη

Το επόμενο βήμα είναι να ορίσουμε το deck:
<panel name="Deck1LeftDeck" visible="deck 1 leftdeck"><deck deck="1">...</deck></panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck"><deck deck="3">...</deck></panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck"><deck deck="2">...</deck></panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck"><deck deck="4">...</deck></panel>


Το τρίτο και τελευταίο βήμα είναι να ζωγραφίσουμε τα panels που απαρτίζουν το deck

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</deck>
</panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck">
<deck deck="3">
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</deck>
</panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck">
<deck deck="2">
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</deck>
</panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck">
<deck deck="4">
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</deck>
</panel>


Αν και ο κώδικας παραπάνω είναι ολόσωστος (και θα δουλέψει άψογα) εμείς επαναλαμβάνουμε 3 γραμμές 4 φορές "χωρίς λόγο"
Έτσι λοιπόν μπορούμε να βελτιστοποιήσουμε τον κώδικα κι άλλο.
Τα 3 panels που επαναλαμβάνονται για κάθε deck μπορούν να οριστούν σαν 1 panel!

Έτσι σαν τελική λύση θα έχουμε:

<define class="MyDeckVideo" name="DeckVideo" visible="video ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioInt" name="DeckAudioInternalMixer" visible="video ? off : mixermode ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioExt" name="DeckAudioExternalMixer" visible="video ? off : mixermode ? off : on">... (αντικείμενα του panel)</define>

<define class="MyDeck" name="Deck"/>
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</define>

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeck"/>
</deck>
</panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck"><deck deck="3"><panel class="MyDeck"/></deck></panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck"><deck deck="2"><panel class="MyDeck"/></deck></panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck"><deck deck="4"><panel class="MyDeck"/></deck></panel>


Μένει μόνο ένα πρόβλημα: Οι συντεταγμένες κάθε deck. αυτό λύνεται στο τελευταίο κομμάτι του κώδικα:


<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeck" x="20" y="40"/>
</deck>
</panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck"><deck deck="3"><panel class="MyDeck" x="20" y="40"/></deck></panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck"><deck deck="2"><panel class="MyDeck" x="980" y="40"/></deck></panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck"><deck deck="4"><panel class="MyDeck" x="980" y="40"/></deck></panel>


Αν θέλεις όλο τον κώδικα συγκεντρωμένο:


<define class="MyDeckVideo" name="DeckVideo" visible="video ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioInt" name="DeckAudioInternalMixer" visible="video ? off : mixermode ? on : off">... (αντικείμενα του panel)</define>
<define class="MyDeckAudioExt" name="DeckAudioExternalMixer" visible="video ? off : mixermode ? off : on">... (αντικείμενα του panel)</define>

<define class="MyDeck" name="Deck"/>
<panel class="MyDeckVideo"/>
<panel class="MyDeckAudioInt"/>
<panel class="MyDeckAudioExt"/>
</define>

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck"><deck deck="1"><panel class="MyDeck" x="20" y="40"/></deck></panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck"><deck deck="3"><panel class="MyDeck" x="20" y="40"/></deck></panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck"><deck deck="2"><panel class="MyDeck" x="980" y="40"/></deck></panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck"><deck deck="4"><panel class="MyDeck" x="980" y="40"/></deck></panel>


Βλέπεις πόσο συμμαζεμένος είναι ο τελευταίος κώδικας. Και το καλό είναι οτι κάθε αλλαγή που κάνεις σε ένα από τα 3 αρχικά defines (τις προσόψεις/απεικονίσεις του deck) εμφανίζεται αυτόματα σε όλα τα deck χωρίς καμία άλλη αλλαγή στον κώδικα.
 

Posted Fri 25 Jan 19 @ 8:37 am
Theios Giorgos wrote :
1. Εντολή για να εμφανίζει την τιμή Gain του κομματιού, ως αυτή εμφανίζεται στα tags του, με την ίδια μορφή:
action="param_equal gain 0.5 ? get_text '+0.0' : param_smaller gain 0.5 ? get_text '+%Plevel' : get_text '%Plevel db'"
Πέραν αυτής, δεν βρήκα κάτι άλλο. Είναι "φρέσκια" ή όχι?

Είναι μια χαρά καθώς είναι και η "μοναδική"

Theios Giorgos wrote :
2. Εντολή για να εμφανίζει την τιμή (+/-db) του trim (gain), το οποίο έχει μεταβληθεί αυτόματα κατά το AutoGain?

Όχι δεν υπάρχει.

Theios Giorgos wrote :
3. Υπάρχει τρόπος απόδοσης της εντολής: action="get_text '`get_vu_meter_peak & param_cast percentage & param_cast int_trunc`%'" σε "πραγματικά" db?

Όχι δεν υπάρχει.

Theios Giorgos wrote :
4. Υπάρχει η δυνατότητα να εμφανίζονται (μέσω σχετικών εντολών) οι τιμές των settings?
Παράδειγμα 1: action="autogain ? get_text 'On' : get_text 'Off'"
Παράδειγμα 2: action="get_equalizerLowFrequency"

Για όλες τις ρυθμίσεις μπορείς να χρησιμοποιήσεις την εντολή setting
action="setting 'autogain' 'auto' ? get_text 'Auto' : setting 'autogain' 'auto+remember' ? get_text 'Remember' : get_text 'Off'
action="setting 'equalizerLowFrequency' "

Theios Giorgos wrote :
5. Επέλεξα εξαρχής να σχεδιάσω το png σε 16bit βάθος χρώματος, ώστε να έχω καλύτερη απεικόνιση χρωματικών διαβαθμίσεων? Έπραξα καλώς ή "βαραίνει" το skin?
Σημειώνω ότι μέχρι τώρα, δεν ξεπερνάει τα 2MB...

Ναι, και αμφιβάλω αν η skin engine διαβάζει PNG με λιγότερα από 16 bit (οπότε θα είχες πρόβλημα)
 

Posted Fri 25 Jan 19 @ 8:45 am
Σε ευχαριστώ πάρα πολύ για την ιδιαίτερα αναλυτική απάντησή σου! Είσαι άκρως δοτικός σε αυτό το forum και νομίζω ότι και το αντιλαμβανόμαστε και το εκτιμούμε όλοι ανεξαιρέτως αυτό…

Επειδή ψιλομπερδεύτηκα, θα ήθελα να γίνω πιο συγκεκριμένος, ώστε (σε παρακαλώ) να με κατατοπίσεις καλύτερα…

Επισυνάπτω το png με τα βασικά (έχω αφαιρέσει τα δευτερεύοντα) γραφικά, τα οποία δεν θα είναι στατικά μεν, αλλά τα έχω προσθέσει για λόγους ευκολίας δε…

Στο αρχείο, πέραν των άλλων, απεικονίζεται το Deck Left (Deck 1 μπλε), το Master (γκρι) και το Deck Right (Deck 2 κόκκινο).

Ας ασχοληθούμε μόνο με το Deck Left

Το επιθυμητό είναι, το Deck Left να αλλάζει, είτε σε Deck 1 (μπλε περίγραμμα), είτε σε Deck 3 (πράσινο περίγραμμα). Άρα, κατά τα γραφόμενά σου, έχω:
<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck">

Μέχρι εδώ, εάν δεν έχω κάνει κάποιο λάθος, κατανοητά…

Κατόπιν, το επιθυμητό είναι, στο Deck 1 (μπλε περίγραμμα) η “οθόνη” (μαύρη, εσωτερικά του μπλε περιγράμματος), να μπορεί να αλλάζει σε Layout A, Layout B, Layout C, Layout D. Διευκρίνηση: Τα Layouts δεν θα έχουν τα ίδια elements, αλλά διαφορετικά.

Προφανώς και κάθε διαφορετικό Layout αποτελεί και το αντίστοιχο διαφορετικό panel. Εδώ προκύπτει ότι θα έχω:
<panel name="DeckLayoutA" visible="deck 1 leftdeck">
<panel name="DeckLayoutB" visible="deck 1 leftdeck">
<panel name="DeckLayoutC" visible="deck 1 leftdeck">
<panel name="DeckLayoutD" visible="deck 1 leftdeck">
Εδώ το: visible="deck 1 leftdeck" δεν είναι ορθό, καθότι όλα τα layouts θα είναι κοινά για όλα τα Decks.

Άρα, πως θα συντάξω τον κώδικα, ώστε να έχουμε 4 διαφορετικά layouts, τα οποία θα μπορούν να παρουσιάζονται (κατ’ επιλογήν) σε 4 διαφορετικά Decks. Για παράδειγμα, στο Deck Left, θα μπορούμε να έχουμε το Deck 3 με Layout B και στο Deck Right το Deck 2 με Layout D.

Εγώ όπως το αντιλαμβάνομαι, θα πρέπει να έχω Panels (layouts) “μέσα” σε Panels (Decks). Και επειδή έχουμε 4 Panels (layouts) και 4 Panels (Decks), θα προκύπτουν 16 συνδυασμοί συνολικά. Έτσι είναι ή “το χάνω” κάπου?

Διευκρίνηση: Αυτό που χαρακτηρίζει το εκάστοτε Deck, είναι η χρωματιστή γραμμή (μπλε, κόκκινη, πράσινη, κίτρινη), την οποία σχεδίασα ως “ανεξάρτητη” και όχι ως outline του screen του deck, ώστε να μην απαιτηθεί να σχεδιάσω 16 διαφορετικά screens…


Πάω λίγο παρακάτω…

Το εκάστοτε Layout περιλαμβάνει:

I. Τα Graphics
II. Τα Labels
III. Τα Values

Ξεκινώντας απ’ τα Labels (που ήδη έχω δουλέψει), ένα τυχαίο παράδειγμα κώδικα είναι το ακόλουθο:
<define class="lbl_Elapsed">
<size width="90-10" height="16"/>
<text font="Segoe UI" size="16" align="center" scroll="no" color="#808080" format="ELAPSED"/>
</define>

Ερώτηση: Εφόσον τα Labels θα είναι ίδια για όλα τα Layouts και απλά θα αλλάζει το Format=”…” και το ποιο θα εμφανίζεται ανά Layout, πώς πρέπει εγγραφούν στον κώδικα?
Να τα έχω ξεχωριστά και μεμονωμένα ως definitions στην αρχή του xml και να τα αναφέρω ξεχωριστά ανά Layout - Panel? Να δημιουργήσω ένα definition Labels’ group ανά Layout ξεχωριστά? Άλλος τρόπος? Ποιος είναι ο καλύτερος?

Συνεχίζοντας με τα Values (που επίσης ήδη έχω δουλέψει), ένα αντίστοιχο παράδειγμα κώδικα είναι το ακόλουθο:

<define class="val_Elapsed" visibility="loaded" classdeck="1">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>

Σε αυτή την περίπτωση, ο κώδικας classdeck="1" είναι αναγκαίος ή περιττός?


 

Posted Fri 25 Jan 19 @ 1:11 pm
Ξεκινάμε με τα "απλά"

Έχεις 4 layouts
Αυτά τα layouts πως τα ελέγχεις; Πως επιλέγεις ποιο θα είναι ορατό κάθε φορά;
Είτε "αυτόματα", είτε χειροκίνητα, τα layout αυτά κάπως θα αλλάζουν.
Έστω οτι ο χρήστης επιλέγει "ελεύθερα" όποιο layout θέλει για οποιοδήποτε deck (με βάση κάποια κουμπιά)
Για να εκμεταλλευτείς πλήρως τις δυνατότητες της script engine και να αποφύγεις περιττές επαναλήψεις κώδικα ο σωστός τρόπος είναι τα κουμπιά να ορίζουν μια μεταβλητή, και τα panels να εξαρτώνται από αυτή τη μεταβλητή.

Για παράδειγμα θα έχεις ένα κουμπί σε κάθε deck με εντολή <button action="cycle '@DeckLayout' 4"

Έτσι στα panels θα έχεις

<panel name="DeckLayoutA" visible="var_equal '@DeckLayout' 0">
<panel name="DeckLayoutB" visible="var_equal '@DeckLayout' 1">
<panel name="DeckLayoutC" visible="var_equal '@DeckLayout' 2">
<panel name="DeckLayoutD" visible="var_equal '@DeckLayout' 3">

Πρόσεχε λίγο το όνομα της μεταβλητής:
Ξεκινάει με @ που σημαίνει οτι είναι persistent (αποθηκεύεται κατά το κλείσιμο του προγράμματος)
Δεν έχει το $ μετά το @ που σημαίνει οτι είναι τοπική μεταβλητή (για κάθε deck) και όχι καθολική (global)
Έτσι λοιπόν κάθε deck έχει τη δική του τιμή για την μεταβλητή DeckLayout η οποία αποθηκεύεται και ανακαλείται κατά την έναρξη/επανεκκίνηση του προγράμματος.

Quote :
Εγώ όπως το αντιλαμβάνομαι, θα πρέπει να έχω Panels (layouts) “μέσα” σε Panels (Decks). Και επειδή έχουμε 4 Panels (layouts) και 4 Panels (Decks), θα προκύπτουν 16 συνδυασμοί συνολικά. Έτσι είναι ή “το χάνω” κάπου?

Έτσι είναι, μόνο που εσύ δεν θα φτιάξεις (γράψεις σε κώδικα) τους 16 συνδυασμούς, ούτε θα καθίσεις να τους "υπολογίσεις"

Αυτή είναι η πραγματική δύναμη των conditional panels

Εσύ καθαρίζεις με 10 γραμμές κώδικα:

<define class="DeckLayoutA" name="DeckLayoutA" visible="var_equal '@DeckLayout' 0">... (αντικείμενα του panel)</define>
<define class="DeckLayoutB" name="DeckLayoutB" visible="var_equal '@DeckLayout' 1">... (αντικείμενα του panel)</define>
<define class="DeckLayoutC" name="DeckLayoutC" visible="var_equal '@DeckLayout' 2">... (αντικείμενα του panel)</define>
<define class="DeckLayoutD" name="DeckLayoutD" visible="var_equal '@DeckLayout' 3">... (αντικείμενα του panel)</define>

<define class="MyDeck" name="Deck"/>
<panel class="DeckLayoutA"/>
<panel class="DeckLayoutB"/>
<panel class="DeckLayoutC"/>
<panel class="DeckLayoutD"/>
</define>

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck"><deck deck="1"><panel class="MyDeck" x="20" y="40"/></deck></panel>
<panel name="Deck3LeftDeck" visible="deck 3 leftdeck"><deck deck="3"><panel class="MyDeck" x="20" y="40"/></deck></panel>
<panel name="Deck2RightDeck" visible="deck 2 rightdeck"><deck deck="2"><panel class="MyDeck" x="980" y="40"/></deck></panel>
<panel name="Deck4RightDeck" visible="deck 4 rightdeck"><deck deck="4"><panel class="MyDeck" x="980" y="40"/></deck></panel>


Quote :
Ξεκινώντας απ’ τα Labels (που ήδη έχω δουλέψει), ένα τυχαίο παράδειγμα κώδικα είναι το ακόλουθο:
<define class="lbl_Elapsed">
<size width="90-10" height="16"/>
<text font="Segoe UI" size="16" align="center" scroll="no" color="#808080" format="ELAPSED"/>
</define>

Ερώτηση: Εφόσον τα Labels θα είναι ίδια για όλα τα Layouts και απλά θα αλλάζει το Format=”…” και το ποιο θα εμφανίζεται ανά Layout, πώς πρέπει εγγραφούν στον κώδικα?
Να τα έχω ξεχωριστά και μεμονωμένα ως definitions στην αρχή του xml και να τα αναφέρω ξεχωριστά ανά Layout - Panel? Να δημιουργήσω ένα definition Labels’ group ανά Layout ξεχωριστά? Άλλος τρόπος? Ποιος είναι ο καλύτερος?

Για αυτό το ερώτημα δεν υπάρχει σαφής απάντηση γιατί εξαρτάται εν πολύ από το σχεδιασμό του skin.
Προσωπικά θα σου πω πως δουλεύω εγώ:
  • Κάνω define κάθε label χωριστά. Δηλαδή κάνω διαφορετικό define για κάθε διαφορετικό label (label σε διαφορετική θέση)
  • Τα define τα κάνω με βάση το "πρώτο" layout στο οποίο τα καλώ/χρειάζομαι
  • Στο define περιλαμβάνω ΤΑ ΠΑΝΤΑ (όλα τα στοιχεία που χρειάζεται για να εμφανιστεί στη σωστή θέση στο πρώτο layout)
  • Όταν χρειάζεται να επαναχρησιμοποιήσω το ίδιο label σε άλλο layout και έχει άλλη θέση απ' ότι στο πρώτο, τότε δεν κάνω νέο define αλλά κάνω override την θέση του label στο layout.

Παράδειγμα:

1. Definition:
<define class="lbl_Elapsed">
<size width="90-10" height="16"/>
<pos x="+150" y="+20"
<text font="Segoe UI" size="16" align="center" scroll="no" color="#808080" format="ELAPSED"/>
</define>

2. Κλήση στο πρώτο Layout

<panel class="LayoutA">
...
<textzone class="lbl_Elapsed"/>
...
</panel>

3. Κλήση στο δεύτερο layout σε διαφορετική θέση:

<panel class="LayoutΒ">
...
<textzone class="lbl_Elapsed"><pos x="+130" y="+35"/></textzone>
...
</panel>


Quote :
<define class="val_Elapsed" visibility="loaded" classdeck="1">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>

Σε αυτή την περίπτωση, ο κώδικας classdeck="1" είναι αναγκαίος ή περιττός?

Το classdeck το χρειάζεσαι σε λίγες περιπτώσεις, και κυρίως για να δώσεις διαφορετικά γραφικά σε κουμπιά / visuals κτλ ανάλογα με το deck.
Σε textzones το classdeck στο 99% των περιπτώσεων είναι πλέον αχρείαστο αφού μπορείς να ορίσεις τόσο το χρώμα όσο και το κείμενο με VDJ Script.
Όταν πρωτοκυκλοφόρησε το VirtualDJ 8 δεν μπορούσες να γράψεις "εντολή" για το χρώμα του κειμένου. Έτσι έπρεπε να χρησιμοποιείς το classdeck αν ήθελες διαφορετικό χρώμα για κάθε deck. Τώρα που μπορείς να δώσεις εντολές, είναι ψιλό-περιττό
Γενικά να στο πω διαφορετικά:
Αν ο κώδικας είναι "ίδιος" μεταξύ των διαδοχικών definitions που χρησιμοποιούν το classdeck τότε όχι ΔΕΝ το χρειάζεσαι.

Σημείωση:
Όταν χρησιμοποιούμε classdeck κάνουμε τόσες φορές define το αντίστοιχο element όσα και τα decks που θέλουμε να το χρησιμοποιήσουμε.
Έτσι στο παράδειγμα σου θα πρέπει να κάνεις define ως εξής:

<define class="val_Elapsed" visibility="loaded" classdeck="1">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>

<define class="val_Elapsed" visibility="loaded" classdeck="2">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>

<define class="val_Elapsed" visibility="loaded" classdeck="3">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>

<define class="val_Elapsed" visibility="loaded" classdeck="4">
<size width="90-10" height="26"/>
<text font="LCD" size="26" align="center" scroll="no" weight="bold" color="`songpos_remain 15000ms ? blink 500ms ? color '#ff00ff' : color '#660066' : songpos_remain 30000ms ? blink 1000ms ? color 'orange' : color 'darkorange' : color '#c0c0c0'`" action="get_time 'elapsed'"/>
<tooltip>Elapsed Time</tooltip>
</define>


Απ' ότι βλέπεις, απλά γράφεις 4 φορές τον ίδιο ακριβώς κώδικα... Οπότε στο συγκεκριμένο παράδειγμα το classdeck όχι μόνο είναι περιττό, αλλά είναι ΜΗ επιθυμητό!
 

Posted Sun 27 Jan 19 @ 3:20 pm
Εφόσον, πλέον, ο κώδικάς μου είναι ολοκληρωμένος σε ικανοποιητικό ποσοστό, θα κάνω μία σύνοψη και με διορθώνεις όπου απαιτείται ή μου προτείνεις πιο "ευέλικτες" λύσεις...

Αρχικά...

<group name="class_defines">
<group name="Graphics">elements</group>
<group name="Labels">elements</group>
<group name="Values">elements</group>
<group name="Panels">elements</group>
</group>

Ερώτηση 1: Κατ' αρχήν συμφωνείς με το grouping? Σημειωτέων ότι ο βασικός λόγος που το δημιούργησα είναι η σύμπτυξη/ανάπτυξη των groups, ώστε να μετακινούμαι ευκολότερα στο NotePad. Εάν όχι, τότε τελειώνοντας με τα definitions, να διαγράψω τα sub-groups (graphics, labels, values, panels)?

Ερώτηση 2: Όπως προανέφερα, σκέφτηκα ότι το "ιδεατό" θα είναι στα όποια definitions να υφίστανται όλες οι πληροφορίες του εκάστοτε element, πλην του position και του classdeck. Εάν, όπως ανέφερες, συμπεριλάβω και το (αρχικό) position (και κατόπιν να κάνω override), τί έχω να "κερδίσω"?


Ακολούθως και επί του group Panels, όπως τα ανέλυσες...

<define class="DeckLayoutA" name="DeckLayoutA" visible="var_equal '@DeckLayout' 0">
<textzone class="element1" x="+000" y="+000"/>
<textzone class="element2"/><pos x="+000" +y="+000"/>
.....
</define>

Ερώτηση 3: Ποιος από τους 2 τρόπους σύνταξης προσδιορισμού θέσης είναι ο "ορθός"?


<define class="MyDeck" name="Deck"/>
<panel class="DeckLayoutA"/>
</define>

Ερώτηση 4: Αυτό το definition, δεν το κατανοώ! Μπορείς να μου το αναλύσεις σε παρακαλώ?


<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1"><panel class="MyDeck" x="20" y="40"/></deck>
</panel>

Ερώτηση 5: Και εδώ δεν το κατανοώ! Μπορείς να μου το αναλύσεις σε παρακαλώ?


Μέχρι εδώ, λοιπόν, εάν όλα είναι ορθά και υλοποιηθούν, τότε θα έχω πλέον έτοιμα τα π.χ. 4 Layouts που επιθυμώ. Οπότε το μόνο που απομένει είναι να οριστεί είτε 1 button που θα κάνει roll τα layouts, είτε 4 ξεχωριστά buttons, είτε αντίστοιχες επιλογές σε σχετικό menu.

Ερώτηση 6: Παίζει ρόλο ο τρόπος επιλογής, όσον αφορά στον κώδικα, ώστε να μπορώ να τον κάνω mapping και στον controller? Π.χ Εάν στον Denon MC6000MK2 αντιστοιχίσω το roll-button BEATS για αυτό το σκοπό, ενώ στο skin να αλλάζει μέσω menu, θα έχω ασυμβατότητα?


Αυτά προς το παρόν...
 

Posted Sun 27 Jan 19 @ 9:59 pm
Κάτι μου δεν κάνω σωστά. Παραθέτω ένα δείγμα ενός minimum “κορμού” που δημιούργησα, το οποίο βγάζει error

<Skin>

<group name="class_defines">

<group name="Graphics">
<define class="btn_Config" action="settings"> … </define>
<define class="btn_Minimize" action="minimize"> … </define>
<define class="btn_Maximize" action="maximize 'maximized'" visibility="maximize 'windowed' ? true : false"> … </define>
<define class="btn_Restore" action="maximize 'windowed'" visibility="maximize 'windowed' ? false : true"> … </define>
<define class="btn_Fullscreen" action="maximize 'fullscreen' ? on & maximize 'maximized' : maximize 'fullscreen'"> … </define>
<define class="btn_Exit" action="close"> … </define>
</group>

<group name="Labels">
<define class="lbl_Elapsed"> … </define>
<define class="lbl_Remain"> … </define>
<define class="lbl_Tempo"> … </define>
<define class="lbl_Pitch"> … </define>
<define class="lbl_Key"> … </define>
<define class="lbl_Gain"> … </define>
<define class="lbl_Loop"> … </define>
<define class="lbl_Pads"> … </define>
<define class="lbl_Effects"> … </define>
<define class="lbl_Sampler"> … </define>
</group>

<group name="Panels">
<define class="DeckLayoutA" name="DeckLayoutA" visible="yes">
<textzone class="lbl_Elapsed" x="+6" y="+1"/>
<textzone class="lbl_Remain" x="+636" y="+1"/>
<textzone class="lbl_Tempo" x="+51" y="+91"/>
<textzone class="lbl_Pitch" x="+231" y="+91"/>
<textzone class="lbl_Key" x="+411" y="+91"/>
<textzone class="lbl_Gain" x="+591" y="+91"/>
<textzone class="lbl_Loop" x="+51" y="+151"/>
<textzone class="lbl_Pads" x="+231" y="+151"/>
<textzone class="lbl_Effects" x="+411" y="+151"/>
<textzone class="lbl_Sampler" x="+591" y="+151"/>
</define>
<define class="MyDeck" name="Deck"/><panel class="DeckLayoutA"/>
</define>
</group>

</group>

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck"><deck deck="1"><panel class="MyDeck" x="6" y="151"/></deck></panel>

</skin>


Λείπει το size του panel? Λείπει κάτι άλλο? Που το "έχασα"?...
 

Posted Mon 28 Jan 19 @ 6:43 am
Quote :
Ερώτηση 1: Κατ' αρχήν συμφωνείς με το grouping? Σημειωτέων ότι ο βασικός λόγος που το δημιούργησα είναι η σύμπτυξη/ανάπτυξη των groups, ώστε να μετακινούμαι ευκολότερα στο NotePad. Εάν όχι, τότε τελειώνοντας με τα definitions, να διαγράψω τα sub-groups (graphics, labels, values, panels)?

Εφόσον το grouping το χρησιμοποιείς για τους λόγους που ανέφερες, δεν υπάρχει λόγος ούτε να διαγράψεις, ούτε να τροποποιήσεις κάτι

Quote :
Ερώτηση 2: Όπως προανέφερα, σκέφτηκα ότι το "ιδεατό" θα είναι στα όποια definitions να υφίστανται όλες οι πληροφορίες του εκάστοτε element, πλην του position και του classdeck. Εάν, όπως ανέφερες, συμπεριλάβω και το (αρχικό) position (και κατόπιν να κάνω override), τί έχω να "κερδίσω"?

Κατ' αρχήν ποιος ο λόγος να χρησιμοποιήσεις classdeck αν δεν το βάλεις στο definition. Το classdeck είναι στοιχείο χρήσιμο στο definition και μόνο εκεί. Αυτό που κάνει το classdeck είναι να "λέει" στο πρόγραμμα οτι το definition με όνομα "Χ" ισχύει έτσι όπως είναι ορισμένο μόνο στο συγκεκριμένο deck.
Εκτός definition το classdeck είναι περιττό και μάλιστα το VirtualDJ το αγνοεί τελείως αφού δεν είναι στοιχείο που υποστηρίζεται σε άλλα elements

Τώρα για τη θέση, εξαρτάται από το πως δουλεύεις και το πως επαναχρησιμοποιείς στοιχεία.
Αυτό που ανακάλυψα εγώ στα δικά μου skin είναι οτι πολλά επαναχρησιμοποιούμενα στοιχεία καταλήγουν στις ίδιες σχετικές συντεταγμένες, οπότε το να προσθέσω στον κώδικα τις ίδιες συντεταγμένες σε 3 διαφορετικά layouts από τα 4 π.χ. είναι counter-productive.
Επίσης πολλά στοιχεία τα καλείς μόνο μια φορά. Για αυτά τα στοιχεία είναι πιο εύκολο όταν θες να τα τροποποιήσεις να βλέπεις όλα τα child attributes συγκεντρωμένα στο definition, παρά να ψάχνεις τα μισά σε ένα μέρος και τα μισά σε άλλο.
Θα σου θέσω ένα πραγματικό πρόβλημα:
Φτιάχνεις όλα τα texts με βάση τον υπολογιστή σου που τρέχει σε Windows. Και μετά δοκιμάζεις το skin και στο MAC ενός φίλου. Επειδή τα κείμενα γίνονται render ελαφρώς διαφορετικά στο MAC OS απ' οτι στα Windows ανακαλύπτεις οτι πρέπει να τροποποιήσεις 5 labels για να δείχνουν σωστά (να τα μεγαλώσεις και να πειράξεις λίγο τις συντεταγμένες τους)
Με τη δική σου λογική για κάθε label θα πρέπει να αλλάξεις το size στο definition και την θέση στο panel. Που σημαίνει συνεχώς "back and forth" στον κώδικα για δοκιμές μέχρι να "ταιριάξουν" οι μετατροπές.
Και οι δύο λογικές (και η δική σου και η δική μου) δεν είναι λάθος. Απλά θεωρώ οτι κερδίζεις λίγη ευκολία παραπάνω με τον δικό μου τρόπο.

Quote :
Ακολούθως και επί του group Panels, όπως τα ανέλυσες...

<define class="DeckLayoutA" name="DeckLayoutA" visible="var_equal '@DeckLayout' 0">
<textzone class="element1" x="+000" y="+000"/>
<textzone class="element2"/><pos x="+000" +y="+000"/>
.....
</define>

Ερώτηση 3: Ποιος από τους 2 τρόπους σύνταξης προσδιορισμού θέσης είναι ο "ορθός"?

Κανένας! :P
Και εξηγώ: Κάποια elements όπως τα panels δέχονται attributes όπως Χ και Υ. Κάποια άλλα όχι και η θέση X και Υ ορίζεται μόνο μέσω του child node
Έτσι τα
<panel id="MyPanel" x="+000" y="+000">
...
</panel>
και
<panel id="MyPanel">
<pos x="+000" y="+000"/>
...
</panel>
είναι το ίδιο
Επίσης το
<panel id="MyPanel" x="+200" y="+200">
<pos x="+000" y="+000"/>
...
</panel>
θα ζωγραφιστεί στο x="+200" y="+200"

Τα textzones ΔΕΝ δέχονται override στην θέση μέσω attributes.
Στα textzones η θέση δίνεται ΠΑΝΤΑ από το child element <pos>

Τότε, γιατί είναι λάθος το <textzone class="element2"/><pos x="+000" +y="+000"/> που έγραψες παραπάνω;
Γιατί είναι λάθος το XML formatting όσον αφορά την σύνταξη του child element <pos>
Κλείνεις το textzone element πριν ανοίξεις το child.
Ο σωστός τρόπος είναι
<textzone class="element2"><pos x="+000" +y="+000"/></textzone>
Αφαιρέσαμε το / από το κλείσιμο του textzone και έτσι το <pos x="+000" +y="+000"/> είναι τώρα child element του textzone ενώ πριν ήταν ανεξάρτητο node.
Μετά προσθέσαμε το </textzone> για να κλείσουμε το textzone node

Quote :
<define class="MyDeck" name="Deck"/>
<panel class="DeckLayoutA"/>
</define>

Ερώτηση 4: Αυτό το definition, δεν το κατανοώ! Μπορείς να μου το αναλύσεις σε παρακαλώ?

Κατ' αρχήν το define δεν ήταν ακριβώς έτσι. Έτσι όπως το γράφεις είναι περιττό.
Το define ήταν
<define class="MyDeck" name="Deck"/>
<panel class="DeckLayoutA"/>
<panel class="DeckLayoutB"/>
<panel class="DeckLayoutC"/>
<panel class="DeckLayoutD"/>
</define>

Αυτό στην ουσία είναι ένα panel που έχει μέσα του 4 διαφορετικά panel.
Δες αυτό το panel σαν ένα group από 4 panels. O λόγος που το κάνουμε define είναι για να κολλήσουμε τα 4 διαφορετικά layouts σε μία οντότητα, έτσι ώστε αργότερα να καλούμε αυτό το ΕΝΑ πάνελ κάθε φορά που θέλουμε να ζωγραφίσουμε ένα deck. Διαφορετικά θα έπρεπε να καλούμε τα 4 panels κάθε φορά που θέλουμε να ζωγραφίσουμε ένα deck (θα στο εξηγήσω και παρακάτω)

Quote :
<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1"><panel class="MyDeck" x="20" y="40"/></deck>
</panel>

Ερώτηση 5: Και εδώ δεν το κατανοώ! Μπορείς να μου το αναλύσεις σε παρακαλώ?

Εδώ πλέον ζωγραφίζουμε στο skin
Ζωγραφίζουμε ένα panel με το όνομα Deck1LeftDeck, και το ζωγραφίζουμε ΜΟΝΟ όταν το deck 1 είναι το leftdeck
Στη συνέχεια δηλώνουμε πως οτι υπάρχει μέσα σε αυτό το panel ανήκει στο deck 1
Τέλος λέμε οτι μέσα στο panel με όνομα Deck1LeftDeck (που είναι ορατό ΜΟΝΟ όταν το deck 1 είναι το leftdeck, και όλα του τα στοιχεία ανήκουν στο deck 1) θέλουμε να ζωγραφίσουμε το panel MyDeck. To panel MyDeck είναι η ομαδοποίηση των layouts που κάναμε παραπάνω.

Το
<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeck" x="20" y="40"/>
</deck>
</panel>

είναι ισοδύναμο με το

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="DeckLayoutA" x="20" y="40"/>
<panel class="DeckLayoutB" x="20" y="40"/>
<panel class="DeckLayoutC" x="20" y="40"/>
<panel class="DeckLayoutD" x="20" y="40"/>
</deck>
</panel>

το οποίο με τη σειρά του είναι ισοδύναμο με το

<panel name="Deck1LeftDeck" x="20" y="40" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="DeckLayoutA"/>
<panel class="DeckLayoutB"/>
<panel class="DeckLayoutC"/>
<panel class="DeckLayoutD"/>
</deck>
</panel>

που είναι ισοδύναμο με το

<panel name="Deck1LeftDeck" x="20" y="40" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeck"/>
</deck>
</panel>

που είναι ισοδύναμο με το

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<pos x="20" y="40" />
<deck deck="1">
<panel class="MyDeck"/>
</deck>
</panel>

που είναι ισοδύναμο με το

<panel name="Deck1LeftDeck" visible="deck 1 leftdeck">
<deck deck="1">
<panel class="MyDeck">
<pos x="20" y="40" />
</panel>
</deck>
</panel>

Quote :
Ερώτηση 6: Παίζει ρόλο ο τρόπος επιλογής, όσον αφορά στον κώδικα, ώστε να μπορώ να τον κάνω mapping και στον controller? Π.χ Εάν στον Denon MC6000MK2 αντιστοιχίσω το roll-button BEATS για αυτό το σκοπό, ενώ στο skin να αλλάζει μέσω menu, θα έχω ασυμβατότητα?

Όχι δεν θα έχεις καμία ασυμβατότητα.

Quote :

<textzone class="lbl_Elapsed" x="+6" y="+1"/>
<textzone class="lbl_Remain" x="+636" y="+1"/>
<textzone class="lbl_Tempo" x="+51" y="+91"/>
<textzone class="lbl_Pitch" x="+231" y="+91"/>
<textzone class="lbl_Key" x="+411" y="+91"/>
<textzone class="lbl_Gain" x="+591" y="+91"/>
<textzone class="lbl_Loop" x="+51" y="+151"/>
<textzone class="lbl_Pads" x="+231" y="+151"/>
<textzone class="lbl_Effects" x="+411" y="+151"/>
<textzone class="lbl_Sampler" x="+591" y="+151"/>

Εκτός κι αν άλλαξε κάτι στην skin engine πρόσφατα και δεν το αντιλήφθηκα, τα pos στα textzones πρέπει να γίνουν
<textzone class="lbl_Elapsed"><pos x="+6" y="+1"/></textzone>

Quote :
<define class="MyDeck" name="Deck"/><panel class="DeckLayoutA"/>
</define>

Και εδώ το XML formatting είναι λάθος
Πρέπει να γίνει
<define class="MyDeck" name="Deck"><panel class="DeckLayoutA"/>
</define>
 

Posted Mon 28 Jan 19 @ 8:14 am
PhantomDeejay wrote :

Εκτός κι αν άλλαξε κάτι στην skin engine πρόσφατα και δεν το αντιλήφθηκα, τα pos στα textzones πρέπει να γίνουν
<textzone class="lbl_Elapsed"><pos x="+6" y="+1"/></textzone>


Τελικά όντως έχει προστεθεί και στα textzones το override με attributes οπότε και το
<textzone class="lbl_Elapsed" x="+6" y="+1"/> είναι σωστό
 

Posted Mon 28 Jan 19 @ 3:08 pm
Όπως έχω αναφέρει και στο παρελθόν, ήταν εξαρχής επιθυμία μου το skin να έχει DayMode και NightMode επιλογή…

Αυτό, θεωρητικά, θα μπορούσε να επιτευχθεί με μία μεταβλητή, ώστε ανάλογα με την τιμή της, να αλλάζουν “αυτόματα” και τα όποια γραφικά και το χρώμα των όποιων αλφαβητικών ή αριθμητικών τιμών.

Το ερώτημα που θέτω, είναι ποιος είναι ο πλέον “ορθός” τρόπος, για να το υλοποιήσω.

Α. Μία σκέψη είναι να καταφέρω να διαχωρίσω τον κώδικα των definitions σε 2 μέρη. Το πρώτο μέρος θα αφορά μόνο στα γραφικά και το δεύτερο μέρος θα αφορά μόνο στις αλφαβητικές ή αριθμητικές τιμές.

Ξεκινώντας από τα γραφικά, αναφέρω ως απλό παράδειγμα το εξής:

<define class="btn_Exit" action="close">
<pos x="1885" y="5"/>
<size width="30" height="20"/>
<up x="1885" y="1105"/>
<over x="1675" y="1105"/>
<down x="1675" y="1105"/>
<tooltip>Exit</tooltip>
</define>

Ερώτηση A1: Θα μπορούσα στον εν λόγω κώδικα να προσθέσω μία μεταβλητή, ώστε ανάλογα με το Mode (Day / Night) να αλλάζει μόνο το <up…/>, <over…/>, <down…/> του element?
Ερώτηση A2: Εάν ναι, ποια θα έπρεπε να είναι η τελική σύνταξη?
Ερώτηση A3: Εάν ναι, τότε το συγκεκριμένο element οφείλει να συνταχθεί ως panel (panel class) πλέον ή εξακολουθεί να είναι ένα button (button class)?
Ερώτηση A4: Εάν υποθέσουμε ότι υλοποιείται το άνωθεν, τι γίνεται στην περίπτωση που έχουμε ένα απλό γραφικό (π.χ. ένα χρωματιστό screen, ως background ενός deck)? Διότι, το εν λόγω screen μπορεί εύκολα να οριστεί ως background ενός panel που αφορά στο deck. Αλλά, εάν επιθυμούμε να το απεικονίσουμε ξεχωριστά, ως αυτόνομο στοιχείο, δεν βρήκα τον τρόπο να το κάνω. Με άλλα λόγια, όταν έχω ένα μεμονωμένο και στατικό γραφικό (π.χ. μία γραμμή ή ένα πλαίσιο), πώς το ορίζω (definition) και πως το απεικονίζω (graphic class)?

Εφόσον υλοποιούνται τα άνωθεν, για τις αλφαβητικές ή αριθμητικές τιμές έχω ήδη παραδείγματα, οπότε και η υλοποίηση είναι εφικτή.


Β. Μία άλλη σκέψη, είναι σε κάθε definition, να συμπεριλαμβάνεται η μεταβλητή και για απόδοση των γραφικών και για την απόδοση των αλφαβητικών ή αριθμητικών τιμών.

Παράδειγμα:

<define class="Cpu">
<size width="120" height="20"/>
<pos x="+305" y="+6"/>
<up x="210" y="1105"/>
<textzone>
<size width="110" height="18"/>
<text font="Segoe UI" size="18" align="center" scroll="no" color="`param_bigger 0.75 get_cpu ? color '#ff00ff' : param_bigger 0.50 get_cpu ? color 'orange' : param_bigger 0.25 get_cpu ? color 'cyan' : color 'green'`" action="get_text 'CPU: `get_cpu & param_cast percentage & param_cast int_trunc`%'"/>
<tooltip>Cpu Usage</tooltip>
</textzone>
</define>

Στην συγκεκριμένη περίπτωση, απ’ την στιγμή κατά την οποία συμπεριλαμβάνω στο definition και το background της αλφαριθμητικής τιμής, αυτό (απ’ ότι κατέληξα, μέσω δοκιμών) παύει να είναι ένα <textzone class … /> και για να εμφανιστεί οφείλει να συνταχθεί πλέον ως <panel class … />

Ερώτηση B1: Γιατί στο συγκεκριμένο παράδειγμα δεν μου εμφανίζει το background (<size width="120" height="20"/><pos x="+305" y="+6"/><up x="210" y="1105"/>?
Ερώτηση B2: Θα μπορούσα στον εν λόγω κώδικα να προσθέσω μία μεταβλητή, ώστε ανάλογα με το Mode (Day / Night) να αλλάζει και το <up…/> και το color?
Ερώτηση B3: Εάν ναι, ποια θα έπρεπε να είναι η τελική σύνταξη αυτού του element?


Τέλος και ανεξαρτήτως των άνωθεν:

- Εάν επιθυμούμε την δημιουργία ενός πεδίου αλφαβητικής ή αριθμητικής τιμής, τότε ανακαλείται - απεικονίζεται με textzone class.
- Εάν επιθυμούμε την δημιουργία ενός κουμπιού, τότε ανακαλείται - απεικονίζεται με button class.
- Εάν επιθυμούμε την δημιουργία ενός πάνελ, τότε ανακαλείται - απεικονίζεται με panel class.

Πως, όμως, ανακαλούνται - απεικονίζονται μεμονωμένα άλλα elements, όπως π.χ. slider, knob, menu, ένα απλό graphic (π.χ. ένα led), κ.α.?
 

Posted Tue 29 Jan 19 @ 9:14 am
Κάπου μπερδεύεσαι ή μου φαίνεται;;;

Τα <button > δέχονται και child element <text>

<define class="Cpu">
<size width="120" height="20"/>
<pos x="+305" y="+6"/>
<up x="210" y="1105"/>
<text font="Segoe UI" size="18" width="110" height="18" dx="+5" dy="+1" align="center" scroll="no" color="`param_bigger 0.75 get_cpu ? color '#ff00ff' : param_bigger 0.50 get_cpu ? color 'orange' : param_bigger 0.25 get_cpu ? color 'cyan' : color 'green'`" action="get_text 'CPU: `get_cpu & param_cast percentage & param_cast int_trunc`%'"/>
<tooltip>Cpu Usage</tooltip>
</define>

Αυτό τώρα είναι button, και όχι panel (και μπορείς να δώσεις και action)

Επίσης πέρα από τα buttons, textzones και panels υπάρχουν και άλλα elements στη skin engine.
Έτσι για παράδειγμα τα sliders και knobs ζωγραφίζονται με το element <slider> http://www.virtualdj.com/wiki/Skin%20Slider.html
Τα "απλά led" απεικονίζονται είτε με button είτε με <visual> http://www.virtualdj.com/wiki/Skin%20SDK%20Visual.html
Τα μενού με <menu> http://www.virtualdj.com/wiki/Skin%20menu.html
κ.ο.κ.
Η πλήρης λίστα των elements βρίσκεται εδώ:
http://www.virtualdj.com/wiki/SkinSDK8.html

Άφησα για το τέλος την πιο δύσκολη ερώτηση.
Προσπαθείς να τρέξεις 1ΚΜ sprint (σχεδόν αδύνατο) πριν καλά-καλά καταφέρεις το 100στάρι κάτω από 20'' :P
Προσπάθειες για night/daylight mode έχουν κάνει πολλοί skiners συμπεριλαμβανομένου και εμού προσωπικά.
Όλοι καταλήξαμε οτι ο πιο εύκολος και πρακτικός τρόπος είναι να δημιουργήσεις 2 skins.
Εξηγώ:
Η αλλαγή των γραφικών στα κουμπιά (και γενικότερα) δεν μπορεί να γίνει με μεταβλητή. Αυτό σημαίνει οτι για κάθε κουμπί θα χρειαστείς 2 defines ένα για night και ένα για daylight mode. Αυτό από μόνο του σημαίνει διπλό κώδικα και διπλά γραφικά στο αρχείο PNG.
Οπότε:
Ο πιο εύκολος τρόπος είναι να δημιουργήσεις το night skin και όταν το τελειώσεις να δημιουργήσεις ένα αντίγραφο στο οποίο θα τροποποιήσεις τα γραφικά για daylight mode. Όσον αφορά τον κώδικα, μπορείς είτε να τροποποιήσεις το αντίγραφο, είτε να συγχωνεύσεις τις αλλαγές.
Γενικά στο daylight mode θα χρειαστείς εκτός από τα διαφορετικά γραφικά και διαφορετικό χρώμα στο κείμενο και τον browser.
Αυτό όπως έχεις καταλάβει ήδη μπορεί να γίνει με μεταβλητή.

Αν δεις προσεκτικά το skin που σου έστειλα για παράδειγμα, βασίζεται σε αυτή την ιδέα.
Όλα τα κείμενα, visuals, κτλ. ελέγχουν μια μεταβλητή για το χρώμα τους. Όταν το night mode τελειώσει, τότε το μόνο που θα μένει για να υπάρξει το daylight mode θα είναι η επεξεργασία των χρωμάτων του αρχείου PNG
Για τα κουμπιά κτλ στον κώδικα XML δεν χρειάζεται να προσθέσεις/πειράξεις κάτι καθώς αυτά διαβάζουν τα γραφικά τα οποία στο daylight θα βρίσκονται στην ίδια θέση με το ίδιο μέγεθος, αλλά με διαφορετικό χρώμα!

Σημείωση: Στο VirtualDJ8 μπορείς να αλλάζεις skins και variations μέσω VDJScript. Αυτό σημαίνει οτι με ένα κουμπί στο skin σου μπορείς να κάνεις εναλλαγή από day σε night και αντίστροφα, χωρίς να χρειάζεται να ανοίξεις την καρτέλα των ρυθμίσεων και να επιλέξεις το skin χειροκίνητα.
 

Posted Tue 29 Jan 19 @ 10:06 am
PhantomDeejay wrote :
Κάπου μπερδεύεσαι ή μου φαίνεται;;;
Δεν μπερδεύομαι, έχω πνιγεί!!! Γιατί ναι μεν η γνώση Html και Photoshop με βοήθησε αρκετά, αλλά απ' την στιγμή που δεν είμαι προγραμματιστής δε και μέχρι να μπω πλήρως στην "φιλοσοφία" του κώδικα δημιουργίας skin, έχω πιει ολόκληρη την θάλασσα... :-)

PhantomDeejay wrote :
Τα <button > δέχονται και child element <text>
<define class="Cpu">
<size width="120" height="20"></size>
<pos x="+305" y="+6"></pos>
<up x="210" y="1105"></up>
<text font="Segoe UI" size="18" width="110" height="18" dx="+5" dy="+1" align="center" scroll="no" color="`param_bigger 0.75 get_cpu ? color '#ff00ff' : param_bigger 0.50 get_cpu ? color 'orange' : param_bigger 0.25 get_cpu ? color 'cyan' : color 'green'`" action="get_text 'CPU: `get_cpu & param_cast percentage & param_cast int_trunc`%'"></text>
<tooltip>Cpu Usage</tooltip>
</define>

Αυτό τώρα είναι button, και όχι panel (και μπορείς να δώσεις και action)
Τότε και σύμφωνα με τα γραφόμενά σου, το "button" δεν είναι απαραίτητα ένα "κουμπί", αλλά γενικότερα ένα graphic! Σωστά? Εάν ναι, γιατί δεν δόθηκε εξαρχής το όνομα graphic, ώστε να μην χρειαζόμουν ναυαγοσώστη?

PhantomDeejay wrote :
Επίσης πέρα από τα buttons, textzones και panels υπάρχουν και άλλα elements στη skin engine.
Έχω δει - μελετήσει όλες τις παραπομπές σου. Το "πρόβλημα" είναι ότι σχεδόν (όχι σε όλα) σε κάθε element που αναλύεται, "λείπουν" 2 βασικά στοιχεία: 1. Ένα απλό παράδειγμα, για το πως το συντάσσεις ως definition και 2. Ένα απλό παράδειγμα, για το πως το συντάσσεις, ώστε να το "ανακαλείς" - προβάλεις στο skin.

PhantomDeejay wrote :
Προσπαθείς να τρέξεις 1ΚΜ sprint (σχεδόν αδύνατο) πριν καλά-καλά καταφέρεις το 100στάρι κάτω από 20'' :P
Σε αυτό που λες, έχεις απόλυτο δίκιο! Αλλά, προσπαθώ να αποφύγω το γράψιμο "αχρείαστου" κώδικα! Και εξηγώ:
Όταν ξεκίνησα την δημιουργία του skin και εφόσον μελέτησα - κατανόησα κάποια βασικά πράγματα, άρχισα (άμεσα, ως ενθουσιασμένος) να γράφω τα definitions ξεχωριστά και για οτιδήποτε.
Κατόπιν συνειδητοποίησα την ικανότητα πράξεων επί των συντεταγμένων! Διορθώσεις στον κώδικα...
Κατόπιν συνειδητοποίησα την χρησιμότητα των groups! Κι άλλες διορθώσεις στον κώδικα...
Κατόπιν συνειδητοποίησα την χρησιμότητα των panels! Κόντρα διορθώσεις στον κώδικα...

Τελικά ο κώδικάς μου έχει (μέχρι στιγμής) 701 σειρές, που βέβαια δεν είναι τίποτε μπρος στις 9980 σειρές του δικού σου, αλλά να είσαι σίγουρος ότι συνολικά έχω γράψει πάνω από 10.000 σειρές. Οπότε για να μην γράφω - σβήνω, προσπαθώ να εξηγήσω εξ' αρχής τι ακριβώς θέλω να κάνω, ώστε (εξαρχής) να μου δοθεί ο σωστός τρόπος...

PhantomDeejay wrote :
Στο VirtualDJ8 μπορείς να αλλάζεις skins και variations μέσω VDJScript. Αυτό σημαίνει οτι με ένα κουμπί στο skin σου μπορείς να κάνεις εναλλαγή από day σε night και αντίστροφα, χωρίς να χρειάζεται να ανοίξεις την καρτέλα των ρυθμίσεων και να επιλέξεις το skin χειροκίνητα.
Συνεπώς, η καλύτερη - τελική λύση ποια είναι: 1 xml αρχείο και 2 png?
 

Posted Tue 29 Jan 19 @ 10:51 am
Αν κατάλαβα καλά, αυτό που σε μπερδεύει τελικά είναι τα definitions

Ας το ξεκαθαρίσουμε λοιπόν.

Τα defines είναι η δημιουργία μιας "συντόμευσης" προς ένα element την οποία συντόμευση την καλείς μετά όσες φορές θέλεις χωρίς να ξαναγράφεις τα ίδια και τα ίδια.

Έτσι λοιπόν οποιοδήποτε element μπορεί να γίνει define με 2 απλά βήματα.

Ας πάρουμε για παράδειγμα το button example της Wiki

<button action="loop" rightclick="loop_select" visibility="deck 1 leftdeck">
<Tooltip>Click to enable-disable the selected loop\nRight-click to select a loop length</Toolip>
<pos x="12" y="300" width="49" height="39"/>
<off x="+0" y="1130"/>
<on x="+0" y="1130+50"/>
<over x="62" y="1130+50"/>
<down x="+0" y="1172"/>
<text size="16" weight="bold" color="#e1e1e1" align="center" format="%loop"/>
</button>

Για να το κάνεις define
1) Αλλάζεις το element από button σε define
2) Δίνεις ένα όνομα στην συντόμευση σου χρησιμοποιώντας το class="Όνομα Συντόμευσης"

<define class="MyShortcut" action="loop" rightclick="loop_select" visibility="deck 1 leftdeck">
<Tooltip>Click to enable-disable the selected loop\nRight-click to select a loop length</Toolip>
<pos x="12" y="300" width="49" height="39"/>
<off x="+0" y="1130"/>
<on x="+0" y="1130+50"/>
<over x="62" y="1130+50"/>
<down x="+0" y="1172"/>
<text size="16" weight="bold" color="#e1e1e1" align="center" format="%loop"/>
</define>

Προαιρετικά μπορείς να ορίσεις και classdeck.
To classdeck απλά λέει στην συντόμευση που έχεις φτιάξει οτι ισχύει μόνο για συγκεκριμένο deck

Με αυτό τον τρόπο, τα ΠΑΝΤΑ στην skin engine μπορούν να γίνουν define. Ο τρόπος ΔΕΝ αλλάζει από element σε element.

Τώρα, πως καλούμε τα defines (τις συντομεύσεις μας) όταν τις χρειαζόμαστε;

ΑΠΛΑ:
Γράφουμε το element και μετά το όνομα του. Δηλαδή για το παράδειγμα μας:
<button class="MhShortcut"/>

To ίδιο ισχύει για όλα τα elements.

Π.χ.:

Έστω οτι έχουμε το element equalizer:
<equalizer type="horizontal" nb="96" color="#007fff" width="0.6" slow="false" bass="left" mirror="true" canstretch="true">
<pos x="+475" y="+165+55"/>
<size width="475" height="60" />
</equalizer>

Για να το κάνουμε define

1. Αλλάζουμε το equalizer σε define:
<define type="horizontal" nb="96" color="#007fff" width="0.6" slow="false" bass="left" mirror="true" canstretch="true" >
<pos x="+475" y="+165+55"/>
<size width="475" height="60" />
</define>

2. Δίνουμε όνομα:
<define class="eq_DeckEq" type="horizontal" nb="96" color="#007fff" width="0.6" slow="false" bass="left" mirror="true" canstretch="true" >
<pos x="+475" y="+165+55"/>
<size width="475" height="60" />
</define>

Τελειώσαμε!

Τώρα όταν το θέλουμε να το τοποθετήσουμε κάπου στο skin γράφουμε απλά το element και το όνομα του.
Δηλαδή:
<equalizer class="eq_DeckEq"/>


Τέλος, προγραμματισμό (σε οποιαδήποτε γλώσσα) χωρίς σβήσε/γράψε δεν μαθαίνεις... :P Και αν εσύ για 700 γραμμές έχεις γράψει 10.000, φαντάσου πόσες έγραψα εγώ για τις 10.000 δικές μου... :P (Ναι, κι εγώ σβήνω και ξαναγράφω και ξανασβήνω κ.ο.κ)

Quote :

Τότε και σύμφωνα με τα γραφόμενά σου, το "button" δεν είναι απαραίτητα ένα "κουμπί", αλλά γενικότερα ένα graphic! Σωστά? Εάν ναι, γιατί δεν δόθηκε εξαρχής το όνομα graphic, ώστε να μην χρειαζόμουν ναυαγοσώστη?

Όχι, το κουμπί είναι κουμπί. Το αν εσύ το χρησιμοποιήσεις και για άλλους λόγους, αυτό είναι δικό σου θέμα. Δεν είναι "graphic" αλλά κουμπί γιατί ο χρήστης μπορεί να κάνει click πάνω του. Και γιατί ακόμα και χωρίς εντολή το κουμπί είναι... κουμπί και πατιέται! Αλλάζει γραφικά στο over, στο down κτλ
Για απλά γραφικά το VirtualDJ έχει τα visual που είναι σαφώς καλύτερος ορισμός.

Quote :
Συνεπώς, η καλύτερη - τελική λύση ποια είναι: 1 xml αρχείο και 2 png?

Τεχνικά, 2 αρχεία XML και δύο αρχεία PNG.
Πρακτικά το 2ο αρχείο XML μπορεί να είναι ένα απλό Save As του πρώτου εφόσον όμως φτιάξεις τον κώδικα έτσι (κάτι που ακούγεται απλό αλλά είναι λίγο πιο πολύπλοκο)
 

Posted Tue 29 Jan 19 @ 2:30 pm
Ωραία... Ας κάνω λοιπόν μία σύνοψη και διορθώνεις ή συμπληρώνεις όπου απαιτείται...

Στην περιοχή του skin, πάνω από τον Browser, έχω συνήθως (κατά περίπτωση και περίσταση):

1. Κείμενα (στατικά ή μεταβλητά).
2. Τιμές (στατικές ή μεταβλητές).
3. Γραφικά (στατικά ή μεταβλητά).

Για την περίπτωση των κειμένων, τα συμπεράσματά μου είναι:
1.1. Συντάσσονται με: <text ... ... .../> και απεικονίζονται με <textzone class ... ... .../>
1.2. Τα κείμενα δεν μπορούν να έχουν δικό τους (ανεξάρτητο του γενικού) γραφικό background. Άρα, εάν απαιτείται να έχουν δικό τους γραφικό background, τότε αυτό θα πρέπει να έχει ήδη ορισθεί, είτε μέσω του panel ή του windows (που ανήκουν), είτε μέσω άλλου τρόπου που μου διαφεύγει.

Για την περίπτωση των τιμών, τα συμπεράσματά μου είναι τα ίδια.

Για την περίπτωση των γραφικών, τα συμπεράσματά μου είναι:
3.1. Υφίσταται το square/circle (new element VDj 2018), μέσω του οποίου μπορούν να δημιουργηθούν απλά γραφικά, τα οποία δεν υφίστανται στο png αρχείο
3.2. Υφίσταται μία ομάδα γραφικών, τα οποία έχουν την δική τους "ιδιαίτερη" σύνταξη. Αυτά είναι: rhythmzone, songpos, scratchwave.
3.3. Υφίστανται τα buttons. Η σύνταξη είναι παρόμοια με αυτή των texts, αλλά με πολύ περισσότερες παραμέτρους - δυνατότητες και απεικονίζονται με <button class ... ... .../>.
3.3.1. Τα buttons δύναται να "περιέχουν", είτε άλλα γραφικά (icons), είτε κείμενα - τιμές (texts).
3.3.2. Τα buttons δύναται να έχουν δικό τους (ανεξάρτητο του γενικού) γραφικό background, το οποίο ορίζεται μέσω του σχετικού κώδικα.
3.4. Υφίστανται τα sliders. Τα sliders είναι ουσιαστικά buttons, τα οποία ολισθαίνουν (faders) ή περιστρέφονται (knobs).
3.5. Υφίστανται τα visuals. Τα visuals είναι μεταβλητά γραφικά, τα οποία αλλάζουν αναλόγως κάποιας παραμετρικής τιμής.

Εάν μέχρι εδώ είμαι ορθός, τότε προκύπτουν τα ακόλουθα ερωτήματα επί των άνωθεν:

1. Εάν έχουμε ένα "σκέτο" και στατικό γραφικό, το οποίο δεν "ανήκει" σε κάποιο panel ή window ή οτιδήποτε άλλο και θέλουμε να εμφανίζεται απλά στο skin. Ποια είναι η ορθότερη επιλογή ορισμού , ως visual, ως button (μόνο με ορισμό up), ως τί?

2. Εάν έχουμε text, το οποίο έχει το δικό του στατικό background. Ποια είναι η ορθότερη επιλογή ορισμού , ώστε να συμπεριλάβουμε το background στο definition? Ως visual, ως button (μόνο με ορισμό up), ως ένα μικρό panel, ως τί?

3. Εάν έχουμε value, η οποία έχει το δικό της μεταβλητό background (π.χ. το background είναι πράσινο υπό μία συγκεκριμένη τιμή και κόκκινο, υπό μία άλλη συγκεκριμένη τιμή). Ποια είναι η ορθότερη επιλογή ορισμού σε αυτή την περίπτωση? Ή αυτό δεν γίνεται, με τον τρόπο τον οποίο αναφέρω?

Παράδειγμα: Έστω ότι έχουμε το outline ενός deck, το οποίο αναλόγως του deck number, αλλάζει χρώμα.
Θα πρέπει λοιπόν να συντάξουμε ένα definition, το οποίο να "λέει" ότι: Εάν το deck left είναι το deck 1, τότε θα πρέπει το background να είναι το ορθογώνιο, μπλε περιγράματος και κενού "γεμίσματος", με συντεταγμένες x=a και y=b (επί του png αρχείου). Εάν το deck left είναι το deck 3, τότε θα πρέπει το background να είναι το ορθογώνιο, πράσινου περιγράματος και κενού "γεμίσματος", με συντεταγμένες x=c και y=d (επί του png αρχείου).
Αυτό το definition, στη ουσία τί είναι? Ένα panel?
 

Posted Tue 29 Jan 19 @ 7:37 pm
1. Τα κείμενα μπορούν να είναι είτε ανεξάρτητα οπότε χρησιμοποιείς το <textzone> είτε μέρος ενός άλλου element όπως το button οπότε έχεις child <text> στο αντικείμενο αυτό.

2. Τα κείμενα είναι εξ' ορισμού διάφανα. Δηλαδή το VirtualDJ γράφει μόνο το κείμενο σε οτι υπάρχει από κάτω. Το πως βρίσκονται τα γραφικά από κάτω (από που προέρχονται) ποσώς το ενδιαφέρει.

3. Κακώς διαχωρίζεις (στο τεχνικό κομμάτι) τα "κείμενα" από τις "τιμές" Και τα δύο για το πρόγραμμα είναι κείμενα.

4. Τα buttons είναι βασικό element της skin engine. Τα buttons μπορούν να χρησιμοποιηθούν για ΠΑΡΑ ΠΟΛΛΑ πράγματα, αλλά έχουν και περιορισμούς. (περισσότερα παρακάτω)

Με αυτές τις διευκρινίσεις πάμε παρακάτω:
Quote :
1. Εάν έχουμε ένα "σκέτο" και στατικό γραφικό, το οποίο δεν "ανήκει" σε κάποιο panel ή window ή οτιδήποτε άλλο και θέλουμε να εμφανίζεται απλά στο skin. Ποια είναι η ορθότερη επιλογή ορισμού , ως visual, ως button (μόνο με ορισμό up), ως τί?

Χμμμμ. Για να σκεφτώ... έχουμε ένα γραφικό που δεν ανήκει κάπου... Ώπα!
Πως δεν ανήκει κάπου;;; Τα πάντα ανήκουν κάπου αλλιώς δεν "ζωγραφίζονται". Το κατώτερο επίπεδο (πάνω στο οποίο ζωγραφίζονται όλα τα άλλα) είναι το background του skin. Οπότε οτι ζωγραφίσεις εκεί θα εμφανίζεται πάντα, αρκεί να μην πέσει κάτι άλλο από πάνω του.
Αν θεωρήσουμε οτι το γραφικό αυτό δεν θέλουμε να είναι στο background του skin και να εμφανίζεται πάντα, αλλά να εμφανίζεται "σχεδόν πάντα" τότε αυτό το γραφικό ανήκει σε κάτι. Όχι τεχνικά, αλλά λογικά! Δηλαδή ανήκει σε κάποιο λογικό στοιχείο που με κάποιο τεχνικό τρόπο θα το απεικονίσουμε στο skin.
Τεχνικά οι τρόποι να ζωγραφίσεις μια στατική εικόνα στο skin είναι:
1. Σαν background στο skin (κατώτατο επίπεδο)
2. Σαν background ενός panel
3. Σαν background ενός button
4. Σαν background ενός slider
5. Σαν visual.
Κάθε τρόπος έχει τα υπέρ και τα κατά του. Εφόσον θέλουμε απλά να δείξουμε κάτι (έστω οτι θέλουμε να βάλουμε την φωτογραφία μας πίσω από τον browser) τότε οι προτιμώμενοι τρόποι είναι ο 1, ο 2 και ο 5.
Γενικά αποφεύγουμε να δείχνουμε εικόνα σαν background ενός button/slider κτλ αν δεν χρειαζόμαστε την λειτουργικότητα του button/slider κτλ
Ο βασικός λόγος που το αποφεύγουμε είναι το transparency και το click through.
Και εξηγώ: Αν θες να ζωγραφίσεις μια ορθογώνια εικόνα, τότε το button μπορεί να χρησιμοποιηθεί με μια σχετική ασφάλεια, καθώς είναι ένα ορθογώνιο element.
Τι γίνεται όμως αν θες να ζωγραφίσεις ένα "πολύπλοκο" σχήμα (έστω ένα ισόπλευρο τρίγωνο); Σαφώς και στο button μπορείς να ορίσεις μια περιοχή με transparency και να δείξεις το γραφικό σου. Όμως το button είναι ορθογώνιο. Αυτό σημαίνει οτι σε όλη του την έκταση (τόσο αυτή που είναι βαμμένη όσο και στην διάφανη) το button κάνει "capture" τα mouse clicks και δεν τα αφήνει να περάσουν παρακάτω. Αυτό σημαίνει οτι αν πίσω από την "διάφανη" περιοχή του τριγώνου που έδειξες με button έχεις άλλα buttons, δεν θα μπορείς να τα κάνεις click! Για να μπορέσεις να κάνεις click θα πρέπει να ορίσεις και mousemask, δηλαδή extra δουλειά...
Σαφώς και αν το τρίγωνο πρέπει να κάνει κάτι όταν το κάνεις click η λύση είναι το button με mousemask, αλλά αν το τρίγωνο είναι διακοσμητικό, γιατί να μπεις στη φασαρία να φτιάξεις mousemask ?
Αν το γραφικό που θες να δείξεις είναι το background ενός "group" στοιχείων, τότε η προτιμότερη λύση είναι να το βάλεις σαν background ενός panel αφού ούτως ή άλλως θα χρησιμοποιήσεις panel για να ομαδοποιήσεις τα στοιχεία (και πιθανότατα για να τα δείξεις ή να τα κρύψεις από την οθόνη)
Τέλος αν το γραφικό είναι απλά "ξεκάρφωτο" τότε η προτιμότερη λύση είναι το <visual>

<visual type="onoff" source="on">
<size width="475" height="63"/>
<pos x="+0" y="+0"/>
<on x="0" y="1830"/>
<tooltip />
</visual>

Απ' οτι βλέπεις ο ορισμός του είναι πολύ απλός. Και με define γίνεται:

<define class="vis_MyPhoto" type="onoff" source="on">
<size width="475" height="63"/>
<pos x="+0" y="+0"/>
<on x="0" y="1830"/>
<tooltip />
</define>

<visual class="vis_MyPhoto"/>

Quote :
2. Εάν έχουμε text, το οποίο έχει το δικό του στατικό background. Ποια είναι η ορθότερη επιλογή ορισμού , ώστε να συμπεριλάβουμε το background στο definition? Ως visual, ως button (μόνο με ορισμό up), ως ένα μικρό panel, ως τί?

3. Εάν έχουμε value, η οποία έχει το δικό της μεταβλητό background (π.χ. το background είναι πράσινο υπό μία συγκεκριμένη τιμή και κόκκινο, υπό μία άλλη συγκεκριμένη τιμή). Ποια είναι η ορθότερη επιλογή ορισμού σε αυτή την περίπτωση? Ή αυτό δεν γίνεται, με τον τρόπο τον οποίο αναφέρω?

Θα σου απαντήσω και στα δύο ταυτόχρονα:
Τα κείμενα ΔΕΝ έχουν background. Οπότε το background θα προέρχεται από κάπου αλλού. Το από που, εξαρτάται από το σχεδιασμό του skin.
Οπότε για στατικό background δες οτι σου έγραψα και παραπάνω για τα γραφικά.
Για δυναμικό τα πράγματα είναι περίπου τα ίδια, μόνο που εδώ το visual μπορεί να σε βοηθήσει περισσότερο

<visual type="onoff" source="param_bigger 0.5 get_cpu">
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<on x="0" y="1830"/>
<off x="0+60" y="1830"/>
<tooltip />
</visual>
<textzone>
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<text action="get_cpu"/>
</visual>

Εδώ ζωγραφίζουμε ένα γραφικό με τη βοήθεια του visual (άλλο γραφικό αν η CPU είναι κάτω από 50% και άλλο αν είναι πάνω από 50%) και αμέσως μετά ακριβώς από πάνω ζωγραφίζουμε και το κείμενο
Μπορείς να τα κάνεις define και να τα καλείς σαν δύο elements ή μπορείς να τα κάνεις και πάνελ

<define class="vis_CPUBG" type="onoff" source="param_bigger 0.5 get_cpu">
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<on x="0" y="1830"/>
<off x="0+60" y="1830"/>
<tooltip />
</define>
<define class="txt_CPUVal">
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<text action="get_cpu"/>
</define>

<visual class="vis_CPUBG"/>
<textzone class="txt_CPUVal"/>

Αλλά και:

<define class="pnl_CPU"
<visual type="onoff" source="param_bigger 0.5 get_cpu">
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<on x="0" y="1830"/>
<off x="0+60" y="1830"/>
<tooltip />
</visual>
<textzone>
<size width="60" height="20"/>
<pos x="+0" y="+0"/>
<text action="get_cpu"/>
</textzone>
</define>

<panel class="pnl_CPU"/>


Quote :
Παράδειγμα: Έστω ότι έχουμε το outline ενός deck, το οποίο αναλόγως του deck number, αλλάζει χρώμα.
Θα πρέπει λοιπόν να συντάξουμε ένα definition, το οποίο να "λέει" ότι: Εάν το deck left είναι το deck 1, τότε θα πρέπει το background να είναι το ορθογώνιο, μπλε περιγράματος και κενού "γεμίσματος", με συντεταγμένες x=a και y=b (επί του png αρχείου). Εάν το deck left είναι το deck 3, τότε θα πρέπει το background να είναι το ορθογώνιο, πράσινου περιγράματος και κενού "γεμίσματος", με συντεταγμένες x=c και y=d (επί του png αρχείου).
Αυτό το definition, στη ουσία τί είναι? Ένα panel?

Ναι, στο 99% των περιπτώσεων είναι panel. Μπορεί να γίνει και με visual, αλλά από τη στιγμή που το panel θα το χρησιμοποιήσεις ούτως ή άλλως γιατί θα αλλάζεις το deck που ζωγραφίζεις την οθόνη, είναι προτιμότερο να το κάνεις με panel
 

Posted Tue 29 Jan 19 @ 9:47 pm
Υπέροχα!!! "Τυχερή" η Atomix που σε έχει συνεργάτη...

Πριν πάω παρακάτω, 2 διευκρινήσεις:

#1. Είχες αναφέρει κάποτε ότι το όποιο skin "βαραίνει" και από τον αριθμό των panels που διαθέτει. Οπότε ρωτώ: Όπου το visual εξυπηρετεί επ' ακριβώς αυτό που θέλουμε να κάνουμε (αναφέρομαι σε στατικό γραφικό, όπως π.χ. ένα background ενός text), είναι προτιμότερο να χρησιμοποιούμε αυτό ή να χρησιμοποιούμε το panel (και ας μην πρόκειται ουσιαστικά για panel)?

#2. Χρησιμοποιώντας το visual και την παράμετρο type="onoff", ουσιαστικά έχεις τον περιορισμό μεταξύ 2 εναλλαγών γραφικών: 1 για το on και 1 για το off. Σωστά? Εάν ναι, τότε στην περίπτωση που επιθυμούμε και 3 εναλλαγή background, τι γίνεται?


Πάω τώρα στο θέμα του panel. Κάνω λοιπόν μία σύνοψη και διορθώνεις ή συμπληρώνεις όπου απαιτείται...

Χρησιμοποιώντας το panel, ορίζουμε μία περιοχή, η οποία περιλαμβάνει μία ομάδα στοιχείων και ένα ξεχωριστό background. Τα βασικά πλεονεκτήματα του όποιου panel, είναι ότι:
Α. Η περιοχή αυτή δύναται να εμφανίζεται ή όχι, κατ' επιλογήν.
Β. Μπορούμε να ορίσουμε ένα διαφορετικό - ξεχωριστό background αυτού.
C. Μπορούμε να ορίσουμε τις γενικές συντεταγμένες του panel, τις σχετικές συντεταγμένες των elements που περιέχει και αλλάζοντας τις γενικές συντεταγμένες, να αλλάζει κατ' αντιστοιχία και αναλογία, η θέση όλων των elements.

#3. Όλες οι παράμετροι του panel κατανοητές, πλην της: <clipmask x="" y="">. Μπορείς να την αναλύσεις, σε παρακαλώ?

Ας δούμε λίγο και το θέμα της σύνταξης...

Ξεκινάω από τον ορισμό του:

<define class="pnl_A">
<element1/>
<element2/>
<element3/>
</define>

Και η "ανάκλησή" του (για να εμφανιστεί):

<panel class="pnl_A"/>

Ας το κάνω λίγο πιο σύνθετο, επί του ορισμού του:

<define class="pnl_A" visible="yes"> Ώστε να εμφανίζεται όταν ανοίγει το πρόγραμμα...
<size width="111" height="111"> Ορίζω το μέγεθός του...
<pos x="222" y="222"> Ορίζω τις γενικές συντεταγμένες, όπου θα εμφανίζεται επί του skin...
<down x="333" y="333"> Ορίζω ουσιαστικά το background του...
<up x="" y=""> Ορίζω ουσιαστικά το background της περιοχής του, όταν αυτό δεν εμφανίζεται ...
<element1 x="+10" y="+20"/> Ορίζω τις σχετικές συντεταγμένες του element, ως προς τις γενικές συντεταγμένες του panel...
<element2 x="+20" y="+30"/> Ορίζω τις σχετικές συντεταγμένες του element, ως προς τις γενικές συντεταγμένες του panel...
<element3 x="+30" y="+40"/> Ορίζω τις σχετικές συντεταγμένες του element, ως προς τις γενικές συντεταγμένες του panel...
</define>

#4. Η παράμετρος <up x="" y="">, όταν το panel αντικαθίσταται πάντα από κάποιο άλλο (άρα δεν υπάρχει η περίπτωση "κενού"), είναι υποχρεωτική στην σύνταξη ή όχι?

Πάμε τώρα στα πιο "σύνθετα"...

#5. Έστω ότι το panel περιέχει elements (π.χ. texts), τα οποία αφορούν γενικές πληροφορίες και όχι πληροφορίες των Decks. Εάν θελήσω να το αναπαράγω και σε άλλο σημείο του skin, τι κάνω?

Περίπτωση I:
<panel class="pnl_A"/>
<panel class="pnl_A" x="444" y="444/> Override τις αρχικές - γενικές συντεταγμένες...
Περίπτωση II:
<panel class="pnl_A" x="222" y="222"/> Στο αρχικό panel δεν αναφέρω τις γενικές συντεταγμένες (<pos x="222" y="222">) του, αλλά τις ορίζω μόνο στην "ανάκληση"...
<panel class="pnl_A" x="444" y="444"/> Στο αντίγραφο panel ορίζω τις δικές του συντεταγμένες στην "ανάκληση"...

#6. Έστω ότι το panel περιέχει elements (π.χ. values), τα οποία αφορούν πληροφορίες των Decks (π.χ. bpm του κομματιού). Εάν θελήσω να το αναπαράγω και σε άλλο σημείο του skin, τι κάνω?
Εδώ, όπως γίνεται κατανοητό, δεν τίθεται μόνο θέμα αλλαγής συντεταγμένων κατά την ανάκληση. Θα πρέπει όλες οι τιμές στο αρχικό panel να αφορούν π.χ. το Deck 1 και όλες οι τιμές στο αντίγραφο panel να αφορούν στο Deck 2. Πως, λοιπόν, αλλάζει ο κώδικας, ώστε να επιτύχω την διαφοροποίηση αυτή?

Και τέλος (γιατί θα φάω ξύλο, εάν συνεχίσω...):

#7. Εάν επιθυμούμε το panel να εναλλάσσεται (pnl_A & pnl_B) ξεχωριστά για κάθε Deck, μέσω π.χ. ενός button του, ποια είναι η ορθή διαδικασία που θα πρέπει να ακολουθήσω?
 

Posted Wed 30 Jan 19 @ 7:20 am
1. Για ένα σκέτο-νέτο γραφικό, το visual
Επίσης το φαντάστηκα οτι η απέχθεια σου προς τα panel μπορεί να οφείλεται σ' αυτό που είχα αναφέρει παλιότερα, αλλά αν θυμάσαι καλά, μίλησα για τεράστιο αριθμό panel. Στο SilverSleek 2 πρέπει να υπάρχουν περισσότεροι από 100.000 συνδυασμοί panels. Κάποια στιγμή είχαν φτάσει σχεδόν τις 200.000 κι εκεί παρατηρήσαμε για πρώτη φορά οτι το skin αργούσε λίγο περισσότερο να φορτώσει από το αναμενόμενο. Βέβαια δεν φταίνε τα panels αυτά καθ' αυτά, αλλά και το γεγονός οτι σχεδόν όλα ήταν conditional που σημαίνει οτι το πρόγραμμα έπρεπε να υπολογίσει όλους τους πιθανούς συνδυασμούς πριν αρχίσει να ζωγραφίζει στην οθόνη.
Με απλά λόγια, αν δεν πρόκειται να φτιάξεις ένα skin με την πολυπλοκότητα του SilverSleek ή του V8 by Fruit, τότε δεν χρειάζεται να ανησυχείς για τις επιδόσεις του skin και την επιβάρυνση από τα panels.
Και για την ιστορία, αλλάζοντας ελαφρώς τον τρόπο που ζωγραφίζονταν στην οθόνη 3 πράγματα, από τα 200.000 panels πέσαμε στα 100.000 ;)

2. Μπορείς να το κάνεις με <visual type="custom"> αλλά με κάποιους περιορισμούς. Διαφορετικά με panels

3. To <clipmask> όπως και το <mousemask> είναι children άλλων elements. Αυτό που κάνουν είναι οτι δίνεις μια περιοχή στο skin με ασπρόμαυρα γραφικά και το πρόγραμμα εμφανίζει το element όπου βλέπει μαύρο χρώμα, και το κρύβει όπου βλέπει άσπρο. Το ίδιο ισχύει και για το mousemask. Όπου το πρόγραμμα βλέπει μαύρο δέχεται click για το element και όπου άσπρο όχι.
Αυτά τα 2 children είχαν δημιουργηθεί κυρίως για τις ανάγκες των skins πριν την έκδοση 8 που δεν υποστηριζόταν αρχεία PNG και transparency. Πλέον τα δύο αυτά children δεν χρησιμοποιούνται συχνά. ΔΕΝ είναι deprecated, αλλά λόγω του transparency είναι λίγες πλέον οι φορές που πρακτικά τα χρειάζεσαι (συνήθως όταν βάζεις jogs στο skin ή rotating covers κτλ

4.Όχι. Και το up και το down είναι προαιρετικά. Ένα panel δεν είναι απαραίτητο καν να έχει down δηλαδή μπορεί το ίδιο το panel να είναι διάφανο. Επίσης ένα panel μπορεί να μην έχει διαστάσεις. Το up/down και οι διαστάσεις ήταν απαραίτητα σε παλιότερες εκδόσεις του VirtualDJ (Από το 7 και πίσω)

5. Σωστά

6. Μπορείς είτε να ορίσεις deck στην ανάκληση, είτε να βάλεις όλα τα panels του deck μέσα στο special container <deck>
<panel class="pnl_A" deck="1" x="222" y="222"/>
<panel class="pnl_A" deck="2" x="222+333" y="222"/>

ή

<deck deck="1"><panel class="pnl_A" x="222" y="222"/></deck>
<deck deck="2"><panel class="pnl_A" x="222+333" y="222"/></deck>

7. Στο έγραψα και παραπάνω. Ο καλύτερος τρόπος πλέον είναι με μία μεταβλητή τύπου '@VarControlName'
 

Posted Wed 30 Jan 19 @ 8:06 am
Απολύτως κατανοητά! Πριν προχωρήσω στο ιδιαίτερο θέμα των μεταβλητών (variables), θα εξάγω κάποια συμπεράσματα (με συμπληρώνεις ή διορθώνεις όπου απαιτείται) και θα κάνω κάποιες σχετικές ερωτήσεις...

Α. Στο όποιο skin υφίστανται διάφορα γραφικά.

Α1. Τα γραφικά μπορούμε, είτε να τα σχεδιάσουμε απ' ευθείας στο background ("μόνιμα" γραφικά), είτε να τα σχεδιάσουμε κάτω από το βασικό background του png αρχείου και κατόπιν τα "μεταφέρουμε" στην επιθυμητή θέση και τρόπο εμφάνισης μέσω κατάλληλου κώδικα ("μεταφερόμενα" γραφικά), είτε συνδυασμός των άνωθεν.

Α2. Τα όποια γραφικά, διαχωρίζονται σε 3 κατηγορίες:
α΄) Αυτά τα οποία είναι στατικά, κοινώς αμετάβλητα ως προς την μορφή τους (π.χ. ένα πλαίσιο). Σε αυτή την περίπτωση, ο "προτιμότερος" (αλλά όχι μοναδικός) τρόπος απεικόνισης στο skin, είναι η χρήση του element visual.
β΄) Αυτά τα οποία είναι μεταβλητά, κοινώς μεταβάλλονται ως προς την μορφή τους, αναλόγως κάποιας τιμής (π.χ. ένα vu meter). Σε αυτή την περίπτωση, ο "μοναδικός" τρόπος απεικόνισης στο skin, είναι η χρήση του element visual.
γ΄) Αυτά τα οποία είναι είναι στατικά ή μεταβλητά, αλλά περιλαμβάνουν και κείμενο (π.χ. ένα text, με διαφορετικό -του γενικού- background). Σε αυτή την περίπτωση και εφόσον δεν αφορά το element button, ο "μοναδικός" τρόπος απεικόνισης στο skin, εφόσον επιθυμούμε 1 definition να περιλαμβάνει 2 elements (και γραφικό και κείμενο), είναι η χρήση του element panel.

#1. Ορθά τα συμπεράσματα ή χρειάζεται κάποια συμπλήρωση ή διόρθωση?

#2. Τι είναι "προτιμότερο" από άποψη "λειτουργικότητας" του skin:

α΄) Δημιουργώ ένα definition - textzone, το οποίο αφορά την τιμή CPU και ένα definition - visual για το ξεχωριστό background που επιθυμώ να έχει το κείμενο.
β΄) Δημιουργώ ένα definition - panel ("αναγκαστικά", εφόσον το visual δεν δέχεται text ως child element), το οποίο συμπεριλαμβάνει και την τιμή CPU και το ξεχωριστό background.

Θεωρητικά η 1η περίπτωση έχει το "πλεονέκτημα" ότι πλέον έχω "έτοιμα" (μη συσχετισμένα με γραφικά) όλα τα definitions που αφορούν στα texts, για κάποιο επόμενο skin.
Θεωρητικά η 2η περίπτωση έχει το "πλεονέκτημα" ότι γράφεις λιγότερο κώδικα.

Πρακτικά, τι είναι καλύτερο για την skin engine του VDj?
 

Posted Thu 31 Jan 19 @ 8:56 am
Τελικά προχώρησα με την λύση των panels, στην περίπτωση κειμένου + ξεχωριστού background και όλα λειτουργούν άψογα!

2 ερωτήσεις…

1. Έχω το ακόλουθο panel definition:

<define class="val_Deck">
<size width="722" height="242"/>
<down x="5" y="1235"/>
<textzone>
<pos x="+350" y="-15"/>
<size width="110" height="20"/>
<text font="Segoe UI" size="20" align="center" scroll="no" color="`get_deck 1 ? is_audible ? blink ? color 'blue' : color 'darkblue' : color 'blue' : color '#808080'`" action="get_text 'DECK `get_deck`'"/>
</textzone>
</define>

Ποιος είναι ο ορθότερος τρόπος, ώστε αναλόγως της επιλογής Deck 1 ή Deck 2 ή Deck 3 ή Deck 4, να αλλάζει κατ’ αντιστοιχία και το <down x="…" y="…"/> (background) και το color?

2. Τι είναι το Panel id και πότε το χρησιμοποιούμε?
 

Posted Fri 01 Feb 19 @ 10:29 am
21%