Skip to main content

UI: Footer – Stopka

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

markac

Full-stack Web Developer

4 thoughts to “UI: Footer – Stopka”

  1. 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.

    1. 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 🙂

Komentarze są zamknięte.