Posts tagged ‘GUI’

Bootstrap, a UI framework for the modern Web

2012-04-22 20:11

It was almost exactly one year ago and I remember it quite vividly. I was attending an event organized by Google which was about the Chrome Web Store, as well as HTML5 and web applications in general. After the speaker finished pitching about awesomeness of this stuff (and how Chrome was the only browser that supported them all, of course), it was time for a round of questions and some discussion. I seized this opportunity and brought up an issue of user interface inconsistencies that plague the contemporary web apps. Because the Web as a platform doesn’t really enforce any constraints on UI paradigms, we can experience all sorts of “creative” approaches to user interface. In their pursuit of novelty and eye candies, web designers often sacrifice usability by not adhering to well known interface metaphors, and shying away from uniform UI elements.

At that time I didn’t really get a good answer that would address this issue. And it’s an important one, given the rate at which web applications are springing to life and replacing their equivalent desktop programs. Does it mean we’ll be stuck with this UI bonanza for the time being?…

Fortunately, there are some early first signs that it might not necessarily be so.

Enter Bootstrap


Few months later, in August 2011, Twitter released the first version of Bootstrap framework. Originally intended for internal use, this set of common HTML, CSS and JS patterns was made open source and released into the wild. The praise it subsequently gained is definitely well deserved, for it is a great set of tools for kickstarting development of any web-related project. Its features include:

  • a flexible grid system for establishing a skeleton of the web page or app
  • a set of great-looking styles for HTML form elements
  • many complex UI components, like collapsible alerts, dropdowns, navigation bars, modal windows, and so on
  • customizable set of CSS styles for typical markup elements, such as headers or tables

Along with universal acclaim came also the popularity: it is currently the most watched project on GitHub.

The value of consistency

However, some want to argue that being so popular has also an unanticipated, negative side. It makes the developers lazy, convinced they can get away without a “proper” design for their site or app. Even more: it allegedly shows disrespect for their users, as if the creator simply didn’t care how does their product look like.

Does it compute? I don’t think so. Do you complain if you find that any particular desktop application uses the very same looks for UI components, like buttons or list boxes?… Of course not. We learned to value the consistency and predictability that this entails, because it frees us from the burden of mentally adjusting to every single GUI app that we happen to use. Similarly, developers appreciate how this makes their work easier: they don’t have to code dropdown menus or modal dialogs, which in turns allows them to spend more time on actual, useful functionality.

Sure, it didn’t happen overnight when desktop OS’ were emerging as software platforms. Also, there are still plenty of apps whose creators – willfully or unintentionally – chose not to adhere to the standards. Sometimes it’s even for the good, as it allows for new, useful UI patterns to emerge and be adopted by the mainstream. The resulting process is still that of convergence, producing interfaces which are more consistent and easier to use.

Bootstrap shapes the Web

The analogous process may just be happening to the Internet, considered as a “platform” for web applications. By steadily raising in popularity, Bootstrap has a chance of becoming the UI framework for Web in general – an obvious first choice for any new project.

Of course, even if this happens, it would be terribly unlikely that it starts reigning supreme and making every website look almost exactly the same – i.e. transforming the Web into equivalent of desktop. What’s much more likely is following the footsteps of mobile platforms. In there, every app strives to be original and appealing but only those that correctly balance usability with artsy design provide really compelling user experience.

It will not be without differences, though. Mobile platforms are generally ruled with iron (or clay) fist and have relevant UI guidelines spelled out explicitly. For Web it’s very much not the case, so any potential “standardization” is necessarily a bottom-up process whose benefits have to be indisputable and clearly visible. Despite some opposition, Bootstrap seems to have enough momentum to really (ahem) bootstrap this process. It already wins hearts and minds of many web developers, so it may be just a matter of time.

If it happens, I believe the Web will be in better place.

Tags: , , , ,
Author: Xion, posted under Internet, Programming, Thoughts » Comments Off on Bootstrap, a UI framework for the modern Web

Prezentacja nt. programowania UI w Androidzie

2011-08-29 21:16

