mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-29 16:31:05 +02:00
TODO: make custom colors themable
Origin commit data
------------------
Branch: ni/coolstream
Commit: 1da3f5ef61
Author: vanhofen <vanhofen@gmx.de>
Date: 2021-11-19 (Fri, 19 Nov 2021)
Origin message was:
------------------
- colors_custom: rework colors; use Google Material Palette
TODO: make custom colors themable
------------------
This commit was generated by Migit
453 lines
15 KiB
C++
453 lines
15 KiB
C++
/*
|
|
Based up Neutrino-GUI - Tuxbox-Project
|
|
Copyright (C) 2001 by Steffen Hehn 'McClean'
|
|
|
|
Classes for generic GUI-related components.
|
|
Copyright (C) 2013-2017, Thilo Graf 'dbt'
|
|
|
|
License: GPL
|
|
|
|
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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <neutrino.h>
|
|
#include <gui/color_custom.h>
|
|
#include "cc_frm_footer.h"
|
|
#include <system/debug.h>
|
|
#include <driver/fontrenderer.h>
|
|
|
|
using namespace std;
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
//sub class CComponentsFooter inherit from CComponentsHeader
|
|
CComponentsFooter::CComponentsFooter(CComponentsForm* parent):CCButtonSelect()
|
|
{
|
|
//CComponentsFooter
|
|
initVarFooter(1, 1, 0, 0, 0, parent, CC_SHADOW_OFF, COL_FRAME_PLUS_0, COL_MENUFOOT_PLUS_0, COL_SHADOW_PLUS_0, CC_HEADER_SIZE_LARGE);
|
|
}
|
|
|
|
CComponentsFooter::CComponentsFooter( const int& x_pos, const int& y_pos, const int& w, const int& h,
|
|
const int& buttons,
|
|
CComponentsForm* parent,
|
|
int shadow_mode,
|
|
fb_pixel_t color_frame,
|
|
fb_pixel_t color_body,
|
|
fb_pixel_t color_shadow,
|
|
int sizeMode):CCButtonSelect()
|
|
{
|
|
//CComponentsFooter
|
|
initVarFooter(x_pos, y_pos, w, h, buttons, parent, shadow_mode, color_frame, color_body, color_shadow, sizeMode);
|
|
}
|
|
|
|
void CComponentsFooter::initVarFooter( const int& x_pos, const int& y_pos, const int& w, const int& h,
|
|
const int& buttons,
|
|
CComponentsForm* parent,
|
|
int shadow_mode,
|
|
fb_pixel_t color_frame,
|
|
fb_pixel_t color_body,
|
|
fb_pixel_t color_shadow,
|
|
int sizeMode)
|
|
{
|
|
cc_item_type.id = CC_ITEMTYPE_FOOTER;
|
|
cc_item_type.name = "cc_footer";
|
|
|
|
x = cc_xr = cc_xr_old = x_old = x_pos;
|
|
y = cc_yr = cc_yr_old = y_old = y_pos;
|
|
|
|
//init footer width
|
|
width = width_old = w == 0 ? frameBuffer->getScreenWidth(true) : w;
|
|
|
|
cch_font = NULL;
|
|
cch_size_mode = sizeMode;
|
|
|
|
//init font and height
|
|
initSizeMode();
|
|
if (h)
|
|
setHeight(h);
|
|
|
|
//init default button text font
|
|
ccf_btn_font = g_Font[SNeutrinoSettings::FONT_TYPE_BUTTON_TEXT];
|
|
|
|
shadow = shadow_mode;
|
|
ccf_enable_button_shadow = false ;
|
|
ccf_button_shadow_width = shadow ? OFFSET_SHADOW/2 : 0;
|
|
ccf_button_shadow_force_paint = false;
|
|
ccf_button_container_y = -1; //centered as default
|
|
col_frame = color_frame;
|
|
col_body_std = color_body;
|
|
col_shadow = color_shadow;
|
|
cc_body_gradient_enable = cc_body_gradient_enable_old = CC_COLGRAD_OFF/*g_settings.theme.menu_ButtonBar_gradient*/; //TODO: not complete implemented at the moment
|
|
cc_body_gradient_direction = CFrameBuffer::gradientVertical;
|
|
cc_body_gradient_mode = CColorGradient::gradientDark2Light;
|
|
btn_auto_frame_col = false; //TODO: currently global disabled
|
|
|
|
corner_rad = RADIUS_LARGE;
|
|
corner_type = CORNER_BOTTOM;
|
|
|
|
ccf_enable_button_bg = false /*g_settings.theme.Button_gradient*/; //TODO: not implemented at the moment
|
|
|
|
addContextButton(buttons);
|
|
initCCItems();
|
|
initParent(parent);
|
|
|
|
//init repaint slot before re paint of body, if paint() is already done
|
|
initRepaintSlot();
|
|
}
|
|
|
|
int CComponentsFooter::initButtonContainer(const int& chain_width)
|
|
{
|
|
/*
|
|
* Button container contains all passed button label items and
|
|
* represents the parent for button labels and is working as single child object inside footer.
|
|
*/
|
|
|
|
/* clean up before init */
|
|
if (btn_container){
|
|
removeCCItem(btn_container);
|
|
btn_container = NULL;
|
|
}
|
|
|
|
/*
|
|
* Check and init parameter 'chain_width':
|
|
*
|
|
* Set usable basic space for button container,
|
|
* Default width of container is footer width minus width of all containing items and offsets inside footer object.
|
|
*/
|
|
int dx_used = 0;
|
|
for (size_t i = 0; i< size(); i++){
|
|
if (getCCItem(i) != btn_container) // avoid to point on button container itself!
|
|
dx_used -= getCCItem(i)->getWidth();
|
|
}
|
|
int dx_container_max = width - dx_used - 2*cch_offset;
|
|
int dx_container = min(width - 2*cch_offset, dx_container_max);
|
|
|
|
/*
|
|
* Initialize width and x position of button container
|
|
*/
|
|
int x_container = cch_offset;
|
|
|
|
if (cch_icon_obj)
|
|
{
|
|
int dx_icon_obj = cch_icon_obj->getWidth();
|
|
dx_container -= dx_icon_obj;
|
|
x_container += dx_icon_obj + cch_offset;
|
|
}
|
|
|
|
if (cch_text_obj)
|
|
if (!cch_text_obj->getText().empty())
|
|
{
|
|
dx_container -= cch_text_obj->getXPos() + cch_text_obj->getWidth();
|
|
dx_container -= cch_offset;
|
|
}
|
|
|
|
if (cch_btn_obj)
|
|
{
|
|
dx_container -= cch_btn_obj->getWidth();
|
|
dx_container -= cch_offset;
|
|
}
|
|
|
|
/*
|
|
* On defined parameter chain_width (means width of button container),
|
|
* compare and if required use current available space for button container depends of passed chain with parameter.
|
|
* Consider that chain_width is not too large. In this case parameter chain_width will be ignored.
|
|
*/
|
|
if (chain_width > 0)
|
|
{
|
|
if (chain_width > dx_container)
|
|
{
|
|
dprintf(DEBUG_INFO, "\033[33m[CComponentsFooter]\t[%s - %d], NOTE: chain_width [%d] too large, fallback to max allowed width [%d]\033[0m\n", __func__, __LINE__, chain_width, dx_container);
|
|
}
|
|
}
|
|
|
|
int dist = height/2-cch_offset;
|
|
int dy_container = ccf_btn_font->getHeight() > height+dist ? height-dist : ccf_btn_font->getHeight()+dist;
|
|
dy_container -= cc_parent ? (cc_parent->getFrameThickness()/2 - shadow_w) : 0; // if footer is embedded then consider possible frame around parent object (e.g. window)
|
|
int y_container = ccf_button_container_y < 0 ? height/2 - dy_container/2 : ccf_button_container_y;
|
|
|
|
if (btn_container == NULL){
|
|
btn_container = new CComponentsFrmChain(x_container, y_container, dx_container, dy_container, 0, CC_DIR_X, this, CC_SHADOW_OFF, COL_MENUCONTENT_PLUS_6, col_body_std);
|
|
btn_container->setItemName(cc_parent ? cc_parent->getItemName() + ":" + getItemName() + ":btn_container" : "");
|
|
btn_container->setAppendOffset(0, 0);
|
|
//btn_container->setCorner(this->corner_rad, this->corner_type);
|
|
btn_container->doPaintBg(false);
|
|
}
|
|
|
|
return dx_container;
|
|
}
|
|
|
|
void CComponentsFooter::setButtonLabels(const struct button_label_cc * const content, const size_t& label_count, const int& chain_width, const int& label_width)
|
|
{
|
|
/* init button container and get its usable width*/
|
|
int dx_container = initButtonContainer(chain_width);
|
|
|
|
if (label_count == 0)
|
|
return;
|
|
|
|
/* init global increments */
|
|
size_t l_count = label_count;
|
|
|
|
/*
|
|
* Evaluate parameter 'label_width':
|
|
*
|
|
* Button label width is default auto generated, if no label width is defined.
|
|
* If parameter label_width is too large, we use maximal possible value.
|
|
*/
|
|
int dx_btn = (dx_container - cch_offset * (int)l_count-1) / (int)l_count;
|
|
if (label_width)
|
|
if (label_width < dx_btn)
|
|
dx_btn = label_width;
|
|
|
|
/*
|
|
* Primary x postion of buttons inside button container is fix,
|
|
* height and y position of button labels are calculated by button container
|
|
* dimensions and have a fix value.
|
|
*/
|
|
int x_btn = 0;
|
|
int dy_btn = btn_container->getHeight()- 2*fr_thickness - ccf_button_shadow_width;
|
|
int y_btn = ccf_button_container_y < 0 ? btn_container->getHeight()/2 - dy_btn/2 : ccf_button_container_y;
|
|
|
|
/*
|
|
* Init button label objects
|
|
*/
|
|
for (size_t i = 0; i < l_count; i++){
|
|
/*
|
|
* init button label face values
|
|
*/
|
|
string txt = content[i].locale == NONEXISTANT_LOCALE ? content[i].text : g_Locale->getText(content[i].locale);
|
|
string icon_name = content[i].button ? string(content[i].button) : "";
|
|
|
|
/*
|
|
* Ignore item, if no text and no icon is defined.
|
|
*/
|
|
if (txt.empty() && icon_name.empty()){
|
|
//l_count -= 1;
|
|
dprintf(DEBUG_NORMAL, "[CComponentsFooter]\t[%s - %d]\tignore item [%zu], no icon and text defined!\n", __func__, __LINE__, i);
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* Create all button label objects and add to button container
|
|
* Set properties, like position, font, key values, coler etc...
|
|
*/
|
|
CComponentsButton *btn = new CComponentsButton(x_btn, y_btn, dx_btn, dy_btn, txt, icon_name, btn_container, false, true, ccf_enable_button_shadow);
|
|
btn->setButtonFont(NULL/*ccf_btn_font*/); // ensure init font type by item itself
|
|
btn->doPaintBg(ccf_enable_button_bg);
|
|
|
|
x_btn += btn_container->getCCItem(i)->getWidth();
|
|
x_btn += cch_offset;
|
|
|
|
btn->setButtonDirectKeys(content[i].directKeys);
|
|
btn->setButtonResult(content[i].btn_result);
|
|
btn->setButtonAlias(content[i].btn_alias);
|
|
|
|
btn->doPaintBg(true);
|
|
|
|
/*
|
|
* Set button frames to icon color, predefined for available color buttons
|
|
*/
|
|
if (btn_auto_frame_col){
|
|
fb_pixel_t f_col = btn->getColorFrame();
|
|
if (icon_name == NEUTRINO_ICON_BUTTON_RED)
|
|
f_col = COL_DARK_RED;
|
|
if (icon_name == NEUTRINO_ICON_BUTTON_GREEN)
|
|
f_col = COL_DARK_GREEN;
|
|
if (icon_name == NEUTRINO_ICON_BUTTON_YELLOW)
|
|
f_col = COL_DARK_YELLOW;
|
|
if (icon_name == NEUTRINO_ICON_BUTTON_BLUE)
|
|
f_col = COL_DARK_BLUE;
|
|
btn->setColorFrame(f_col);
|
|
}
|
|
}
|
|
|
|
//set width of button container and ensure its center position inside button area of footer
|
|
int dx_cont_free = btn_container->getFreeDX();
|
|
int dx_cont = btn_container->getWidth();
|
|
int x_cont = btn_container->getXPos();
|
|
if (dx_cont_free > 0)
|
|
{
|
|
btn_container->setWidth(dx_cont - dx_cont_free);
|
|
btn_container->setXPos(x_cont + dx_cont_free/2);
|
|
}
|
|
|
|
// get the lowest font height for unified typeface
|
|
int dy_font_min = btn_container->getHeight();
|
|
int dy_font_max = 0;
|
|
CComponentsButton *btn_smallest = NULL;
|
|
|
|
for (size_t i = 0; i < l_count; i++){
|
|
CComponentsButton *btn = static_cast<CComponentsButton*>(btn_container->getCCItem(i));
|
|
int dy_font_tmp = btn->getButtonFont()->getHeight();
|
|
if (dy_font_tmp < dy_font_min)
|
|
{
|
|
dy_font_min = dy_font_tmp;
|
|
btn_smallest = btn;
|
|
}
|
|
dy_font_max = max(dy_font_max, dy_font_tmp);
|
|
|
|
// dprintf(DEBUG_NORMAL, "[CComponentsFooter]\t[%s - %d]\tbutton: %s dy_font_min [%d]\n", __func__, __LINE__, btn->getItemName().c_str(), dy_font_min);
|
|
}
|
|
|
|
// set smallest font height
|
|
if (btn_smallest)
|
|
{
|
|
Font* tmp_font = btn_smallest->getButtonFont();
|
|
for (size_t i = 0; i < l_count; i++){
|
|
CComponentsButton *btn = static_cast<CComponentsButton*>(btn_container->getCCItem(i));
|
|
btn->setButtonFont(tmp_font);
|
|
}
|
|
// dprintf(DEBUG_NORMAL, "[CComponentsFooter]\t[%s - %d]\tsmallest button font height: dy_font_min [%d] dy_font_max [%d]\n", __func__, __LINE__, dy_font_min, dy_font_max);
|
|
}
|
|
}
|
|
|
|
void CComponentsFooter::setButtonLabels(const struct button_label * const content, const size_t& label_count, const int& chain_width, const int& label_width)
|
|
{
|
|
//conversion for compatibility with older paintButtons() methode, find in /gui/widget/buttons.h
|
|
button_label_cc *buttons = new button_label_cc[label_count];
|
|
for (size_t i = 0; i< label_count; i++){
|
|
buttons[i].button = content[i].button;
|
|
buttons[i].locale = content[i].locale;
|
|
//NOTE: here are used default values, because old button label struct don't know about this,
|
|
//if it possible, don't use this methode!
|
|
buttons[i].directKeys.push_back(CRCInput::RC_nokey);
|
|
buttons[i].btn_result = -1;
|
|
buttons[i].btn_alias = -1;
|
|
}
|
|
setButtonLabels(buttons, label_count, chain_width, label_width);
|
|
delete[] buttons;
|
|
buttons = NULL;
|
|
}
|
|
|
|
void CComponentsFooter::setButtonLabels(const vector<button_label_cc> &v_content, const int& chain_width, const int& label_width)
|
|
{
|
|
size_t label_count = v_content.size();
|
|
button_label_cc *buttons = new button_label_cc[label_count];
|
|
|
|
for (size_t i= 0; i< label_count; i++){
|
|
buttons[i].button = v_content[i].button;
|
|
buttons[i].text = v_content[i].text;
|
|
buttons[i].locale = v_content[i].locale;
|
|
for (size_t j= 0; j< v_content[i].directKeys.size(); j++)
|
|
buttons[i].directKeys.push_back(v_content[i].directKeys[j]);
|
|
buttons[i].btn_result = v_content[i].btn_result;
|
|
buttons[i].btn_alias = v_content[i].btn_alias;
|
|
}
|
|
|
|
setButtonLabels(buttons, label_count, chain_width, label_width);
|
|
delete[] buttons;
|
|
buttons = NULL;
|
|
}
|
|
|
|
void CComponentsFooter::setButtonLabel( const char *button_icon,
|
|
const std::string& text,
|
|
const int& chain_width,
|
|
const int& label_width,
|
|
const neutrino_msg_t& msg,
|
|
const int& result_value,
|
|
const int& alias_value)
|
|
{
|
|
button_label_cc button[1];
|
|
|
|
button[0].button = button_icon;
|
|
button[0].text = text;
|
|
button[0].directKeys.push_back(msg);
|
|
button[0].btn_result = result_value;
|
|
button[0].btn_alias = alias_value;
|
|
|
|
setButtonLabels(button, 1, chain_width, label_width);
|
|
}
|
|
|
|
void CComponentsFooter::setButtonLabel( const char *button_icon,
|
|
const neutrino_locale_t& locale,
|
|
const int& chain_width,
|
|
const int& label_width,
|
|
const neutrino_msg_t& msg,
|
|
const int& result_value,
|
|
const int& alias_value)
|
|
{
|
|
string txt = locale != NONEXISTANT_LOCALE ? g_Locale->getText(locale) : "";
|
|
|
|
setButtonLabel(button_icon, txt, chain_width, label_width, msg, result_value, alias_value);
|
|
}
|
|
|
|
void CComponentsFooter::enableButtonBg(bool enable)
|
|
{
|
|
ccf_enable_button_bg = enable;
|
|
if (btn_container) {
|
|
for (size_t i= 0; i< btn_container->size(); i++)
|
|
btn_container->getCCItem(i)->doPaintBg(ccf_enable_button_bg);
|
|
}
|
|
}
|
|
|
|
void CComponentsFooter::paintButtons(const int& x_pos,
|
|
const int& y_pos,
|
|
const int& w,
|
|
const int& h,
|
|
const size_t& label_count,
|
|
const struct button_label * const content,
|
|
const int& label_width,
|
|
const int& context_buttons,
|
|
Font* font,
|
|
const bool &do_save_bg)
|
|
{
|
|
this->setDimensionsAll(x_pos, y_pos, w, h);
|
|
this->setButtonFont(font);
|
|
this->setContextButton(context_buttons);
|
|
this->setButtonLabels(content, label_count, 0, label_width);
|
|
this->paint(do_save_bg);
|
|
}
|
|
|
|
void CComponentsFooter::setButtonText(const uint& btn_id, const std::string& text)
|
|
{
|
|
CComponentsItem *item = getButtonChainObject()->getCCItem(btn_id);
|
|
if (item){
|
|
CComponentsButton *button = static_cast<CComponentsButton*>(item);
|
|
button->setCaption(text);
|
|
}
|
|
else
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: can't set button text, possible wrong btn_id=%u, item=%p...\n", __func__, __LINE__, btn_id, item);
|
|
}
|
|
|
|
|
|
void CComponentsFooter::enableButtonShadow(int mode, const int& shadow_width, bool force_paint)
|
|
{
|
|
ccf_enable_button_shadow = mode;
|
|
ccf_button_shadow_width = shadow_width;
|
|
ccf_button_shadow_force_paint = force_paint;
|
|
if (btn_container){
|
|
for(size_t i=0; i<btn_container->size(); i++){
|
|
btn_container->getCCItem(i)->enableShadow(ccf_enable_button_shadow, ccf_button_shadow_width, ccf_button_shadow_force_paint);
|
|
//int y_btn = ccf_enable_button_shadow == CC_SHADOW_OFF ? CC_CENTERED : chain->getHeight()/2 - chain->getCCItem(i)->getHeight()/2 - ccf_button_shadow_width;
|
|
int y_btn = btn_container->getHeight()/2 - btn_container->getCCItem(i)->getHeight()/2;
|
|
btn_container->getCCItem(i)->setYPos(y_btn);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CComponentsFooter::initDefaultFonts()
|
|
{
|
|
l_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE];
|
|
s_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_FOOT];
|
|
}
|
|
|
|
CComponentsButton* CComponentsFooter::getButtonLabel(const uint& item_id)
|
|
{
|
|
if (btn_container)
|
|
return static_cast<CComponentsButton*>(btn_container->getCCItem(item_id));
|
|
return NULL;
|
|
}
|