mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-29 16:31:11 +02:00
Replacing messagebox, hintbox_ext and some derivated parts with basic class hintbox and derivated class CMsgBox. This should unify window handling and avoids maintain of multiple classes with quasi same purpose and adds more functionality. TODO: fix and optimize details
695 lines
19 KiB
C++
695 lines
19 KiB
C++
/*
|
|
Based up Neutrino-GUI - Tuxbox-Project
|
|
Copyright (C) 2001 by Steffen Hehn 'McClean'
|
|
|
|
Classes for generic GUI-related components.
|
|
Copyright (C) 2012, 2013, 2014 Thilo Graf 'dbt'
|
|
Copyright (C) 2012, Michael Liebmann 'micha-bbg'
|
|
|
|
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 <global.h>
|
|
#include <neutrino.h>
|
|
#include "cc_frm.h"
|
|
#include <stdlib.h>
|
|
#include <algorithm>
|
|
#include <system/debug.h>
|
|
|
|
using namespace std;
|
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
//sub class CComponentsForm from CComponentsItem
|
|
CComponentsForm::CComponentsForm( const int x_pos, const int y_pos, const int w, const int h,
|
|
CComponentsForm* parent,
|
|
int shadow_mode,
|
|
fb_pixel_t color_frame,
|
|
fb_pixel_t color_body,
|
|
fb_pixel_t color_shadow)
|
|
:CComponentsItem(parent)
|
|
{
|
|
cc_item_type = CC_ITEMTYPE_FRM;
|
|
|
|
Init(x_pos, y_pos, w, h, color_frame, color_body, color_shadow);
|
|
cc_xr = x;
|
|
cc_yr = y;
|
|
|
|
shadow = shadow_mode;
|
|
shadow_w = OFFSET_SHADOW;
|
|
corner_rad = RADIUS_LARGE;
|
|
corner_type = CORNER_ALL;
|
|
cc_item_index = 0;
|
|
|
|
//add default exit keys for exec handler
|
|
v_exit_keys.push_back(CRCInput::RC_home);
|
|
v_exit_keys.push_back(CRCInput::RC_setup);
|
|
|
|
v_cc_items.clear();
|
|
|
|
append_x_offset = 0;
|
|
append_y_offset = 0;
|
|
page_count = 1;
|
|
cur_page = 0;
|
|
sb = NULL;
|
|
w_sb = 15;
|
|
|
|
page_scroll_mode = PG_SCROLL_M_UP_DOWN_KEY;
|
|
|
|
//connect page scroll slot
|
|
sigc::slot4<void, neutrino_msg_t&, neutrino_msg_data_t&, int&, bool&> sl = sigc::mem_fun(*this, &CComponentsForm::execPageScroll);
|
|
this->OnExec.connect(sl);
|
|
}
|
|
|
|
void CComponentsForm::Init( const int& x_pos, const int& y_pos, const int& w, const int& h,
|
|
const fb_pixel_t& color_frame,
|
|
const fb_pixel_t& color_body,
|
|
const fb_pixel_t& color_shadow)
|
|
{
|
|
setDimensionsAll(x_pos, y_pos, w, h);
|
|
setColorAll(color_frame, color_body, color_shadow);
|
|
}
|
|
|
|
CComponentsForm::~CComponentsForm()
|
|
{
|
|
clear();
|
|
delete sb;
|
|
}
|
|
|
|
int CComponentsForm::exec()
|
|
{
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] \n", __func__, __LINE__);
|
|
|
|
//basic values
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
int res = menu_return::RETURN_REPAINT;
|
|
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(-1);
|
|
|
|
//allow exec loop
|
|
bool cancel_exec = false;
|
|
|
|
//signal before exec
|
|
OnBeforeExec();
|
|
|
|
while (!cancel_exec)
|
|
{
|
|
g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd );
|
|
|
|
//execute connected slots
|
|
OnExec(msg, data, res, cancel_exec);
|
|
//exit loop
|
|
execExit(msg, data, res, cancel_exec, v_exit_keys);
|
|
|
|
if (CNeutrinoApp::getInstance()->handleMsg(msg, data) & messages_return::cancel_all)
|
|
{
|
|
dprintf(DEBUG_INFO, "[CComponentsForm] [%s - %d] messages_return::cancel_all\n", __func__, __LINE__);
|
|
res = menu_return::RETURN_EXIT_ALL;
|
|
cancel_exec = EXIT;
|
|
}
|
|
}
|
|
|
|
//signal after exec
|
|
OnAfterExec();
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
void CComponentsForm::execKey(neutrino_msg_t& msg, neutrino_msg_data_t& data, int& res, bool& cancel_exec, const std::vector<neutrino_msg_t>& v_msg_list, bool force_exit)
|
|
{
|
|
for(size_t i = 0; i < v_msg_list.size(); i++){
|
|
if (execKey(msg, data, res, cancel_exec, v_msg_list[i], force_exit)){
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline bool CComponentsForm::execKey(neutrino_msg_t& msg, neutrino_msg_data_t& data, int& res, bool& cancel_exec, const neutrino_msg_t& msg_val, bool force_exit)
|
|
{
|
|
if (msg == msg_val){
|
|
OnExecMsg(msg, data, res);
|
|
if (force_exit)
|
|
cancel_exec = EXIT;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void CComponentsForm::execPageScroll(neutrino_msg_t& msg, neutrino_msg_data_t& /*data*/, int& /*res*/, bool& /*cancel_exec*/)
|
|
{
|
|
if (page_scroll_mode == PG_SCROLL_M_OFF)
|
|
return;
|
|
|
|
if (page_scroll_mode & PG_SCROLL_M_UP_DOWN_KEY){
|
|
if (msg == CRCInput::RC_page_up)
|
|
ScrollPage(SCROLL_P_DOWN);
|
|
if (msg == CRCInput::RC_page_down)
|
|
ScrollPage(SCROLL_P_UP);
|
|
}
|
|
|
|
if (page_scroll_mode & PG_SCROLL_M_LEFT_RIGHT_KEY){
|
|
if (msg == CRCInput::RC_left)
|
|
ScrollPage(SCROLL_P_DOWN);
|
|
if (msg == CRCInput::RC_right)
|
|
ScrollPage(SCROLL_P_UP);
|
|
}
|
|
}
|
|
|
|
void CComponentsForm::execExit(neutrino_msg_t& msg, neutrino_msg_data_t& data, int& res, bool& cancel_exec, const std::vector<neutrino_msg_t>& v_msg_list)
|
|
{
|
|
execKey(msg, data, res, cancel_exec, v_msg_list, true);
|
|
}
|
|
|
|
|
|
void CComponentsForm::clear()
|
|
{
|
|
if (v_cc_items.empty())
|
|
return;
|
|
|
|
for(size_t i=0; i<v_cc_items.size(); i++) {
|
|
if (v_cc_items[i]){
|
|
|
|
dprintf(DEBUG_DEBUG, "[CComponentsForm] %s... delete form cc-item %d of %d (type=%d)\n", __func__, (int)i+1, (int)v_cc_items.size(), v_cc_items[i]->getItemType());
|
|
|
|
delete v_cc_items[i];
|
|
v_cc_items[i] = NULL;
|
|
}
|
|
}
|
|
v_cc_items.clear();
|
|
}
|
|
|
|
|
|
int CComponentsForm::addCCItem(CComponentsItem* cc_Item)
|
|
{
|
|
if (cc_Item){
|
|
dprintf(DEBUG_DEBUG, "[CComponentsForm] %s-%d try to add cc_Item [type %d] to form [current index=%d] \n", __func__, __LINE__, cc_Item->getItemType(), cc_item_index);
|
|
|
|
cc_Item->setParent(this);
|
|
v_cc_items.push_back(cc_Item);
|
|
|
|
dprintf(DEBUG_DEBUG, "\tadded cc_Item [type %d] to form [current index=%d] \n", cc_Item->getItemType(), cc_item_index);
|
|
|
|
//assign item index
|
|
int new_index = genIndex();
|
|
cc_Item->setIndex(new_index);
|
|
cc_Item->setFocus(true);
|
|
|
|
dprintf(DEBUG_DEBUG, "\t%s-%d parent index = %d, assigned index ======> %d\n", __func__, __LINE__, cc_item_index, new_index);
|
|
return getCCItemId(cc_Item);
|
|
}
|
|
else
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] %s-%d tried to add an empty or invalide cc_item !!!\n", __func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
int CComponentsForm::addCCItem(const std::vector<CComponentsItem*> &cc_Items)
|
|
{
|
|
for (size_t i= 0; i< cc_Items.size(); i++)
|
|
addCCItem(cc_Items[i]);
|
|
return size();
|
|
}
|
|
|
|
int CComponentsForm::getCCItemId(CComponentsItem* cc_Item)
|
|
{
|
|
if (cc_Item){
|
|
for (size_t i= 0; i< v_cc_items.size(); i++)
|
|
if (v_cc_items[i] == cc_Item)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int CComponentsForm::genIndex()
|
|
{
|
|
int count = v_cc_items.size();
|
|
char buf[64];
|
|
snprintf(buf, sizeof(buf), "%d%d", cc_item_index, count);
|
|
buf[63] = '\0';
|
|
int ret = atoi(buf);
|
|
return ret;
|
|
}
|
|
|
|
CComponentsItem* CComponentsForm::getCCItem(const uint& cc_item_id)
|
|
{
|
|
if (cc_item_id >= size()){
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] Error: parameter cc_item_id = %u, out of range (size = %" PRIx32")...\n", __func__, __LINE__, cc_item_id, size());
|
|
return NULL;
|
|
}
|
|
|
|
if (v_cc_items[cc_item_id])
|
|
return v_cc_items[cc_item_id];
|
|
return NULL;
|
|
}
|
|
|
|
void CComponentsForm::replaceCCItem(const uint& cc_item_id, CComponentsItem* new_cc_Item)
|
|
{
|
|
if (!v_cc_items.empty()){
|
|
CComponentsItem* old_Item = v_cc_items[cc_item_id];
|
|
if (old_Item){
|
|
CComponentsForm * old_parent = old_Item->getParent();
|
|
new_cc_Item->setParent(old_parent);
|
|
new_cc_Item->setIndex(old_parent->getIndex());
|
|
delete old_Item;
|
|
old_Item = NULL;
|
|
v_cc_items[cc_item_id] = new_cc_Item;
|
|
}
|
|
}
|
|
else
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] %s replace cc_Item not possible, v_cc_items is empty\n", __func__);
|
|
}
|
|
|
|
void CComponentsForm::replaceCCItem(CComponentsItem* old_cc_Item, CComponentsItem* new_cc_Item)
|
|
{
|
|
replaceCCItem(getCCItemId(old_cc_Item), new_cc_Item);
|
|
}
|
|
|
|
void CComponentsForm::insertCCItem(const uint& cc_item_id, CComponentsItem* cc_Item)
|
|
{
|
|
|
|
if (cc_Item == NULL){
|
|
dprintf(DEBUG_DEBUG, "[CComponentsForm] %s parameter: cc_Item = %p...\n", __func__, cc_Item);
|
|
return;
|
|
}
|
|
|
|
if (v_cc_items.empty()){
|
|
addCCItem(cc_Item);
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] %s insert cc_Item not possible, v_cc_items is empty, cc_Item added\n", __func__);
|
|
}else{
|
|
v_cc_items.insert(v_cc_items.begin()+cc_item_id, cc_Item);
|
|
cc_Item->setParent(this);
|
|
//assign item index
|
|
int index = genIndex();
|
|
cc_Item->setIndex(index);
|
|
}
|
|
}
|
|
|
|
void CComponentsForm::removeCCItem(const uint& cc_item_id)
|
|
{
|
|
if (!v_cc_items.empty()){
|
|
if (v_cc_items[cc_item_id]) {
|
|
delete v_cc_items[cc_item_id];
|
|
v_cc_items[cc_item_id] = NULL;
|
|
v_cc_items.erase(v_cc_items.begin()+cc_item_id);
|
|
dprintf(DEBUG_DEBUG, "[CComponentsForm] %s removing cc_Item [id=%u]...\n", __func__, cc_item_id);
|
|
}
|
|
}
|
|
else
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] %s removing of cc_Item [id=%u] not possible, v_cc_items is empty...\n", __func__, cc_item_id);
|
|
}
|
|
|
|
void CComponentsForm::removeCCItem(CComponentsItem* cc_Item)
|
|
{
|
|
uint id = getCCItemId(cc_Item);
|
|
removeCCItem(id);
|
|
}
|
|
|
|
void CComponentsForm::exchangeCCItem(const uint& cc_item_id_a, const uint& cc_item_id_b)
|
|
{
|
|
if (!v_cc_items.empty())
|
|
swap(v_cc_items[cc_item_id_a], v_cc_items[cc_item_id_b]);
|
|
}
|
|
|
|
void CComponentsForm::exchangeCCItem(CComponentsItem* item_a, CComponentsItem* item_b)
|
|
{
|
|
exchangeCCItem(getCCItemId(item_a), getCCItemId(item_b));
|
|
}
|
|
|
|
void CComponentsForm::paintForm(bool do_save_bg)
|
|
{
|
|
//paint body
|
|
paintInit(do_save_bg);
|
|
|
|
//paint
|
|
paintCCItems();
|
|
}
|
|
|
|
void CComponentsForm::paint(bool do_save_bg)
|
|
{
|
|
paintForm(do_save_bg);
|
|
}
|
|
|
|
bool CComponentsForm::isPageChanged()
|
|
{
|
|
for(size_t i=0; i<v_cc_items.size(); i++){
|
|
if (v_cc_items[i]->getPageNumber() != cur_page)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CComponentsForm::paintPage(const u_int8_t& page_number, bool do_save_bg)
|
|
{
|
|
cur_page = page_number;
|
|
paint(do_save_bg);
|
|
}
|
|
|
|
void CComponentsForm::paintCCItems()
|
|
{
|
|
size_t items_count = v_cc_items.size();
|
|
|
|
//using of real x/y values to paint items if this text object is bound in a parent form
|
|
int this_x = x, auto_x = x, this_y = y, auto_y = y, this_w = width;
|
|
int w_parent_frame = 0;
|
|
if (cc_parent){
|
|
this_x = auto_x = cc_xr;
|
|
this_y = auto_y = cc_yr;
|
|
}
|
|
|
|
//init and handle scrollbar
|
|
getPageCount();
|
|
int y_sb = this_y+1;
|
|
int x_sb = this_x + width - w_sb;
|
|
int h_sb = height-2;
|
|
if (sb == NULL){
|
|
sb = new CComponentsScrollBar(x_sb, y_sb, w_sb, h_sb);
|
|
}else{
|
|
//clean background, if dimension of scrollbar was changed
|
|
if (w_sb != sb->getWidth())
|
|
sb->kill(col_body);
|
|
|
|
//set current dimensions and position
|
|
sb->setDimensionsAll(x_sb, y_sb, w_sb, h_sb);
|
|
}
|
|
|
|
if(page_count > 1){
|
|
sb->setSegmentCount(page_count);
|
|
sb->setMarkID(cur_page);
|
|
this_w = width - w_sb;
|
|
sb->paint(false);
|
|
}else{
|
|
if (sb->isPainted())
|
|
sb->kill(col_body);
|
|
this_w = width;
|
|
}
|
|
|
|
//detect if current page has changed, if true then kill items from screen
|
|
if(isPageChanged()){
|
|
this->killCCItems(col_body, true);
|
|
}
|
|
|
|
for(size_t i=0; i<items_count; i++){
|
|
//assign item object
|
|
CComponentsItem *cc_item = v_cc_items[i];
|
|
|
|
dprintf(DEBUG_DEBUG, "[CComponentsForm] %s: page_count = %u, item_page = %u, cur_page = %u\n", __func__, getPageCount(), cc_item->getPageNumber(), this->cur_page);
|
|
|
|
//get current position of item
|
|
int xpos = cc_item->getXPos();
|
|
int ypos = cc_item->getYPos();
|
|
|
|
//get current dimension of item
|
|
int w_item = cc_item->getWidth() - (xpos <= fr_thickness ? fr_thickness : 0);
|
|
int h_item = cc_item->getHeight() - (ypos <= fr_thickness ? fr_thickness : 0);
|
|
|
|
//check item for corrupt position, skip current item if found problems
|
|
if (ypos > height || xpos > this_w){
|
|
dprintf(DEBUG_INFO, "[CComponentsForm] %s: [form: %d] [item-index %d] [type=%d] WARNING: item position is out of form size:\ndefinied x=%d, defined this_w=%d \ndefinied y=%d, defined height=%d \n",
|
|
__func__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), xpos, this_w, ypos, height);
|
|
if (this->cc_item_type != CC_ITEMTYPE_FRM_CHAIN)
|
|
continue;
|
|
}
|
|
|
|
//move item x-position, if we have a frame on parent, TODO: other constellations not considered at the moment
|
|
w_parent_frame = xpos <= fr_thickness ? fr_thickness : 0;
|
|
|
|
//set required x-position to item:
|
|
//append vertical
|
|
if (xpos == CC_APPEND){
|
|
auto_x += append_x_offset;
|
|
cc_item->setRealXPos(auto_x + xpos + w_parent_frame);
|
|
auto_x += w_item;
|
|
}
|
|
//positionize vertical centered
|
|
else if (xpos == CC_CENTERED){
|
|
auto_x = this_w/2 - w_item/2;
|
|
cc_item->setRealXPos(this_x + auto_x + w_parent_frame);
|
|
}
|
|
else{
|
|
cc_item->setRealXPos(this_x + xpos + w_parent_frame);
|
|
auto_x = (cc_item->getRealXPos() + w_item);
|
|
}
|
|
|
|
//move item y-position, if we have a frame on parent, TODO: other constellations not considered at the moment
|
|
w_parent_frame = ypos <= fr_thickness ? fr_thickness : 0;
|
|
|
|
//set required y-position to item
|
|
//append hor
|
|
if (ypos == CC_APPEND){
|
|
auto_y += append_y_offset;
|
|
cc_item->setRealYPos(auto_y + ypos + w_parent_frame);
|
|
auto_y += h_item;
|
|
}
|
|
//positionize hor centered
|
|
else if (ypos == CC_CENTERED){
|
|
auto_y = height/2 - h_item/2;
|
|
cc_item->setRealYPos(this_y + auto_y + w_parent_frame);
|
|
}
|
|
else{
|
|
cc_item->setRealYPos(this_y + ypos + w_parent_frame);
|
|
auto_y = (cc_item->getRealYPos() + h_item);
|
|
}
|
|
|
|
//reduce corner radius, if we have a frame around parent item, ensure matching corners inside of embedded item, this avoids ugly unpainted spaces between frame and item border
|
|
//TODO: other constellations not considered at the moment
|
|
if (w_parent_frame){
|
|
if(xpos <= fr_thickness || ypos <= fr_thickness)
|
|
cc_item->setCorner(max(0, cc_item->getCornerRadius()-w_parent_frame), cc_item->getCornerType());
|
|
}
|
|
|
|
//These steps check whether the element can be painted into the container.
|
|
//Is it too wide or too high, it will be shortened and displayed in the log.
|
|
//This should be avoid!
|
|
//checkwidth and adapt if required
|
|
int right_frm = (cc_parent ? cc_xr : x) + this_w - 2*fr_thickness;
|
|
int right_item = cc_item->getRealXPos() + w_item;
|
|
int w_diff = right_item - right_frm;
|
|
int new_w = w_item - w_diff;
|
|
//avoid of width error due to odd values (1 line only)
|
|
right_item -= (new_w%2);
|
|
w_item -= (new_w%2);
|
|
if (right_item > right_frm){
|
|
dprintf(DEBUG_INFO, "[CComponentsForm] %s: [form: %d] [item-index %d] [type=%d] this_w is too large, definied width=%d, possible width=%d \n",
|
|
__func__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), w_item, new_w);
|
|
cc_item->setWidth(new_w);
|
|
}
|
|
|
|
//check height and adapt if required
|
|
int bottom_frm = (cc_parent ? cc_yr : y) + height - 2*fr_thickness;
|
|
int bottom_item = cc_item->getRealYPos() + h_item;
|
|
int h_diff = bottom_item - bottom_frm;
|
|
int new_h = h_item - h_diff;
|
|
//avoid of height error due to odd values (1 line only)
|
|
bottom_item -= (new_h%2);
|
|
h_item -= (new_h%2);
|
|
if (bottom_item > bottom_frm){
|
|
dprintf(DEBUG_INFO, "[CComponentsForm] %s: [form: %d] [item-index %d] [type=%d] height is too large, definied height=%d, possible height=%d \n",
|
|
__func__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), h_item, new_h);
|
|
cc_item->setHeight(new_h);
|
|
}
|
|
|
|
//get current visibility mode from item, me must hold it and restore after paint
|
|
bool item_visible = cc_item->paintAllowed();
|
|
//set visibility mode
|
|
if (!this->cc_allow_paint)
|
|
cc_item->allowPaint(false);
|
|
|
|
//finally paint current item, but only required contents of page
|
|
if (cc_item->getPageNumber() == cur_page)
|
|
cc_item->paint(CC_SAVE_SCREEN_NO);
|
|
|
|
//restore defined old visibility mode of item after paint
|
|
cc_item->allowPaint(item_visible);
|
|
}
|
|
}
|
|
#if 0
|
|
void CComponentsForm::hide()
|
|
{
|
|
// hack: ensure hiding of minitv during hide of forms and inherited classes,
|
|
// because the handling of minitv items are different to other item types
|
|
// and need an explizit call of hide()
|
|
for(size_t i=0; i<v_cc_items.size(); i++) {
|
|
if (v_cc_items[i]->getItemType() == CC_ITEMTYPE_PIP){
|
|
v_cc_items[i]->kill();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//hide body
|
|
CComponents::hide();
|
|
}
|
|
#endif
|
|
//erase or paint over rendered objects
|
|
void CComponentsForm::killCCItems(const fb_pixel_t& bg_color, bool ignore_parent)
|
|
{
|
|
for(size_t i=0; i<v_cc_items.size(); i++)
|
|
v_cc_items[i]->kill(bg_color, ignore_parent);
|
|
}
|
|
|
|
void CComponentsForm::setPageCount(const u_int8_t& pageCount)
|
|
{
|
|
u_int8_t new_val = pageCount;
|
|
if (new_val < page_count)
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] %s: current count (= %u) of pages higher than page_count (= %u) will be set, smaller value is ignored!\n", __func__, page_count, new_val) ;
|
|
page_count = max(new_val, page_count);
|
|
}
|
|
|
|
u_int8_t CComponentsForm::getPageCount()
|
|
{
|
|
u_int8_t num = 0;
|
|
for(size_t i=0; i<v_cc_items.size(); i++){
|
|
u_int8_t item_num = v_cc_items[i]->getPageNumber();
|
|
num = max(item_num, num);
|
|
}
|
|
|
|
//convert type, possible -Wconversion warnings!
|
|
page_count = static_cast<u_int8_t>(num+1);
|
|
|
|
return page_count;
|
|
}
|
|
|
|
|
|
void CComponentsForm::setSelectedItem(int item_id)
|
|
{
|
|
size_t count = v_cc_items.size();
|
|
int id = item_id;
|
|
|
|
if (id > (int)(count-1) || id < 0 || (count == 0)){
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] invalid parameter item_id = %u, available items = %u, allowed values are: 0...%u! \n", __func__,
|
|
__LINE__,
|
|
item_id,
|
|
count,
|
|
count==0 ? 0:count-1);
|
|
//exit if no item is available
|
|
if (count == 0)
|
|
return;
|
|
|
|
//jump to last item
|
|
if (id < 0)
|
|
id = count-1;
|
|
//jump to 1st item, if id is out of range, avoids also possible segfault
|
|
if (id > (int)(count-1))
|
|
id = 0;
|
|
}
|
|
|
|
for (size_t i= 0; i< count; i++)
|
|
v_cc_items[i]->setSelected(i == (size_t)id);
|
|
|
|
OnSelect();
|
|
}
|
|
|
|
void CComponentsForm::setSelectedItem(CComponentsItem* cc_item)
|
|
{
|
|
int id = getCCItemId(cc_item);
|
|
if (id == -1){
|
|
dprintf(DEBUG_NORMAL, "[CComponentsForm] [%s - %d] invalid item parameter, no object available\n", __func__,__LINE__);
|
|
return;
|
|
}
|
|
setSelectedItem(id);
|
|
}
|
|
|
|
int CComponentsForm::getSelectedItem()
|
|
{
|
|
for (size_t i= 0; i< size(); i++)
|
|
if (getCCItem(i)->isSelected())
|
|
return static_cast<int>(i);
|
|
return -1;
|
|
}
|
|
|
|
CComponentsItem* CComponentsForm::getSelectedItemObject()
|
|
{
|
|
int sel = getSelectedItem();
|
|
CComponentsItem* ret = NULL;
|
|
if (sel != -1)
|
|
ret = static_cast<CComponentsItem*>(this->getCCItem(sel));
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
void CComponentsForm::ScrollPage(int direction, bool do_paint)
|
|
{
|
|
if (getPageCount() == 1){
|
|
cur_page = 0;
|
|
return;
|
|
}
|
|
|
|
OnBeforeScrollPage();
|
|
|
|
int target_page_id = (int)page_count - 1;
|
|
int target_page = (int)cur_page;
|
|
|
|
if (direction == SCROLL_P_DOWN)
|
|
target_page = target_page+1 > target_page_id ? 0 : target_page+1;
|
|
else if (direction == SCROLL_P_UP)
|
|
target_page = target_page-1 < 0 ? target_page_id : target_page-1;
|
|
|
|
if (do_paint)
|
|
paintPage((uint8_t)target_page);
|
|
else
|
|
cur_page = (uint8_t)target_page;
|
|
|
|
OnAfterScrollPage();
|
|
}
|
|
|
|
bool CComponentsForm::clearSavedScreen()
|
|
{
|
|
if (CCDraw::clearSavedScreen()){
|
|
for(size_t i=0; i<v_cc_items.size(); i++)
|
|
v_cc_items[i]->clearSavedScreen();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CComponentsForm::clearPaintCache()
|
|
{
|
|
if (CCDraw::clearPaintCache()){
|
|
for(size_t i=0; i<v_cc_items.size(); i++)
|
|
v_cc_items[i]->clearPaintCache();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//clean old gradient buffer
|
|
bool CComponentsForm::clearFbGradientData()
|
|
{
|
|
if (CCDraw::clearFbGradientData()){
|
|
for(size_t i=0; i<v_cc_items.size(); i++)
|
|
v_cc_items[i]->clearFbGradientData();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CComponentsForm::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color, const int& direction)
|
|
{
|
|
if (CCDraw::enableColBodyGradient(enable_mode, sec_color, direction)){
|
|
for (size_t i= 0; i< v_cc_items.size(); i++)
|
|
v_cc_items[i]->clearScreenBuffer();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|