W sobotę wziąłem udział w pierwszej konferencji Appspirina – wydarzeniu poświęconemu tworzeniu aplikacji mobilnych. Ta pierwsza edycja była współorganizowana przez polski GTUG i tematycznie była związana z platformą Android, więc przypadkowo w całości pokrywała się z moimi zainteresowaniami ;)
Cieszę się więc, że mogłem tam wystąpić, prezentując wykład na temat niektórych co bardziej zaawansowanych aspektów programowania interfejsu użytkownika w Androidzie. Omówiłem tam nieco rzadziej spotykane przypadki użycia takich typowych narzędzi jak zasoby (resources), układy kontrolek (layouts) czy też różne sposoby powiadamiania użytkownika o istotnych i mniej istotnych zdarzeniach.

Na facebookowej stronie inicjatywy powinno się już pojawić kilka zdjęć, a wkrótce powinien też zostać udostępniony film z każdego z (trzech) wykładów. Póki co zamieszczam dla potomności slajdy ze swojej własnej prezentacji :)

File: Zaawansowane programowanie UI na platformie Android [PL]  Zaawansowane programowanie UI na platformie Android [PL] (762.0 KiB, 13,403 downloads)

Tags: , , , ,
Author: Xion, posted under Events, Programming » 4 comments

Implementacja przeciągania

2011-08-08 20:19

Przedstawię dzisiaj dość elementarną technikę, związaną z szeroką pojętym programowaniem grafiki – a zwłaszcza interfejsów użytkownika. Chodzi o nic innego jak przeciąganie (dragging), czyli przemieszczanie różnych elementów za pomocą myszy czy innego urządzenia wskazującego (np. palca ;]). Celowo nie dodałem tutaj drugiej połowy procesu znanego jako drag & drop – czyli upuszczania – bo nie mam w ogóle na myśli potencjalnie zaawansowanej logiki związanej z wymianą danych reprezentowanych przez przeciągany obiekt. Przeciwnie; chodzi mi wyłącznie o samo przesuwanie go po ekranie. Rezultatem (niekoniecznie jedynym, rzecz jasna) ma być po prostu zmiana jego położenia.

W zaawansowanych systemach GUI rozwiązanie sprowadza się najczęściej do instrukcji w rodzaju obj.Draggable = true;, a cała reszta odbywa się “automagicznie”. Załóżmy jednak, że nie mamy zaawansowanego systemu GUI i dysponujemy jedynie możliwością rysowania oraz odbierania zdarzeń od wskaźnika myszy. Nie jest to wcale rzadka sytuacja: żeby nie szukać daleko, wystarczy cofnąć się o tydzień do opisu elementu <canvas> z HTML5 :) W ogólności dotyczy to jakiejkolwiek “czystej” biblioteki graficznej: OpenGL, DirectX, SDL, itp.
Doprecyzujmy jeszcze to, iż “odbieranie zdarzeń od myszy” obejmuje tak naprawdę poniższe trzy zdarzenia (lub ich odpowiedniki dla innych – np. dotykowych – sposobów wskazywania):

  • wciśnięcie przycisku myszy – zdarzenie odbierane zwykle jako MouseDown
  • ruch wskaźnikiem – MouseMove
  • zwolnienie przycisku – MouseUp

Nietrudno zauważyć, że całkowicie wystarczają one do implementacji przeciągania. Jak więc miałaby ona wyglądać?

Tags: , ,
Author: Xion, posted under Programming » 1 comment

Obrazki dziewięciołatkowe

2011-01-13 22:50

Jako dzisiejszą ciekawostkę chcę przedstawić pewną technikę, która może być przydatna przy implementacji systemu GUI na przykład na potrzeby gier. Zazwyczaj bowiem elementami interfejsu są różnego rodzaju kontrolki, które – chociaż nierzadko nie przypominają klasycznych widgetów w rodzaju przycisków czy pól tekstowych – posiadają prostokątne obramowanie. Ta ramka musi mieć jedną istotną cechę: powinna dopasowywać się do rozmiaru kontrolki, dopuszczając elementy o dowolnie dużych wymiarach. A jednocześnie powinna ona być utrzymana w odpowiednim stylu graficznym, zwykle spójnym z resztą aplikacji lub gry.

