niedziela, 26 sierpnia 2012

WinJS na żywo - odc. 1 (Wstęp & Blend)

Po napisaniu prototypu aplikacji pobierającej clipy z YouTube w C# na Windows 8 (a także ostatnio na WP*), postanowiłem przepisać to co już powstało na WinJS w Windows 8. Przeglądałem jakiś czas temu niemal całą dokumentację msdn na ten temat, ale myślę, że jednak najlepiej pobawić się w praktyce. W międzyczasie przyswoiłem pewną ilość wiedzy na temat samego HTML5, JavaScript, CSS3, jQuery, Knockout oraz innych nowych standardów i frameworków dla aplikacji Web, więc teraz to spojrzenie na WinJS będzie myślę bardziej dojrzałe. Jako, że zawsze bardzo lubiłem narzędzie Blend, więc również i tym razem będę go używał.

Trzecią część tryptyku rozpocząłem od stworzenia nowego projektu z dwiema stronami z przykładowymi danymi, z których drugą przedstawiam poniżej:

jstube_1

Zaraz, zaraz czy takiego screenshota już tutaj nie było? Owszem, jak ktoś przepatrzy historię, to może znaleźć nawet taki z tymi samymi zdjęciami (gdy używałem na początku w C# przykładowych danych, były takie same).

mks_01_C 

Aplikacje w C# i w HTML5 na WinRT nie różnią się wizualnie ani zachowaniem, co świadczy o sporym postępie jeśli chodzi o wykorzystanie technologii Web do pisania natywnych aplikacji.

Teraz parę słów o Blendzie. Nie będę pisał kolejnego tutoriala, jak obsługiwać w nim HTML, JS i CSS, można znaleźć to wszystko w sieci. Ze swojej strony mogę powiedzieć, że jeśli ktoś zna Blenda pod XAML, to tutaj trzeba… chwilki czasu, by się oswoić. Twórcy postanowili odzwierciedlić HTML i CSS takimi jakimi są, bez upiększeń, nie mamy w zasadzie żadnej abstrakcji. Na początku może nam brakować pewnych paneli aplikacji jakie znamy z XAML, ale w miarę używania poczujemy bardzo dużą wygodę korzystania mimo odmiennej filozofii działania. Bardzo wiele rzeczy można zrobić z poziomu designera czy wykorzystując inne pomocnicze narzędzia. W pewnej mierze jest to wzorowane na narzędziach z przeglądarek webowych czy narzędziach dla aplikacji Web w Visual Studio 2012, ale część mechanizmów znanych z Blenda dla XAML zostało tutaj osadzonych.

Zwrócę teraz uwagę na kilka wybranych rzeczy. Layout odpowiadający Grid-owi z XAML, możemy robić … tak samo. Jest to zasługą specyfikacji Grid Layout w CSS3 (szkoda że przy “otwartych” aplikacjach webowych to zagadnienie jest bardziej złożone z uwagi, że na razie chyba jedynie IE10 implementuje ten standard). Na razie używałem grid i flex w paru miejscach… Na screenshocie grid w AppBar z niestandardową zawartością… (btw AppBar pod WinJS jest na większym poziomie organizacyjnym, ma też wygodniejszą obsługę z poziomu Blenda).

jstube_2

Warto powiedzieć, że w designerze wykonuje się kod JS na żywo, z reguły do obserwowania zmian automatyczne odświeżanie jest wystarczające. Z dużą łatwością ustalimy, dlaczego np. dany element ma taki kolor a nie inny. Widzimy jakie reguły CSS z jakich plików odnoszą się do danego elementu, która reguła zwyciężyła, jakie wartości są ostatecznie wyliczane.

jstube_3

Przy okazji mała dygresja na temat gwiazdek. W C# użyłem dla celów demonstracyjnych jedynie napisu, w WinJS mamy kontrolkę Rating, której parametr pozwoliłem sobie zbindować. Trochę też ją przestylowałem, pomniejszając nieco gwiazdki i zmieniając im kolor… Miałem tutaj chwilkę na wyczajenie jednego parametru z layoutu flex. Kontrolka mi się niepotrzebnie rozciągała horyzontalnie, nawet wbrew innym ustawieniom. Pomogło ustawienie w stylu dla gwiazdki ms-flex: 0 0 auto …

Koniecznie należy wspomnieć o przycisku ze “strzałką z kreseczkami” nad prawą górną krawędzią designera. Otwiera nam okno trybu interaktywnego, w którym możemy coś zrobić w naszej aplikacji, a potem wrócić z powrotem wrócić do designera. Mi się to bardzo przydało, gdy edytowałem wygląd zaznaczonego elementu.

jstube_4

W przeciwieństwie do kontrolki z C# zamiast docelowego wyglądu, jaki chciałem osiągnąć w WinJS zastałem domyślnie niewidoczne obramowanie oraz check z przezroczystym tłem przy domyślnej zmianie tła całego elementu na niebieski. Taki styl spotkamy w części wbudowanych aplikacji np. Skydrive. Wszędzie tam stawia się na mały obrazek, jakiś napis i przezroczyste tło, które zmieni kolor. Mi jednak bardziej pasowało by to obrazek był tłem, chciałem więc mieć wygląd taki jaki jest domyślny w C# i … trochę mi to zajęło. Ponieważ nie jest to takie oczywiste więc podam sposób, w jaki osiągnąłem pomarańczową ramką i check w pomarańczowym trójkącie.

Pomarańczowa ramka: ramka … już jest, wystarczy zmienić tylko jej kolor definiując regułę nadpisującą (u mnie były takie zagnieżdżenia jak poniżej, w każdym razie należy zwrócić uwagę na zagnieżdżenie klas .win-selected .win-selectionborder w kontrolce ListView):

.addnewvideospage .groupeditemslist .win-selected .win-selectionborder {
                background-color: #D8512B;   
            }

Z pomarańczowym trójkątem było już gorzej, bo po zmianie koloru tła elementu z checkiem w kontrolce okazał się … prostokątem. Posiłkując się stronami w sieci na temat otrzymywania figur z bordera (np. http://css3shapes.com/, http://www.howtocreate.co.uk/tutorials/css/slopes), ustawiłem regułę:

.addnewvideospage .groupeditemslist .win-selected .win-selectioncheckmarkbackground {
                width: 0px;
                border-top: 20px solid #D8512B;
                border-right: 20px solid #D8512B;
            }

Teraz mała dygresja o tym, jak zrobiłem formatowanie daty. W XAML był to konwerter do bindingu (w przeciwieństwie do Silverlight nie ma StringFormat), w WinJS też mamy podobną koncepcję. Definiujemy funkcję w JavaScript:

var formatDate = WinJS.Binding.converter(function (date) {       
        var dateTimeFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("{day.integer(2)}/{month.integer(2)}/{year.full}‎ {hour.integer(2)}: {minute.integer(2)}");
        return dateTimeFmt.format(date);
    });

Rejestrujemy ją w przestrzeni nazw (w sumie jest to jakaś implementacja w WinJS jednego z polecanych wzorców projektowych dla JS):

WinJS.Namespace.define("Data", {
        formatDate: formatDate, …
});  

W data bindingu po ścieżce dopisujemy zdefiniowaną funkcję konwertującą:

<h6 class="item-subtitle" data-win-bind="textContent:pubDate Data.formatDate"></h6>

Inną małą dygresją jest wyświetlanie automatyczne wyświetlanie … w przypadku, gdy napis okaże się za długi. W XAML czy Silverlight był na to parametr w TextBlock, w HTML na Windows 8 wystarczy użyć predefiniowanej klasy win-type-ellipsis np.

<h4 class="item-title win-type-ellipsis" data-win-bind="textContent: title"></h4>

W sumie to nasunął mi się jeden komentarz odnośnie data bindingu w WinJS po tych dwóch dygresjach. Używa data-* więc jest zgodny z HTML5 i przypomina Knockouta.

Wiadomo, nie opiszę wszystkiego-;)  Myślę że jak na ten post to już wystarczy.

Ciąg dalszy nastąpi.

Brak komentarzy: