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 !