• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Desktop/eigenes GUI Design - wie Daten strukturieren (hier Javascript)

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Hallo, der Titel ist vielleicht etwas konfus gewählt, aber ich versuche einen Desktop auf eiinem Canvas zu realisieren.
Sorry für den "Brainfuck" am Morgen, aber ich komme nicht wirklich weiter mit meinem Ansatz. bzw. kommt es mir zu komplex vor :confused:

Ich habe dabei ein Problem wie man die Daten in Javascript strukturiert so das man Design von den aktuellen gezeichneten Elementen isoliert bzw. diese so anlegt das man mit dynamischen Größen arbeiten kann und wie diese grundlegend Beschrieben werden sollen (hier als design.templateItem definiert).

Momentan sieht das Design Template in Javascript in etwa so aus:

Zum Einstieg die Beschreibung der gezeichneten Maus:
[src=javascript]design.defaultMouse = ["#fff", "#000", "round", [0, 0, 1, 0, 12, 10, 12, 15, 5, 15]];[/src]

Die Felder sind zum Beispiel hier:
Vordergrundfarbe (fillStyle), Strich (strokeStyle) Farbe, Linien-Kanten-Typ (lineMiter), die Koordinaten für einen Line-Befehl in "x, y"-Paaren.

Komplexer nun aber bei einem Fenster-Prototype:
Ich habe mal darüber nachgedacht das Fenster als ganzes zu beschreiben, breche es aber nun auf einzelne Elemente herunter wie Titel-Leiste, und Fenster Inhalt da es sonst (für mich) zu komplex war.

[src=javascript] // Window prototype
design.windowTitleBar = [[100, 10], ["#fff", "#aeaeae"], ["rect"], ["gradient_tb"], [["#4a0000", "#4a0000", "#000"]], [[0, 0, 100, 10]]];
design.windowContent = [[100, 150], ["#fff", "#aeaeae"], ["rect"], ["solid"], [["#2a0000"]], [[0, 10, 100, 150]]];[/src]

Vielleicht liegt hier schon der Fehler das überhaupt als Array anzulegen, aber kurz zum Aufbau:
1) Standardgröße des Elements in Breite und Höhe
(wenn das Fenster skaliert wird sollten diese beiden Werte innerhalb einer Begrenzung von x und y liegen)
2) Aktive Farben für den Inhalt (aktiv/inaktiv)
3) Zeichnungsmethode des Canvas was für die Zeichnung genutzt wird (Array von Befehlen ("rect" oder "line")
4) Array des FillStyle - also hier Verlauf_obenunten (topbottom)
5) Array mit Farben für jeden FillStyle-Typ (Verlauf/solid)
6) Array der Zeichnungs-Koordinaten für den in 3 gesetzten Befehl

Das ganze ist daher noch sonderlich komplex weil ich mir nicht sicher bin wie ich dynamisch auf die Veränderungen der Größe reagieren könnte, ich würde hier die Koordinaten in X und Y einschränken die im ersten Array des Design-Elements liegen, aber beispielsweise die Titel-Leiste soll immer 10 Pixel hoch sein und Standardmäßig 100 weit, wobei das Fenster mit 100 und 150 (hoch/breit) wäre in der Design-Definition, aber sowohl x als auch y dynamisch sind, ganz im Gegensatz zur Titelleiste wo eigentlich nur die weite dynamisch sein soll.

Denke ich hier unnötig komplex oder müsste man die Elemente sogar noch komplexer beschreiben?
Wie wird das in anderen GUI-Kits realisiert, hat jemand damit konkrete Erfahrungen?
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.507
Zu den Feinheiten von JS kann ich vermutlich nicht helfen, aber, was ist denn z.B. mit MVC Frameworks für JS?
 

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.754
Ort
in der Zukunft
http://imo.im fällt mir da auf anhieb ein wo ich sowas schon mal gesehen habe.
Habe gerade auf die Seite geschaut, leider muss man sich dort nun über ne Handyapp anmelden - früher konnte man das auch ohne die App anmelden...
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #4
@BurnerR,