Sposobem na sprostanie tym wymaganiom jest podział prostokąta kontrolki na dziewięć części, różniących się zakresem skalowania, jakiemu są poddawane, gdy kontrolka zmienia rozmiary. Wśród tych części możemy mianowicie znaleźć następujące:

  • cztery rogi, które w ogóle nie zmieniają rozmiarów i są zawsze rysowane tak samo
  • dwie krawędzie poziome (górna i dolna) oraz dwie pionowe (lewa i prawa), które zmieniają tylko jeden ze swoich wymiarów, odpowiednio: szerokość lub wysokość
  • środek, któremu zmieniają się zawsze oba wymiary

Żeby więc poprawnie narysować naszą kontrolkę, potrzebujemy w ogólności aż dziewięciu różnych obrazków. Oczywiście niekiedy będzie ich mniej, jeśli sprytnie posłużymy się obrotami i odbicia obrazów. Prawie na pewno jednak będzie to więcej niż jeden sprite i każdy z nich trzeba będzie jakoś oznaczyć i zapisać razem z naszą aplikacją, wymyślając do tego mniej lub bardziej skomplikowaną konwencję.

To, co chcę przedstawić, to w gruncie rzeczy taka właśnie konwencja. Nazywa się ona nine-patch images, czyli tytułowe obrazki dziewięciołatkowe. Pochodzi ona z systemu Android i jest jedną z wielu może mało efektownych, ale pomysłowych rozwiązań, ukrytych w jego API.
Idea jest dość prosta. Jeśli mamy już obramowanie w postaci obrazka otoczonego nim prostokąta, nie musimy wycinać z niego poszczególnych części i zapisywać ich osobno. Zamiast tego zaznaczamy je bezpośrednio na obrazku, dodając wpierw jednopikselowe, czarno-białe obramowanie. Czarny fragment określa część podlegającą skalowaniu (czyli środek), zaś biały – niezmieniające rozmiaru mu rogi prostokąta. Najlepiej widać to na ilustracji po lewej stronie.
Można na niej zauważyć, że do określenia obszaru skalowania wystarczy zasadniczo jeden dodatkowy rząd i jedna dodatkowa kolumna pikseli. Pozostała część dodatkowego obramowania może nam wtedy posłużyć do zdefiniowania obszaru treści, czyli tego fragmentu kontrolki, który będzie mógł być wypełniony tekstem i innymi elementami, ustawionymi jako jej zawartość. Obszar treści nie musi pokrywać się z obszarem skalowania, co z kolei jest widoczne na obrazku po prawej stronie.

Z tak przygotowanej grafiki wciąż możemy w miarę łatwo odczytać programowo potrzebne informacje o sposobie rysowania obramowania kontrolki i wypełniania jej treści. Rozwiązanie to ma przy tym tę oczywistą zaletę, że przygotowanie takiej grafiki jest z pewnością mniej pracochłonne i kłopotliwe niż tworzenie od 3 do 9 osobnych sprite‘ów i podawanie informacji o obszarze treści w jakiegoś rodzaju pliku konfiguracyjnym.
Jeśli więc ktoś w ramach silnikologii stosowanej zajmuje się implementacją modułu GUI, może rozważyć zastosowanie podobnego systemu :)

Tags: , ,
Author: Xion, posted under Programming » 7 comments

Odchudzanie lisa

2010-10-29 20:04

Jak można przeczytać tu i ówdzie (a potem sprawdzić u źródła), premiera czwartej wersji przeglądarki Firefox przesunie się z końca tego roku na początek przyszłego. Zwolennicy tzw. bardziej nowoczesnych przeglądarek zapewne skorzystają z okazji, by używać tego faktu jako argumentu na rzecz tezy, że Ognisty Lis pozostaje w tyle pod względem szybkości, zgodności z sieciowymi standardami oraz estetyki i komfortu interfejsu.
Nawet jako jego użytkownik muszę przyznać, że przynajmniej ostatni z tych zarzutów faktycznie może być zasadny – ale tylko pod jednym zastrzeżeniem, które w przypadku Firefoksa jest po prostu nie fair. O ile bowiem FF3.6 out-of-the-box jest faktycznie dość siermiężny, o tyle nadrabia to z nawiązką możliwościami konfiguracji, których nie można w uczciwym zestawieniu pominąć.


