SzFMV2020-Osz / AutomatedCar-B

Working repository for the subject "Szoftverfejlesztés multinacionális vállalatoknál" @OE-NIK 2020 Autumn Group B
0 stars 1 forks source link

Implement SetRotation function #34

Closed kingpeti closed 3 years ago

kingpeti commented 3 years ago

Modulok diagram Kép forgatása a WordObject paraméterei alapján.

A WorldObjectTransformer-t kell kiegészíteni az ezért felelős függvénnyel.

Végül csak meg kellett fejteni, hogy hogyan is lehet forgatni avalonia-ban. A WorldObject kiegészült a megfelelő adattagokkal.

zsofiath commented 3 years ago

branch: B4_Implement_SetRotationfunction#34

pintergreg commented 3 years ago

@zsofiath A branch linkelésnél sokkal jobb, ha az adott branchről nyitsz egy PR-t a masterba (draft-nak jelölve ha még nincs kész) majd a linked issues részen hozzákapcsolod az issue-(ka)t amit megvalósít.

A GH olyan mutat egy diff-et, lehet kommentelni (akár soronként), lefutnak a beállított ellenőrzések, stb. Átláthatóbb, kényelmesebb.

Mivel ez mindenkinek érdekes best practice lehet, hivatkozom az @SzFMV2020-Osz/everyone -t.

zsofiath commented 3 years ago

@pintergreg , a draftot hol tudom beállítani?

zsofiath commented 3 years ago

Asszem találtam valami avalonia bugot: image image image

pintergreg commented 3 years ago

@zsofiath Megszerkesztettem a fenti posztomat, de itt is itt van a link a draft funkcióról: https://github.blog/2019-02-14-introducing-draft-pull-requests/

TL;DR: a zöld PR létrehozás gomb jobb oldalán levő nyíl alá van rejtve.

Forgatás: Azt hiszem megértem a problémát, bár a LayoutTransformControl-t egyáltalán nem ismerem. A problémát szerintem az okozza, hogy a stíluslappal beállítom az adott elem méretét majd te elforgatod a képet. Ekkor miután a konténer szélessége az álló autóhoz lett megválasztva, a megjelenítő összenyomja, hogy a tartalom beleférjen.

Van egy másik módszer is a forgatás/átméretezés funkcióra. Nem mondom, hogy dobd el amit eddig csináltál, esetleg nézd meg, hogy ezzel kényelmesebb-e dolgozni. Lehet ilyeneket „CSS-ből” is csinálni. Az Avalonia CSS-szerű formázást is biztosít és ha megnézed a kódot, akkor az X,Y koordináta beállítása is a Styles részen belül van (itt van a konténer mérete is beállítva). 0.10-től lehet azzal CSS3-szerű transzformációkat is csinálni (https://github.com/AvaloniaUI/Avalonia/pull/4092)

<Style Selector="ItemsControl#CourseDisplay > ContentPresenter">
    <Setter Property="Canvas.Left" Value="{Binding X, Mode=OneWay}"/>
    <Setter Property="Canvas.Top" Value="{Binding Y, Mode=OneWay}"/>
    <Setter Property="ZIndex" Value="{Binding ZIndex, Mode=OneWay}"/>
    <Setter Property="RenderTransform" Value="rotate(120deg)"/>
</Style>

És a value összetettebb is lehet pl. <Setter Property="RenderTransform" Value="rotate(120deg) scale(1.5) translateX(5px)" /> A konkrét értékeket bind-elheted ugyanúgy mint az X,Y koordináta van.

Ez valójában az ItemsControl teljes content-jére szól, tehát egyúttal a poligont is forgatja. Képernyőkép_2020-09-28_09-31-59

Továbbá az ItemsControl minden elemére érvényes, beleértve a fekete kört is (később minden útelemet, stb), ami a WorldObjects listában szerepel.

Ezt nyilván árnyalni kellene. Nem tudom, hogyan lehet azonban olyan selector-t írni, ami típus szerint válogat. Nem túl elegáns megoldás ha az autó esetében pl. az Image és a Polyline is kap egy osztályt (pl. Car) és ahhoz adsz egy stílust. Így az egész konténert forgatod el, nem csak a képet a konténeren belül.

Úgy gondolom, hogy a te megoldásod is javítható azzal ha a kép elforgatása után a konténerét is megfelelően állítod be. Úgy értem, hogy az elforgatott kép méreteire igazítod, nem pedig az eredetin hagyod.

<DataTemplate DataType="{x:Type models:AutomatedCar}">
    <Canvas>
        <Image Classes="Car"
            Source="{Binding Filename, Converter={x:Static visualization:WorldObjectTransformer.Instance}}"/>
        <Polyline Stroke="{Binding Brush, Mode=OneWay}" Classes="Car" Points="{Binding Geometry.Points, Mode=OneWay}" />
    </Canvas>
</DataTemplate>
<Style Selector="Image.Car, Polyline.Car">
     <Setter Property="RenderTransform" Value="rotate(90deg)"/>
</Style>
zsofiath commented 3 years ago

@pintergreg köszi a segítséget. A Style-on belül hogy működik a binding? Jelenleg így néz ki amit összehoztam, de olyan mintha a Binding-ot figyelmen kívül hagyná teljesen. image image

pintergreg commented 3 years ago

Ugyanúgy mint az X,Y koordináta:

https://github.com/SzFMV2020-Osz/AutomatedCar-B/blob/e792ac6190f91c1c2c91f3f967f1cd13b4861a79/src/AutomatedCar/Views/CourseDisplayView.xaml#L18-L19

Ennek kéne működnie, de valamiért nem jó.

<Setter Property="RenderTransform" Value="{Binding Angle, StringFormat='rotate({0}deg)'}"/>

Workaround:

<Setter Property="RenderTransform" Value="{Binding TransformValue}"/>

és

public string TransformValue { get => $"rotate({Angle}deg)"; }
pintergreg commented 3 years ago

@zsofiath Ez működik:

<DataTemplate DataType="{x:Type models:AutomatedCar}">
    <Canvas>
        <Canvas.RenderTransform>
            <RotateTransform Angle="{Binding Angle}" />
        </Canvas.RenderTransform>
        <Image
            Source="{Binding Filename,
            Converter={x:Static visualization:WorldObjectTransformer.Instance}}"/>
        <Polyline Stroke="{Binding Brush, Mode=OneWay}"
                    Points="{Binding Geometry.Points, Mode=OneWay}" />
    </Canvas>
