Ik mag zo af en toe graag eens wat hobbyen, en nou heb ik onlangs m'n soft synth genaamd "Machinery" weer eens afgestoft. Nou was de UI daarvan oorspronkelijk ontworpen mbv de rauwe win32 API, en gezien mijn kennismaking met WPF van afgelopen jaar leek het mij wel een goed idee om de boel eens volledig om te gooien. Echter, mijn kennis van WPF is nog lang niet op niveau, dus ik vroeg mij af hoe ik het volgende aan moest pakken.
De kern van mijn app bestaat uit 'machines' die aan elkaar te koppelen zijn. Zo'n machine heeft een optioneel aantal inputs en outputs, en de output van de ene machine is weer te knopen aan de input van een ander. Voor diegene die bekend zijn met audio apps, dit is vergelijkbaar met programma's als Reason en Buzz, maar eigenlijk is dat niet eens zo interessant - feitelijk kun je het gewoon zien als een graaf, waarin een Machine een node is en een verbinding tussen de machines een edge. Hier een screenshot van mijn oude win32 implementatie:

Nou zou ik zoiets wel gewoon kunnen implementeren in WPF, maar ik wilde het graag goed aanpakken en ik heb een belangrijke eis: een machine moet zelf zijn eigen view kunnen implementeren. Onder win32 was dit vrij simpel, geef een HDC mee aan een Draw() method op een interface die de machine implementeert zodat ie gewoon zijn eigen shit kan tekenen, en verder had ik nog een HitTest() method zodat de machine kon rapporteren of op die plek een input of output of z'n caption staat, zodat de app de inputs en outputs aan elkaar kon verbinden of de machine kon selecteren en verplaatsen.
Nou is de Draw() in WPF natuurlijk een no-go, maar hij zou wel een DataTemplate oid aan kunnen leveren die je kunt gebruiken om z'n visual tree te instantieren. De HitTest() is nog steeds mogelijk, maar dit lijkt me niet de WPF-manier om dingen te doen. Is het niet netter om specifieke controls of standaard controls met specifieke attached dependency properties in de visual tree te hebben, zodat de app weet wat ie ermee kan doen? Wat ik dus iig wil kunnen is een machine selecteren en draggen door op z'n caption te klikken, en natuurlijk outputs met inputs verbinden op het moment dat je vanaf zo'n output/input begint te click-draggen. Het lijkt me logisch dat de machine view niet zelf verantwoordelijk is voor die logica, maar hij moet bijvoorbeeld wel in staat zijn om een simpele bitmap te tekenen en dat ik dan op een of andere manier te weten kom of er op zo'n input geklikt is. Of is er wellicht nog een compleet andere manier om dit probleem te tacklen?
Hoe zouden jullie zoiets aanpakken?
De kern van mijn app bestaat uit 'machines' die aan elkaar te koppelen zijn. Zo'n machine heeft een optioneel aantal inputs en outputs, en de output van de ene machine is weer te knopen aan de input van een ander. Voor diegene die bekend zijn met audio apps, dit is vergelijkbaar met programma's als Reason en Buzz, maar eigenlijk is dat niet eens zo interessant - feitelijk kun je het gewoon zien als een graaf, waarin een Machine een node is en een verbinding tussen de machines een edge. Hier een screenshot van mijn oude win32 implementatie:

Nou zou ik zoiets wel gewoon kunnen implementeren in WPF, maar ik wilde het graag goed aanpakken en ik heb een belangrijke eis: een machine moet zelf zijn eigen view kunnen implementeren. Onder win32 was dit vrij simpel, geef een HDC mee aan een Draw() method op een interface die de machine implementeert zodat ie gewoon zijn eigen shit kan tekenen, en verder had ik nog een HitTest() method zodat de machine kon rapporteren of op die plek een input of output of z'n caption staat, zodat de app de inputs en outputs aan elkaar kon verbinden of de machine kon selecteren en verplaatsen.
Nou is de Draw() in WPF natuurlijk een no-go, maar hij zou wel een DataTemplate oid aan kunnen leveren die je kunt gebruiken om z'n visual tree te instantieren. De HitTest() is nog steeds mogelijk, maar dit lijkt me niet de WPF-manier om dingen te doen. Is het niet netter om specifieke controls of standaard controls met specifieke attached dependency properties in de visual tree te hebben, zodat de app weet wat ie ermee kan doen? Wat ik dus iig wil kunnen is een machine selecteren en draggen door op z'n caption te klikken, en natuurlijk outputs met inputs verbinden op het moment dat je vanaf zo'n output/input begint te click-draggen. Het lijkt me logisch dat de machine view niet zelf verantwoordelijk is voor die logica, maar hij moet bijvoorbeeld wel in staat zijn om een simpele bitmap te tekenen en dat ik dan op een of andere manier te weten kom of er op zo'n input geklikt is. Of is er wellicht nog een compleet andere manier om dit probleem te tacklen?
Hoe zouden jullie zoiets aanpakken?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.