Standardowy interfejs Firefoksa

Żeby jednak nie być gołosłownym pozwolę sobie pokazać, jak w kilku krokach możemy ów niezbyt imponujący, standardowy interfejs przekształcić w coś bardziej ‘nowoczesnego’. Mój opis można będzie potem potraktować jako swego rodzaju konstruktywną ripostę w świętych wojnach przeglądarkowych :)

Tags: , ,
Author: Xion, posted under Applications, Internet » 20 comments

Własne kontrolki w Windows Forms

2010-06-18 22:06

Gdy tworzymy aplikacje okienkowe w .NET z użyciem Windows Forms, możemy korzystać z mnóstwa (co najmniej kilkudziesięciu) typów kontrolek dostępnych out-of-the-box. Nie wszystkie nawet mają rację bytu jako rzeczywiste kontrolki, ale w wielu przypadkach fakt, że nimi są, ułatwia korzystanie z API, które się kryje za taki komponentami. (Przykładem jest kontrolka BackgroundWorker).
Nie oznacza to jednak, że nie istnieje czasami potrzeba stworzenia własnego rodzaju kontrolki, specyficznej dla pisanego programu. Nawet jeśli miałaby ona być użyta tylko w jednym egzemplarzu, wyodrębnienie jej logiki poza zasadniczy kod aplikacji powinno wyjść im obu na dobre. W tym sensie jest ten rodzaj dodatkowej warstwy abstrakcji, który zazwyczaj opłaca się stworzyć.

Jak to się robi? Przede wszystkim należy wiedzieć, że w .NET kontrolki definiowane przez programistę mogą być jednego z trzech rodzajów. Stosunkowo najprostszym jest user control, które to stanowi po prostu pojemnik na kilka innych kontrolek zebranych w całość. Mogą to być na przykład dwa obiekty typu NumericUpDown opatrzone etykietami “Od” i “Do”, jeśli w naszym programie wielokrotnie i w różnych miejscach zachodzi potrzeba podawania przedziału liczbowego. Właściwości takiej customowej kontrolki są najczęściej bezpośrednio mapowane na właściwości kontrolek składowych, a zdarzenia są sygnalizowane w odpowiedzi na niektóre ze zdarzeń pochodzących z tychże kontrolek. W sumie więc można powiedzieć, że trochę tak jak funkcje i klasy pozwalają na wielokrotne wykorzystywanie kodu, tak user controls dają możliwość ponownego wykorzystania pewnych fragmentów UI.

Drugim typem są kontrolki dziedziczone (inherited controls). Nazwa wskazuje, że powstają one przez odziedziczenie już istniejącego rodzaju (klasy) kontrolki i dodanie do niej lub zmianę funkcjonalności. Może to obejmować dodanie nowych właściwości, częściowego lub całkowitego obsłużenia niektórych zdarzeń i inne tego typu modyfikacje zachowania kontrolki. Ważne jest tutaj to, iż efekt, jaki chcemy osiągnąć, jest na tyle zbliżony do jednej z istniejących kontrolek, że można ją wykorzystać i nie zaczynać od zera.
No ale nie zawsze tak jest i czasem naprawdę trzeba zacząć od podstaw. Jeżeli bazujemy na zupełnie abstrakcyjnym typie z góry hierarchii interfejsu – jak Control czy Component – to mamy do czynienia z kontrolką typu owner-draw. Dla niej musimy ręcznie rysować całą zawartość przy pomocy instrukcji GDI+ (stąd nazwa), opierając się przy tym na prostych zdarzeniach w rodzaju kliknięć myszy. Nie jest to więc łatwe i szybkie do wykonania zadanie.

Bywa aczkolwiek i tak, że jest ono koniecznie. Zanim się do niego zabierzemy, lepiej jednak przejrzeć alternatywy w postaci kontrolek odziedziczonych lub user controls. Możliwe, że w ten sposób zaoszczędzimy sobie pracy.

Tags: , , ,
Author: Xion, posted under Programming » 4 comments

O układaniu kontrolek

2008-05-19 20:57