ich glaube du hattest die Frage falsch aufgefasst oder ich hab mich etwas unverständlich ausgedrückt, vermute letzteres - ist etwas schwer zu beschreiben.
Es ging nicht direkt darum den Code zu organisieren, sondern eher wie man mittels Javascript eine GUI, zum Beispiel das Fensterobjekt, sinnvoll als Element definieren kann.

@drfuture
Zu den Dienst müsste man sich nun anmelden; aber wurde da eine GUI in Javascript realisiert?

//

Ich hab es bisher so gelöst das die GUI wie folgt in Teilen beschrieben wird:
[src=javascript]// Window prototype
design.windowTitleBar = ["x", ["#fff", "#aeaeae"], ["rect"], ["gradient_bt"], [["#4a0000", "#1a0000", "#000"]], [[0, 0, 100, 17]]];
design.windowContent = ["both", ["#fff", "#aeaeae"], ["rect"], ["solid"], [["#2a0000"]], [[0, 17, 100, 150]]];
design.windowStatusBar = ["x", ["#fff", "#aeaeae"], ["rect"], ["solid"], [["#4a0000"]], [[0, 167, 100, 17]]];[/src]

Hier sind noch die alten Parameter drin, nur der erste Parameter ist neu, das soll die Definition sein in welcher Achse das Element erweitertet bzw. verkleinert werden kann.
Für Kontrollelemente müsste man vielleicht die Plazierung in % verwenden.

Die Fenster sehen in der Anwendung dann so aus:
cantop_fenster.png


Wie man sieht sind die Titelleiste und die Statusleiste nur auf der X Achse wirklich interessant, der Fensterinhalt (windowContent) kann jedoch auf der X und Y Achse wachsen, bzw. soll auch verkleinert werden können bis auf ein gewisses Minimum.

Ein Fenster ist so definiert (alle 3 in der Abbildung teilen sich diesen Code).
Das Fenster wird in einer RenderQueue abgelegt (canTopData.renderQueue) und beinhaltet die Zeichengegenstände "windowTitleBar", "windowContent", "windowStatusbar".
Die Hotspots sind quasi die gezeichneten Elemente die auch anklickbar sein sollen um eventuelle Aktionen durchzuführen.
Der HotspotOffsetY ist die Obergrenze auf der Y Achse, also der untere Rand des Klickbereichs, Beispiel (laut Definition) :
titleBar von 0, 0, 100, 17 (100 pixel breit, 17 hoch)
content - 0, 17, 100, 150 (100 breit, 150 hoch, Beginn aber ab 17 auf der Y-Achse)
statusbar (0, 174, 100, 17) (startet auf Y 174, wird dann 100 breit und 17 hoch mit einem Rect befehl gezeichnet, wie auch die anderen)

Alle Elemente wachsen auf der X Achse, wobei der Inhalt auf X und Y wachsen/verkleinert werden kann.
Im Screenshot wurden alle Elemente auf die Fensterbreite von 300 Pixel erweitert.

[src=javascript]
function createWindow(design, title, x, y) {
var windowItem = {};
windowItem.title = title;
windowItem.x = x;
windowItem.y = y;
windowItem.zOrder = canTopData.renderQueueSize;
windowItem.drawingItems = ["windowTitleBar", "windowContent", "windowStatusBar"];
windowItem.hotSpots = ["windowTitleBar", "windowContent", "windowStatusBar"];
windowItem.items = ["Item 1", "Item 2", "Item 3"];
windowItem.style = "list";
windowItem.type = "window";
windowItem.hotSpotOffsetY = [];
//windowItem.drawingCoords = [];

var offsetY = 0;
for (var index = 0; index < windowItem.hotSpots.length; index++) {
//windowItem.drawingCoords.push(getArrayCopy(design[windowItem.hotSpots[index]][6]));
offsetY += design[windowItem.hotSpots[index]][6][3];
windowItem.hotSpotOffsetY.push(offsetY);
}

windowItem.height = offsetY;
windowItem.width = 300;

canTopData.renderQueue.push(windowItem);
canTopData.renderQueueSize++;
}[/src]