</DataTemplate>

És a Style-hoz hasonlóan az egész objektum canvas-t transformálja, egyben a képet és a poligont méret módosítás nélkül.

zsofiath commented 3 years ago

Wow. Köszi. Így barátságosabb. Bele is teszem.

zsofiath commented 3 years ago

Megvan a következő bökkenő :/ a forgatási középpont WPF-ben a RotateTransform-nak van centerX meg centerY paramétere erre, de ez avalonia-ban nincs. Találtam egy olyat, hogy RenderTransformOrigin, amit ha beteszek a canvasba, akkor szépen teszi a dolgát, de bindolni nem tudom.

<Canvas RenderTransformOrigin="100,100" >

így elmozgatja a középpontot, de így már nem akarja

<Canvas RenderTransformOrigin="{Binding CenterPoint}" >

a CenterPoint-ban ez a string van "100,0"

pintergreg commented 3 years ago

Ezt még pont észrevettem ma. Van egy translateX és translateY transzformáció, ami az eltolás X és Y tengelyen. Javában is hasonló volt és azzal oldották meg.

Innen van rá egy példa: https://github.com/AvaloniaUI/Avalonia/pull/4092

<Setter Property="RenderTransform" Value="rotate(120deg) scale(1.5) translateX(5px)" />

Ezt a megadást kellene talán átalakítani úgy, ahogy a rotate-nál, de ezt most nem tudom már kipróbálni.

zsofiath commented 3 years ago

Hát finnyás egy dög ez az avalonia...

ha így írom rinyál, hogy nem lehet több assignmentje a RenderTransformnak

<Canvas.RenderTransform>
<TranslateTransform X="100px"/>
<RotateTransform  Angle="{Binding Angle}" />
</Canvas.RenderTransform>

ha pedig így akkor a legutolsó-t figyelembe veszi, a többit nem

<Canvas.RenderTransform>
       <RotateTransform  Angle="{Binding Angle}" />
</Canvas.RenderTransform>
<Canvas.RenderTransform>
       <TranslateTransform  X="100" />
</Canvas.RenderTransform>
zsofiath commented 3 years ago

Vááá!! Siker

<Canvas.RenderTransform>
    <TransformGroup>
        <RotateTransform  Angle="{Binding Angle}" />
        <TranslateTransform  X="200" />
    </TransformGroup>

</Canvas.RenderTransform>
zsofiath commented 3 years ago

Itt akkor az lett az eredmény, hogy nem kell konverter, hanem elég ha a WorldObjectben benne vannak a megfelelő paraméterek. @aaronrancsik, ezeket tettem bele a WorldObjectbe, hogy sikerüljön nagy küzdelmek árán elforgatni az a nyomorult kocsit.

 private int _angle = 90; // mocking
 public int _rotationCenterPointX = 90; // = width/2
public int _rotationCenterPointY = 120; // = height/2

public int Angle
{
     get => this._angle;
}

public int RotationCenterPointX 
{
       get => this._rotationCenterPointX;
 }
public int RotationCenterPointY
{
       get => this._rotationCenterPointY;
}