/* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. * * This file is part of PortaPack. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #ifndef __UI_H__ #define __UI_H__ #include namespace ui { #define DEG_TO_RAD(d) (d * (2 * pi) / 360.0) using Coord = int16_t; using Dim = int16_t; struct Color { uint16_t v; // rrrrrGGGGGGbbbbb constexpr Color( ) : v { 0 } { } constexpr Color( uint16_t v ) : v { v } { } constexpr Color( uint8_t r, uint8_t g, uint8_t b ) : v { static_cast( ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3) )} { } uint8_t to_greyscale() { uint32_t r = ((v >> 11) & 31U) << 3; uint32_t g = ((v >> 5) & 63U) << 2; uint32_t b = (v & 31U) << 3; uint32_t grey = (r * 299 + g * 587 + b * 114) / 1000; return (uint8_t)grey; } Color operator-() const { return (v ^ 0xffff); } static constexpr Color black() { return { 0, 0, 0 }; } static constexpr Color red() { return { 255, 0, 0 }; } static constexpr Color dark_red() { return { 159, 0, 0 }; } static constexpr Color orange() { return { 255, 175, 0 }; } static constexpr Color dark_orange() { return { 191, 95, 0 }; } static constexpr Color yellow() { return { 255, 255, 0 }; } static constexpr Color dark_yellow() { return { 191, 191, 0 }; } static constexpr Color green() { return { 0, 255, 0 }; } static constexpr Color dark_green() { return { 0, 159, 0 }; } static constexpr Color blue() { return { 0, 0, 255 }; } static constexpr Color dark_blue() { return { 0, 0, 191 }; } static constexpr Color cyan() { return { 0, 255, 255 }; } static constexpr Color dark_cyan() { return { 0, 191, 191 }; } static constexpr Color magenta() { return { 255, 0, 255 }; } static constexpr Color dark_magenta() { return { 191, 0, 191 }; } static constexpr Color white() { return { 255, 255, 255 }; } static constexpr Color light_grey() { return { 191, 191, 191 }; } static constexpr Color grey() { return { 127, 127, 127 }; } static constexpr Color dark_grey() { return { 63, 63, 63 }; } static constexpr Color purple() { return { 204, 0, 102 }; } }; extern Color term_colors[16]; struct ColorRGB888 { uint8_t r; uint8_t g; uint8_t b; }; struct Point { private: Coord _x; Coord _y; public: constexpr Point( ) : _x { 0 }, _y { 0 } { } constexpr Point( int x, int y ) : _x { static_cast(x) }, _y { static_cast(y) } { } constexpr int x() const { return _x; } constexpr int y() const { return _y; } constexpr Point operator-() const { return { -_x, -_y }; } constexpr Point operator+(const Point& p) const { return { _x + p._x, _y + p._y }; } constexpr Point operator-(const Point& p) const { return { _x - p._x, _y - p._y }; } Point& operator+=(const Point& p) { _x += p._x; _y += p._y; return *this; } Point& operator-=(const Point& p) { _x -= p._x; _y -= p._y; return *this; } }; struct Size { private: Dim _w; Dim _h; public: constexpr Size( ) : _w { 0 }, _h { 0 } { } constexpr Size( int w, int h ) : _w { static_cast(w) }, _h { static_cast(h) } { } int width() const { return _w; } int height() const { return _h; } bool is_empty() const { return (_w < 1) || (_h < 1); } }; struct Rect { private: Point _pos; Size _size; public: constexpr Rect( ) : _pos { }, _size { } { } constexpr Rect( int x, int y, int w, int h ) : _pos { x, y }, _size { w, h } { } constexpr Rect( Point pos, Size size ) : _pos(pos), _size(size) { } Point location() const { return _pos; } Size size() const { return _size; } int top() const { return _pos.y(); } int bottom() const { return _pos.y() + _size.height(); } int left() const { return _pos.x(); } int right() const { return _pos.x() + _size.width(); } int width() const { return _size.width(); } int height() const { return _size.height(); } Point center() const { return { _pos.x() + _size.width() / 2, _pos.y() + _size.height() / 2 }; } bool is_empty() const { return _size.is_empty(); } bool contains(const Point p) const; Rect intersect(const Rect& o) const; Rect operator+(const Point& p) const { return { _pos + p, _size }; } Rect& operator+=(const Rect& p); Rect& operator+=(const Point& p); Rect& operator-=(const Point& p); operator bool() const { return !_size.is_empty(); } }; struct Bitmap { const Size size; const uint8_t* const data; }; enum class KeyEvent { /* Ordinals map to bit positions reported by CPLD */ Right = 0, Left = 1, Down = 2, Up = 3, Select = 4, Dfu = 5, Back = 6, /* Left and Up together */ }; using EncoderEvent = int32_t; struct TouchEvent { enum class Type : uint32_t { Start = 0, Move = 1, End = 2, }; Point point; Type type; }; Point polar_to_point(float angle, uint32_t distance); Point fast_polar_to_point(int32_t angle, uint32_t distance); } /* namespace ui */ #endif/*__UI_H__*/