Jedną z nowości jaką wprowadza nowe SDK 2.0 w stosunku do starszej wersji jest kontrolka Footer i Header.
Artykuł dotyczy tej pierwszej, więc tylko na tej kontrolce się skupimy.
W starszych wersjach SDK w stopce formularza mogliśmy mieć tylko rozwijane menu OptionMenu.
Niektórzy bardzo sobie chwalili wysuwane menu w odróżnieniu od nowej kontroli Footer, która podobno zabiera więcej przestrzeni formularza i jest cały czas widoczna.
My nie będziemy prowadzili wojny na ten temat, a nauczymy się korzystać z dobrodziejstw nowych kontrolek.
Tworzymy nowy projekt o nazwie FooterSample typu bada Form Based Application o rozdzielczości (Model) WaveWVGA.
Właśnie stworzyliśmy nowy projekt z przykładowym formularzem. Klikamy go podwójnie w oknie Resource.
Nasz formularz powinien wyglądać jak na poniższym obrazku.
W zakładce Properties znajdujemy właściwość ShowFooter i ustawiamy na True. Wcześniej powinniśmy zaznaczyć nasz formularz np. w oknie Outline.
Każdy z nas ma zapewne inaczej skonfigurowane środowisko programistyczne i rozmieszczenie okien, więc nie piszę dokładnie, gdzie je można znaleźć.
Na dole naszego formularza pojawi się pusta kontrolka Footer. Klikamy na nią i z okna parametrów Properties decydujemy o jej stylu:
Kontrolka może wyglądać na wiele sposobów. Oto pełna lista stylów:
1. FOOTER_STYLE_BUTTON_TEXT – przyciski tekstowe
2. FOOTER_STYLE_BUTTON_ICON – przyciski z ikonkami
3. FOOTER_STYLE_SEGMENTED_* – stopka dzielona na segmenty
4. FOOTER_STYLE_TAB – zakładki
Na potrzeby naszego programu wybieramy styl FOOTER_STYLE_BUTTON_TEXT.
Aby dodać przyciski należy wybrać z okienka ToolBox kontrolkę FooterItem i przeciągnąć na nasz Footer na formularzu.
Powtarzamy operacje dwa razy, aby dodać dwa przyciski. W oknie Outliline powinniśmy widzieć nasze przyciski:
Dla każdego z nich ustawiamy atrybuty w oknie Properties, jak Text i Action ID.
Nasze przyciski powinny posiadać następujące atrybuty:
Przycisk FOOTERITEM1:
Action ID = 100
Text = Button 1
Przycisk FOOTERITEM2:
Action ID = 101
Text = Button 2
Action ID to identyfikator akcji naszego przycisku, w większości unikalny w obrębie formularza lub aplikacji. Przyjmuje się numerację od 100 dla identyfikatorów definiowanych przez użytkownika.
Dobrą praktyką jest ustawianie identyfikatorów w kodzie przypisując je do stałych, a następnie do przycisków podczas inicjalizacji formularza, tak jak to jest z domyślnym przyciskiem w naszym projekcie.
Po skompilowaniu i uruchomieniu naszego programu powinniśmy zobaczyć taki formularz:
Jak na razie idzie gładko 🙂 Zrobiliśmy tak wiele, a nie musieliśmy napisać nawet jednej linii kodu… Tak być nie może! 🙂
Sam wygląd to nie wszystko. Teraz trzeba obsłużyć zdarzenia od naszych przycisków i wykonać odpowiednie akcje, jakie są przewidziane dla naszych przycisków.
W oknie Project Explorer odnajdujemy plik Form1.h.
Odnajdujemy fragment z deklaracjami z widocznością protected i dopisujemy zmienną przechowującą wskaźnik do kontrolki Footer (linia 7):
// Implementation protected: static const int ID_BUTTON_OK = 101; Osp::Ui::Controls::Button *__pButtonOk; // Dopisujemy poniższą linię Osp::Ui::Controls::Footer* __pFooter;
Następnie otwieramy plik Form1.cpp i w funkcji OnInitializing(void) dopisujemy linię 16 i 17:
result Form1::OnInitializing(void) { result r = E_SUCCESS; // TODO: Add your initialization code here // Get a button via resource ID __pButtonOk = static_cast<Button *>(GetControl(L"IDC_BUTTON_OK")); if (__pButtonOk != null) { __pButtonOk->SetActionId(ID_BUTTON_OK); __pButtonOk->AddActionEventListener(*this); } __pFooter = GetFooter(); __pFooter->AddActionEventListener(*this); return r; }
Nasz przykładowy projekt domyślnie implementuje interfejs Osp::Ui::IActionEventListener, dlatego nie musimy go ręcznie implementować.
Interfejs ten wymaga implementacji funkcji obsługi zdarzeń:
virtual void OnActionPerformed (const Osp::Ui::Control &source, int actionId)=0
która to już istnieje, a jej implementacja na chwilę obecną w pliku Form1.cpp wygląda następująco:
void Form1::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case ID_BUTTON_OK: { AppLog("OK Button is clicked! n"); } break; default: break; } }
Chcę ostrzec, że domyślny projekt zawiera przycisk, który posiada identyfikator 101, więc będzie kolidował z naszymi przyciskami w Footer, a dokładnie z drugim przyciskiem.
Powinieneś zadbać o to, żeby identyfikatory były unikalne.
Modyfikujemy powyższą funkcję o obsługę dodatkowych zdarzeń naszych przycisków:
void Form1::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case 100: { AppLog("Button 1 is clicked!"); } break; case 101: { AppLog("Button 2 is clicked!"); } break; default: break; } }
Uruchamiamy nasz projekt i testujemy klikając kolejno pierwszy i drugi przycisk. W konsoli Outout powinniśmy ujrzeć następujące komunikaty świadczące o poprawnej implementacji zdarzeń:
A co z przyciskiem Back? Oczywiście możemy go dodać, ale tylko programowo.
Nasz formularz Form1 powinien implementować interfejs Osp::Ui::Controls::IFormBackEventListener. W pliku Form1.h dodajemy linię 5:
class Form1 : public Osp::Ui::Controls::Form, public Osp::Ui::IActionEventListener, public Osp::Ui::IKeyEventListener, public Osp::Ui::Controls::IFormBackEventListener {
Za słowem kluczowym public deklarujemy funkcję:
// IFormBackEventListener virtual void OnFormBackRequested(Osp::Ui::Controls::Form &source);
W pliku Form1.cpp w funkcji OnInitializing(void) za linią 17 dopisujemy:
__pFooter->SetBackButton(); SetFormBackEventListener(this);
a następnie implementujemy (dopisujemy do pliku Form1.cpp) funkcję OnFormBackRequested():
// IFormBackEventListener void Form1::OnFormBackRequested(Osp::Ui::Controls::Form &source) { AppLog("Back button pressed."); }
Nasza ostateczna aplikacja powinna wyglądać tak:
Obsługa zdarzenia – kliknięcie przycisku Back – zostanie zakomunikowana w okienku Output:
Pozostało nam jeszcze dowiedzieć się, jak programowo dodać nowe przyciski, ustawić Text i Action ID. W funkcji OnInitializing() dopisujemy:
FooterItem footerButton3; footerButton3.Construct(102); // Action Id footerButton3.SetText(L"Button 3"); __pFooter->AddItem(footerButton3);
Trzeci przycisk został dodany. Jeśli chcesz modyfikować atrybuty nowego przycisku podczas działania aplikacji, nie ma metody, która pobierałaby przycisk z Footer.
Co więcej, metoda AddItem tworzy kopie przycisku i dalsze operowanie na wskaźniku lub bezpośrednio na obiekcie footerButton3 jak w tym przypadku nic nie da.
Trzeba go usunąć, ponownie dodać a następnie odrysować Footer:
__pFooter->RequestRedraw();
Pobierz projekt: FooterSample.zip
Zalety projektowania Ui
– prostota tworzenia,
Wady
– problemy z komunikacją pomiędzy elementami ui a kodem – brak możliwości programowej zmiany niektórych właściwości wstawionych elementów.
Problemy z komunikacją w tym wypadku przypadku nie są za sprawą tworzenia UI przez UI Builder’a. Jakbyśmy programowo dodali te przyciski do stopki, to i tak nie da się ich wyedytować, ale można usunąć wybrany przycisk i wstawić nowy na wybraną przez siebie pozycje, więc można to przeżyć. Trzeba tak zaprojektować aplikację, żeby te przyciski się nie rotowały, a były stałe 🙂
Bardzo przydatny poradnik
pierwszorzędny poradnik ! tego szukałem . Dzięki !