From 6d2cbf71b65fcb9bb156d9204e0051c3277c15db Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 28 Nov 2019 17:03:56 +0100 Subject: [PATCH] New Table widget --- .../thirdparty/libopenui/src/CMakeLists.txt | 1 + .../libopenui/src/libopenui_defines.h | 5 +- .../libopenui/src/libopenui_file.cpp | 1 - radio/src/thirdparty/libopenui/src/static.h | 17 +- radio/src/thirdparty/libopenui/src/table.cpp | 50 ++++++ radio/src/thirdparty/libopenui/src/table.h | 157 ++++++++++++++++++ radio/src/thirdparty/libopenui/src/window.cpp | 20 +-- 7 files changed, 233 insertions(+), 18 deletions(-) create mode 100644 radio/src/thirdparty/libopenui/src/table.cpp create mode 100644 radio/src/thirdparty/libopenui/src/table.h diff --git a/radio/src/thirdparty/libopenui/src/CMakeLists.txt b/radio/src/thirdparty/libopenui/src/CMakeLists.txt index e6c7c273f..f3b9ef290 100644 --- a/radio/src/thirdparty/libopenui/src/CMakeLists.txt +++ b/radio/src/thirdparty/libopenui/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(LIBOPENUI_SRC textedit.cpp coloredit.cpp progress.cpp + table.cpp dialog.cpp message_dialog.cpp ) diff --git a/radio/src/thirdparty/libopenui/src/libopenui_defines.h b/radio/src/thirdparty/libopenui/src/libopenui_defines.h index f1a7a26ae..e6b4aba39 100644 --- a/radio/src/thirdparty/libopenui/src/libopenui_defines.h +++ b/radio/src/thirdparty/libopenui/src/libopenui_defines.h @@ -83,7 +83,7 @@ #endif #define OPACITY_MAX 0x0F -#define OPACITY(x) ((x)<<24) +#define OPACITY(value) ((value) << 24) #define RGB(r, g, b) (uint16_t)((((r) & 0xF8) << 8) + (((g) & 0xFC) << 3) + (((b) & 0xF8) >> 3)) #define ARGB(a, r, g, b) (uint16_t)((((a) & 0xF0) << 8) + (((r) & 0xF0) << 4) + (((g) & 0xF0) << 0) + (((b) & 0xF0) >> 4)) @@ -101,9 +101,12 @@ #define SCROLLBAR_COLOR COLOR(SCROLLBAR_COLOR_INDEX) #define MENU_COLOR COLOR(MENU_COLOR_INDEX) #define MENU_BGCOLOR COLOR(MENU_BGCOLOR_INDEX) +#define MENU_TITLE_BGCOLOR COLOR(MENU_TITLE_BGCOLOR_INDEX) #define MENU_LINE_COLOR COLOR(MENU_LINE_COLOR_INDEX) #define MENU_HIGHLIGHT_COLOR COLOR(MENU_HIGHLIGHT_COLOR_INDEX) #define MENU_HIGHLIGHT_BGCOLOR COLOR(MENU_HIGHLIGHT_BGCOLOR_INDEX) +#define TABLE_BGCOLOR COLOR(TABLE_BGCOLOR_INDEX) +#define TABLE_HEADER_BGCOLOR COLOR(TABLE_HEADER_BGCOLOR_INDEX) #define CUSTOM_COLOR COLOR(CUSTOM_COLOR_INDEX) #endif diff --git a/radio/src/thirdparty/libopenui/src/libopenui_file.cpp b/radio/src/thirdparty/libopenui/src/libopenui_file.cpp index 83bfa1caa..1cdb76061 100644 --- a/radio/src/thirdparty/libopenui/src/libopenui_file.cpp +++ b/radio/src/thirdparty/libopenui/src/libopenui_file.cpp @@ -107,4 +107,3 @@ FRESULT sdReadDir(DIR * dir, FILINFO * fno, bool & firstTime) firstTime = false; return res; } - diff --git a/radio/src/thirdparty/libopenui/src/static.h b/radio/src/thirdparty/libopenui/src/static.h index 6e5e1a196..46ae5e06d 100644 --- a/radio/src/thirdparty/libopenui/src/static.h +++ b/radio/src/thirdparty/libopenui/src/static.h @@ -67,6 +67,11 @@ class Subtitle: public StaticText { class StaticBitmap: public Window { public: + StaticBitmap(Window * parent, const rect_t & rect): + Window(parent, rect) + { + } + StaticBitmap(Window * parent, const rect_t & rect, const char * filename): Window(parent, rect), bitmap(BitmapBuffer::loadBitmap(filename)) @@ -79,6 +84,12 @@ class StaticBitmap: public Window { { } + void setBitmap(const char * filename) + { + bitmap = BitmapBuffer::loadBitmap(filename); + invalidate(); + } + #if defined(DEBUG_WINDOWS) std::string getName() override { @@ -88,11 +99,13 @@ class StaticBitmap: public Window { void paint(BitmapBuffer * dc) override { - dc->drawBitmap(0, 0, bitmap); + if (bitmap) { + dc->drawBitmap((width() - bitmap->width()) / 2, (height() - bitmap->height()) / 2, bitmap); + } } protected: - const BitmapBuffer * bitmap; + const BitmapBuffer * bitmap = nullptr; }; #endif diff --git a/radio/src/thirdparty/libopenui/src/table.cpp b/radio/src/thirdparty/libopenui/src/table.cpp new file mode 100644 index 000000000..db8d5cf7d --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/table.cpp @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#include "table.h" +#include "font.h" + +void Table::Header::paint(BitmapBuffer * dc) +{ + coord_t x = 10; + if (!header.values.empty()) { + dc->clear(TABLE_HEADER_BGCOLOR); + for (auto &value: header.values) { + dc->drawText(x, (TABLE_LINE_HEIGHT - getFontHeight(TABLE_HEADER_FONT)) / 2, value.c_str(), TABLE_HEADER_FONT); + x += 200; + } + } +} + +void Table::Body::paint(BitmapBuffer * dc) +{ + coord_t y = 0; + coord_t x; + int index = 0; + for (auto &line: lines) { + dc->drawSolidFilledRect(0, y, width(), TABLE_LINE_HEIGHT - 2, index == selection ? FOCUS_BGCOLOR : TABLE_BGCOLOR); + x = 10; + for (auto &value: line.values) { + dc->drawText(x, y + (TABLE_LINE_HEIGHT - getFontHeight(TABLE_BODY_FONT)) / 2 + 3, value.c_str(), TABLE_BODY_FONT | (index == selection ? FOCUS_COLOR : DEFAULT_COLOR)); + x += 200; + } + y += TABLE_LINE_HEIGHT; + index += 1; + } +} diff --git a/radio/src/thirdparty/libopenui/src/table.h b/radio/src/thirdparty/libopenui/src/table.h new file mode 100644 index 000000000..87c6c16a6 --- /dev/null +++ b/radio/src/thirdparty/libopenui/src/table.h @@ -0,0 +1,157 @@ +/* + * 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. + */ + +#ifndef _TABLE_H_ +#define _TABLE_H_ + +#include "window.h" +#include + +constexpr coord_t TABLE_LINE_HEIGHT = 50; +constexpr coord_t TABLE_HEADER_HEIGHT = 48; + +class Table: public Window { + + class Line { + public: + std::list values; + std::function onPress; + }; + + class Header: public Window { + public: + Header(Window * parent, const rect_t & rect): + Window(parent, rect, OPAQUE) + { + } + + void setLine(const Line & line) + { + header = line; + } + + void paint(BitmapBuffer * dc) override; + + protected: + Line header; + }; + + class Body: public Window { + friend class Table; + + public: + Body(Window * parent, const rect_t & rect): + Window(parent, rect, OPAQUE) + { + } + + void addLine(const Line & line) + { + lines.push_back(line); + setInnerHeight(lines.size() * TABLE_LINE_HEIGHT - 2); + } + + void clear() + { + lines.clear(); + } + + void paint(BitmapBuffer * dc) override; + +#if defined(HARDWARE_TOUCH) + bool onTouchEnd(coord_t x, coord_t y) + { + unsigned index = y / TABLE_LINE_HEIGHT; + auto onPress = lines[index].onPress; + if (onPress) + onPress(); + return true; + } +#endif + + protected: + std::vector lines; + int selection = -1; + }; + + public: + Table(Window * parent, const rect_t & rect, uint8_t columnsCount): + Window(parent, rect), + header(this, {0, 0, width(), TABLE_HEADER_HEIGHT}), + body(this, {0, TABLE_HEADER_HEIGHT, width(), height() - TABLE_HEADER_HEIGHT}) + { + setColumnsCount(columnsCount); + } + + ~Table() override + { + header.detach(); + body.detach(); + } + + void setColumnsCount(uint8_t value) + { + count = value; + } + + int getSelection() const + { + return body.selection; + } + + void setSelection(int index, bool scroll = false) + { + body.selection = index; + if (scroll) { + body.setScrollPositionY(index * TABLE_LINE_HEIGHT); + } + body.invalidate(); + } + + void setHeader(const char * values[]) + { + Line line; + for (uint8_t i = 0; i < count; i++) { + line.values.push_back(values[i]); + } + header.setLine(line); + } + + void addLine(const char * values[], std::function onPress = nullptr) + { + Line line; + for (uint8_t i = 0; i < count; i++) { + line.values.push_back(values[i]); + } + line.onPress = onPress; + body.addLine(line); + } + + void clear() + { + body.clear(); + } + + protected: + uint8_t count = 1; + Header header; + Body body; +}; + +#endif // _TABLE_H_ diff --git a/radio/src/thirdparty/libopenui/src/window.cpp b/radio/src/thirdparty/libopenui/src/window.cpp index 9c151f722..1accc4896 100644 --- a/radio/src/thirdparty/libopenui/src/window.cpp +++ b/radio/src/thirdparty/libopenui/src/window.cpp @@ -405,20 +405,12 @@ void Window::invalidate(const rect_t & rect) void Window::drawVerticalScrollbar(BitmapBuffer * dc) { if (innerHeight > rect.h) { - coord_t x = rect.w - 3; - coord_t y = scrollPositionY + 3; - coord_t h = rect.h - 6; - // lcd->drawSolidFilledRect(x, y, 1, h, LINE_COLOR); - coord_t yofs = (h*scrollPositionY + innerHeight/2) / innerHeight; - coord_t yhgt = (h*rect.h + innerHeight/2) / innerHeight; - if (yhgt + yofs > h) - yhgt = h - yofs; - if (yhgt < 15) { + coord_t yofs = divRoundClosest(rect.h * scrollPositionY, innerHeight); + coord_t yhgt = divRoundClosest(rect.h * rect.h, innerHeight); + if (yhgt < 15) yhgt = 15; - if (y + yofs + yhgt > innerHeight) { - yofs = innerHeight - y - yhgt; - } - } - dc->drawSolidFilledRect(x-1, y + yofs, 3, yhgt, SCROLLBAR_COLOR); + if (yhgt + yofs > rect.h) + yhgt = rect.h - yofs; + dc->drawSolidFilledRect(rect.w - SCROLLBAR_WIDTH, scrollPositionY + yofs, SCROLLBAR_WIDTH, yhgt, SCROLLBAR_COLOR); } }