236 lines
5.1 KiB
C++
236 lines
5.1 KiB
C++
/*
|
|
* Copyright (C) OpenTX
|
|
*
|
|
* Source:
|
|
* https://github.com/opentx/libopenui
|
|
*
|
|
* This file is a part of libopenui library.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "window.h"
|
|
|
|
constexpr WindowFlags FORM_FORWARD_FOCUS = WINDOW_FLAGS_LAST << 1;
|
|
constexpr WindowFlags FORM_DETACHED = WINDOW_FLAGS_LAST << 2;
|
|
constexpr WindowFlags FORM_BORDER_FOCUS_ONLY = WINDOW_FLAGS_LAST << 3;
|
|
constexpr WindowFlags FORM_NO_BORDER = WINDOW_FLAGS_LAST << 4;
|
|
constexpr WindowFlags FORM_FLAGS_LAST = FORM_NO_BORDER;
|
|
|
|
class FormField: public Window
|
|
{
|
|
public:
|
|
FormField(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0, LcdFlags textFlags = 0);
|
|
|
|
virtual void changeEnd(bool forceChanged = false)
|
|
{
|
|
if (changeHandler) {
|
|
changeHandler();
|
|
}
|
|
}
|
|
|
|
void setChangeHandler(std::function<void()> handler)
|
|
{
|
|
changeHandler = std::move(handler);
|
|
}
|
|
|
|
void setBackgroundHandler(std::function<uint32_t(FormField *field)> handler)
|
|
{
|
|
backgroundHandler = std::move(handler);
|
|
}
|
|
|
|
inline void setNextField(FormField *field)
|
|
{
|
|
next = field;
|
|
}
|
|
|
|
inline void setPreviousField(FormField * field)
|
|
{
|
|
previous = field;
|
|
}
|
|
|
|
inline FormField * getPreviousField()
|
|
{
|
|
return previous;
|
|
}
|
|
|
|
inline FormField * getNextField()
|
|
{
|
|
return next;
|
|
}
|
|
|
|
inline bool isEditMode() const
|
|
{
|
|
return editMode;
|
|
}
|
|
|
|
virtual void setEditMode(bool newEditMode)
|
|
{
|
|
editMode = newEditMode;
|
|
invalidate();
|
|
}
|
|
|
|
void enable(bool value = true)
|
|
{
|
|
enabled = value;
|
|
invalidate();
|
|
}
|
|
|
|
bool isEnabled() const
|
|
{
|
|
return enabled;
|
|
}
|
|
|
|
void disable()
|
|
{
|
|
enable(false);
|
|
}
|
|
|
|
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override;
|
|
|
|
void onFocusLost() override
|
|
{
|
|
setEditMode(false);
|
|
Window::onFocusLost();
|
|
}
|
|
|
|
inline static void link(FormField * previous, FormField * next)
|
|
{
|
|
previous->setNextField(next);
|
|
next->setPreviousField(previous);
|
|
}
|
|
|
|
void paint(BitmapBuffer * dc) override;
|
|
|
|
#if defined(HARDWARE_KEYS)
|
|
void onEvent(event_t event) override;
|
|
#endif
|
|
|
|
protected:
|
|
FormField * next = nullptr;
|
|
FormField * previous = nullptr;
|
|
bool editMode = false;
|
|
bool enabled = true;
|
|
std::function<void()> changeHandler = nullptr;
|
|
std::function<uint32_t(FormField *)> backgroundHandler = nullptr;
|
|
};
|
|
|
|
class FormGroup: public FormField
|
|
{
|
|
public:
|
|
FormGroup(Window * parent, const rect_t & rect, WindowFlags windowflags = 0) :
|
|
FormField(parent, rect, windowflags)
|
|
{
|
|
}
|
|
|
|
#if defined(DEBUG_WINDOWS)
|
|
std::string getName() const override
|
|
{
|
|
return "FormGroup";
|
|
}
|
|
#endif
|
|
|
|
void clear()
|
|
{
|
|
Window::clear();
|
|
first = nullptr;
|
|
last = nullptr;
|
|
if (previous && (windowFlags & FORM_FORWARD_FOCUS)) {
|
|
previous->setNextField(this);
|
|
}
|
|
}
|
|
|
|
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override;
|
|
|
|
virtual void addField(FormField * field, bool front = false);
|
|
|
|
virtual void removeField(FormField * field);
|
|
|
|
void setFirstField(FormField * field)
|
|
{
|
|
first = field;
|
|
}
|
|
|
|
void setLastField(FormField * field)
|
|
{
|
|
last = field;
|
|
}
|
|
|
|
FormField * getFirstField() const
|
|
{
|
|
return first;
|
|
}
|
|
|
|
FormField * getLastField() const
|
|
{
|
|
return last;
|
|
}
|
|
|
|
void setFocusOnFirstVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
|
|
{
|
|
auto field = getFirstField();
|
|
while (field && !field->isInsideParentScrollingArea()) {
|
|
field = field->getNextField();
|
|
}
|
|
if (field) {
|
|
field->setFocus(flag);
|
|
}
|
|
}
|
|
|
|
void setFocusOnLastVisibleField(uint8_t flag = SET_FOCUS_DEFAULT) const
|
|
{
|
|
auto field = getLastField();
|
|
while (field && !field->isInsideParentScrollingArea()) {
|
|
field = field->getPreviousField();
|
|
}
|
|
if (field) {
|
|
field->setFocus(flag);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
FormField * first = nullptr;
|
|
FormField * last = nullptr;
|
|
|
|
#if defined(HARDWARE_KEYS)
|
|
void onEvent(event_t event) override;
|
|
#endif
|
|
|
|
void paint(BitmapBuffer * dc) override;
|
|
};
|
|
|
|
class FormWindow: public FormGroup
|
|
{
|
|
public:
|
|
FormWindow(Window * parent, const rect_t & rect, WindowFlags windowFlags = 0) :
|
|
FormGroup(parent, rect, windowFlags)
|
|
{
|
|
}
|
|
|
|
#if defined(DEBUG_WINDOWS)
|
|
std::string getName() const override
|
|
{
|
|
return "FormWindow";
|
|
}
|
|
#endif
|
|
|
|
protected:
|
|
void paint(BitmapBuffer *) override
|
|
{
|
|
}
|
|
|
|
#if defined(HARDWARE_KEYS)
|
|
void onEvent(event_t event) override;
|
|
#endif
|
|
};
|