Was hierbei aber fehlt, sagen wir das Fenster wird mit 300 Pixel definiert, dann müsste quasi zuerest die Titelleiste abgezogen werden mit Y 17, dann die Statusleiste mit 17 höhe, und der Rest wäre frei für den Fensterinhalt - bei 300 pixel, also 300-34 = Fensterinhalt Höhe.

Ich würde diese Daten dann in dem windowItem speichern, also die Höhe und Gesamtbreite wie jetzt auch. Dann aber die Reihenfolge festlegen wie die Elemente berechnetet werden sollen damit die Rechnung wie eben herauskommt. Danach müssten die Zeichen-Koordinaten dann auch so für das Fenster gespeichert werden und diese zum Zeichnen, anstelle des Design Elements verwendet werden. Eigentlich der Codeteil der auskommentiert ist.

Das ist noch relativ easy, allerdings kommt mir das unmerklich kompliziert vor und ich frage mich ob es nicht leichter oder anders geht, das man flexibler wäre, wenn mehrere Elemente % des Fenster, bzw. Rests X Pixel hoch und weit sein sollen.
 

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.754
Ort
in der Zukunft
Ja unter dem Link gab es früher einen Multi-Messanger der jedes Chatfenster in einem solchen Fenster hatte... wie auf dem Desktop.
Meebo wäre auch sowas gewesen...
Habe mich bei imo.im angemeldet - das gibts dort auch nicht mehr. Genauso wie der 2. Laden. Schade... habe dann kein Beispiel für dich wo du dir sowas abschauen kannst.
imo.im wäre unter anderem von ehemaligen google-entwicklern gewesen und sicherlich Technisch recht gut umgesetzt.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
  • Thread Starter Thread Starter
  • #6
Ich hab nun nochmal etwas nachgelegt und bin soweit das man die Fenster skalieren kann, allerdings ist die Lösung noch nicht richtig praktikabel wenn man zum Beispiel mehrere Fensterbereiche hätte die dynamisch sein könnten, aktuell ist nur einer definiert der sich größentechnisch verändern kann, der Fensterinhalt. Hierbei werden einfach Koordinaten verwendet die bei Erstellung in das Fenster(Item) kopiert und dann bearbeitet werden wenn skaliert wird. Dabei bleiben dann die Status und Titelleiste in der Höhe konstant und der Resizer (rechts unten im Fenster) wird Pixelgenau positioniert.

Durch eine Änderung im Code das die Pfade bei einer Auswahl nachgezeichnet und pro Element mit isPointInPath überprüft werden, könnte theoretisch jede Designvorlage genutzt werden, nur behindert derzeit noch das automatische skalieren auf der X Achse exotische Designs.. vermutlich wäre hierbei die sauberste Lösung mit Prozenten zu arbeiten? Klingt jedenfalls so für mich gut.

Wer Interesse hat, hier ein Screenshot und folgend ein Link zum Projekt damit man mal den Code sehen kann.

cantop_fenster_v2.png


Der aktuelle Stand findet sich im Repository. Das letzte Update ist auch kommentiert aber wenig Code von mir dabei dokumentiert, es mutet daher etwas durcheinander an sollte aber halbwegs logisch aufgebaut und nachvollziehbar sein was wofür steht, hoffe ich.

Falls jemand Kritik zum Code hat oder Beispiele/Ideen zur Umsetzung nur her damit! :)

Edit: Noch mehr Kontrollen hinzugefügt, etwas code gemerged und einige Logikfehler behoben:
cantop_fenster_v2b.png
 
Zuletzt bearbeitet:
Oben