Najprostszym sposobem na rozmieszczanie kontrolek w oknie programu jest oczywiście… podanie ich pozycji i rozmiarów dosłownie. Ta metoda sprawdza się dobrze jednak tylko w prostych przypadkach: gdy mamy stałą (i raczej niewielką) liczbę obiektów, gdy rozmiary okna są stałe, gdy nie dostosowujemy rozmiaru interfejsu do rozdzielczości ekranu, itd. W wielu przypadkach to jednak nie wystarcza i dlatego systemy GUI oferują też inne narzędzia pozycjonowania elementów interfejsu. Niektóre z nich są całkiem pomysłowe. Oto kilka przykładów:

  • Przykład dokowania kontrolek
    Przykład dokowania

    Dokowanie (docking), zwane też wyrównywaniem (align). Polega to na “przyklejeniu” kontrolki do którejś z krawędzi nadrzędnego pojemnika (np. okna) w jednym wymiarze oraz do obu krawędzi w wymiarze prostopadłym. Komponentowi pozostaje wówczas jeden stopień swobody. Przykładowo, kontrolka zadokowana po lewej stronie może się jedynie rozszerzać w prawo (lub zmniejszać w lewo), zaś jej górna i dolna krawędź pokrywają się zawsze z odpowiednimi krawędziami zawierającego ją pojemnika.
    Ten sposób pozycjonowania jest idealny chociażby dla pasków stanu (status bar), które zawsze umiejscowione są w dolnej krawędzi okna.

  • Ustawianie zakotwiczania
    Ustawianie zakotwiczania
    w Visual Studio

    Zakotwiczanie (anchoring) polega z kolei na ustawieniu stałej odległości pewnych krawędzi kontrolki od odpowiednich krawędzi kontrolki nadrzędnej. Domyślnie na przykład każdy komponent jest zakotwiczony z lewej i z góry. Gdy zmieniamy rozmiar zawierającego go okna, dystans między lewą krawędzią tegoż okna i lewą krawędzią kontrolki pozostaje stały; podobnie jest z górnymi brzegami. Zmieniając ustawienia zakotwiczania możemy uzyskać efekt kontrolki “wyrównanej” w podobny sposób jak tekst w edytorze, np. do prawej strony okna zamiast do lewej.
    Anchoring można uznać za nieco lepszą wersję dokowania, ale w istocie różni się on od niego dość znacznie (zwłaszcza jeśli dokujemy wiele kontrolek po jednej stronie). Jest on jednak przydatny wtedy, gdy kontrolka ma w określony sposób zmieniać rozmiar wraz z oknem.

  • Układ typu flow
    Układ typu flow

    Układy (layouts) kontrolek. Są to bardziej wyspecjalizowane narzędzia, których jedynym zadaniem jest układanie elementów interfejsu w określony sposób. Do najbardziej przydatnych należy układ typu flow oraz układ tabelkowy. Ten pierwszy polega na rozmieszczaniu kontrolek po kolei (w ustalonym porządku) tak, jak wypisuje się tekst w kolejnych wierszach. (Jak widać, analogie tekstowe w projektowaniu interfejsu pojawiają się całkiem często ;]). Z kolei układ tabelkowy, jak nazwa wskazuje, dzieli zadany obszar na wiersze i kolumny tak, że w każdej z powstałych w ten sposób komórek mieści się dokładnie jedna kontrolką i wypełnia ją całkowicie.
    Układy mają spore zastosowanie zwłaszcza wtedy, gdy rozmieszczane kontrolki są tworzone dynamicznie w trakcie działania programu. Potrafią wówczas zaoszczędzić dużo pracy z ręcznym przeliczaniem ich pozycji i/lub rozmiarów.

To stwierdzenie odnosi się zresztą do każdego z tych trzech sposobów na określanie wymiarów elementu interfejsu. Obecnie bardzo często okazuje się, że nawet stosunkowo zaawansowany układ kontrolek, który musi dostosowywać się do zmian rozmiaru okna, da się stworzyć bez obsługiwania zdarzeń typu OnResize i ręcznego rozmieszczania komponentów. A to może oszczędzić kilku kłopotów i pozwala łatwiej skoncentrować się na tych częściach programu, których wprawdzie nie widać, ale które są o wiele ważniejsze :)

Tags: , , ,
Author: Xion, posted under Programming » 1 comment
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.