cc_item_picture: rework for svg-support, simplified structure

- simplified icon and logohandling in headers
- add svg examples, fix some other tests inside test_menu.cpp
This commit is contained in:
2021-11-13 18:56:47 +01:00
parent 568518c15a
commit 68c8edf09c
6 changed files with 311 additions and 737 deletions

View File

@@ -251,11 +251,6 @@ void CComponentsHeader::setIcon(const char* icon_name)
void CComponentsHeader::setIcon(const std::string& icon_name)
{
cch_icon_name = icon_name;
std::string fullpath_icon_name = frameBuffer->getIconPath(cch_icon_name);
if (fullpath_icon_name.find(".svg") == (fullpath_icon_name.length() - 4))
initIconSVG();
else
initIcon();
}
@@ -270,87 +265,26 @@ void CComponentsHeader::initIcon()
}
return;
}
std::string fullpath_icon_name = frameBuffer->getIconPath(cch_icon_name);
if (fullpath_icon_name.find(".svg") == (fullpath_icon_name.length() - 4))
return;
//create instance for cch_icon_obj and add to container at once
if (cch_icon_obj == NULL){
dprintf(DEBUG_DEBUG, "[CComponentsHeader]\n [%s - %d] init header icon: %s\n", __func__, __LINE__, cch_icon_name.c_str());
cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, 0, 0, cch_icon_name, this);
cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, "blank", this);
}
//set properties for icon object
if (cch_icon_obj){
//get dimensions of header icon
int iw = 0;
int ih = 0;
cch_icon_obj->getSize(&iw, &ih);
dprintf(DEBUG_INFO, "[CComponentsHeader]\n [%s - %d] init icon size: iw = %d, ih = %d\n", __func__, __LINE__, iw, ih);
cch_icon_obj->setWidth(iw);
cch_icon_obj->setHeight(ih);
cch_icon_obj->doPaintBg(false);
//set corner mode of icon item
int cc_icon_corner_type = CORNER_LEFT;
if (corner_type & CORNER_TOP_LEFT || corner_type & CORNER_TOP)
cc_icon_corner_type = CORNER_TOP_LEFT;
cch_icon_obj->setCorner(corner_rad-fr_thickness, cc_icon_corner_type);
//global set width of icon object
cch_icon_w = cch_icon_obj->getWidth();
//global adapt height
height = max(height, cch_icon_obj->getHeight());
// //re-assign height of icon object, for the case of changed height
// cch_icon_obj->setHeight(height);
}
}
void CComponentsHeader::initIconSVG()
{
//init cch_icon_obj only if an icon available
if (cch_icon_name.empty()) {
cch_icon_w = 0;
if (cch_icon_obj){
removeCCItem(cch_icon_obj);
cch_icon_obj = NULL;
}
return;
}
std::string fullpath_icon_name = frameBuffer->getIconPath(cch_icon_name, "svg");
if (!(fullpath_icon_name.find(".svg") == (fullpath_icon_name.length() - 4)))
return;
cch_icon_name = fullpath_icon_name;
//create instance for cch_icon_obj and add to container at once
if (cch_icon_obj == NULL){
dprintf(DEBUG_DEBUG, "[CComponentsHeader]\n [%s - %d] init header svg icon: %s\n", __func__, __LINE__, cch_icon_name.c_str());
cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, 0, 0, cch_icon_name, this);
}
//set properties for icon object
if (cch_icon_obj){
cch_icon_obj->setPicture(cch_icon_name);
//get dimensions of header icon
dprintf(DEBUG_INFO, "[CComponentsHeader]\n [%s - %d] init svg icon size: height = %d\n", __func__, __LINE__, height);
cch_icon_obj->setHeight(height - OFFSET_INNER_SMALL,true);
cch_icon_obj->doPaintBg(false);
int dx_tmp = 0, dy_tmp = 0;
cch_icon_obj->getRealSize(&dx_tmp, &dy_tmp);
cch_icon_obj->setHeight(min(height, dy_tmp));
//set corner mode of icon item
int cc_icon_corner_type = CORNER_LEFT;
if (corner_type & CORNER_TOP_LEFT || corner_type & CORNER_TOP)
cc_icon_corner_type = CORNER_TOP_LEFT;
cch_icon_obj->setCorner(corner_rad-fr_thickness, cc_icon_corner_type);
//global set width of icon object
cch_icon_w = cch_icon_obj->getWidth();
}
}
@@ -358,27 +292,22 @@ void CComponentsHeader::initIconSVG()
void CComponentsHeader::initLogo()
{
// init logo with required height and logo
int h_logo = cch_logo.dy_max == -1 ? height - 2*OFFSET_INNER_MIN : cch_logo.dy_max;
int h_logo = cch_logo.dy_max == -1 ? height - OFFSET_INNER_SMALL : cch_logo.dy_max;
if(!cch_logo_obj)
cch_logo_obj = new CComponentsChannelLogoScalable(1, height/2 - h_logo/2, cch_logo.Name, cch_logo.Id, this);
else
cch_logo_obj->setChannel(cch_logo.Id, cch_logo.Name);
// use value 1 as initial value for logo width, ensures downscale with stupid available logo space
cch_logo_obj->setHeight(1, true);
//ensure logo is not larger than original size if in auto mode
if (cch_logo.dy_max == -1){
int dx_orig = 0, dy_orig = 0 ;
cch_logo_obj->getRealSize(&dx_orig, &dy_orig);
if (h_logo > dy_orig)
h_logo = dy_orig;
{
cch_logo_obj = new CComponentsChannelLogo(1, height/2 - h_logo/2, cch_logo.Name, cch_logo.Id, this);
cch_logo_obj->setAltLogo("blank");
}
else
cch_logo_obj->setChannel(cch_logo.Id, cch_logo.Name, 0, h_logo);
// manage logo position
if (cch_logo_obj->hasLogo()){
cch_logo_obj->setHeight(h_logo, true);
if (cch_logo_obj->hasLogo())
{
int dx_tmp = 0, dy_tmp = 0;
cch_logo_obj->getRealSize(&dx_tmp, &dy_tmp);
cch_logo_obj->setHeight(min(h_logo, dy_tmp));
/* Detect next and previous items,
* current item is logo item.
@@ -390,8 +319,10 @@ void CComponentsHeader::initLogo()
/*
* FIXME: Workaround to fix next item in case of wrong order of items.
*/
if (next_item){
if (next_item->getItemType() == CC_ITEMTYPE_FRM_ICONFORM){
if (next_item)
{
if (next_item->getItemType() == CC_ITEMTYPE_FRM_ICONFORM)
{
/*
* Either clock is present or buttons are enabled,
* different order of objects are required, not optimal
@@ -416,7 +347,7 @@ void CComponentsHeader::initLogo()
* and adjust logo new width if required.
*/
int w_logo = min(cch_logo_obj->getWidth(), logo_space);
cch_logo_obj->setWidth(w_logo, true);
cch_logo_obj->setWidth(w_logo);
/*
* Adjust logo x position depends of align parameters.
@@ -435,21 +366,23 @@ void CComponentsHeader::initLogo()
* but we must notice possible overlapp
* with previous or next item.
*/
if (cch_caption_align & CC_TITLE_LEFT){
if (prev_item){
if (cch_caption_align & CC_TITLE_LEFT)
{
if (prev_item)
{
int left_tag = prev_item->getXPos() + prev_item->getWidth();
if (x_logo <= left_tag)
x_logo = left_tag + logo_space/2 - w_logo/2;
}
}
if (cch_caption_align & CC_TITLE_RIGHT){
if (next_item){
if (cch_caption_align & CC_TITLE_RIGHT)
{
if (next_item)
if (x_logo + w_logo >= next_item->getXPos())
x_logo = next_item->getXPos() - logo_space/2 - w_logo/2;
}
}
}
/*
* Finally set logo x position
@@ -557,10 +490,6 @@ void CComponentsHeader::initButtons()
//re-align height of button object
cch_btn_obj->setHeight(height);
//re-align height of icon object
if (cch_icon_obj)
cch_icon_obj->setHeight(height);
}
}
@@ -764,9 +693,6 @@ void CComponentsHeader::initCCItems()
//init logo
initLogo();
//init svg icon
initIconSVG();
}
void CComponentsHeader::paint(const bool &do_save_bg)

View File

@@ -98,7 +98,7 @@ class CComponentsHeader : public CComponentsForm, public CCTextScreen, CCHeaderT
///object: clock object
CComponentsFrmClock * cch_cl_obj;
///object: logo object
CComponentsChannelLogoScalable * cch_logo_obj;
CComponentsChannelLogo * cch_logo_obj;
///attributes for logos
cch_logo_t cch_logo;
@@ -151,8 +151,6 @@ class CComponentsHeader : public CComponentsForm, public CCTextScreen, CCHeaderT
void initSizeMode();
///sub: init icon object
void initIcon();
///sub: init svg icon object
void initIconSVG();
///sub: init caption object
void initCaption();
///sub: init context button object
@@ -361,9 +359,9 @@ class CComponentsHeader : public CComponentsForm, public CCTextScreen, CCHeaderT
const int& dy = -1)
{cch_logo.Id = channelId; cch_logo.Name = channelName, cch_logo.Align = alignment, cch_logo.dy_max = dy; initCCItems();}
/**Methode to get channel logo object for direct access to its properties and methodes
* @return CComponentsChannelLogoScalable*
* @return CComponentsChannelLogo*
*/
CComponentsChannelLogoScalable* getChannelLogoObject(){return cch_logo_obj;}
CComponentsChannelLogo* getChannelLogoObject(){return cch_logo_obj;}
};
#endif

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Classes for generic GUI-related components.
Copyright (C) 2012-2014, Thilo Graf 'dbt'
Copyright (C) 2012-2021, Thilo Graf 'dbt'
Copyright (C) 2012, Michael Liebmann 'micha-bbg'
License: GPL
@@ -18,10 +18,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
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
@@ -37,440 +35,154 @@
extern CPictureViewer *g_PicViewer;
using namespace std;
//-------------------------------------------------------------------------------------------------------
//sub class CComponentsPicture from CComponentsItem
CComponentsPicture::CComponentsPicture( const int &x_pos, const int &y_pos, const int &w, const int &h,
const std::string& image_name,
CCPictureBase::CCPictureBase(const int &x_pos,
const int &y_pos,
const int &w,
const int &h,
const std::string &image,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent)
fb_pixel_t color_frame,
fb_pixel_t color_background,
fb_pixel_t color_shadow,
const int &transparency_mode)
: CComponentsShapeSquare(x_pos, y_pos, w, h, NULL, shadow_mode, color_frame, color_background, color_shadow)
{
init(x_pos, y_pos, w, h, image_name, parent, shadow_mode, color_frame, color_background, color_shadow, transparent, SCALE);
}
CComponentsPicture::CComponentsPicture( const int &x_pos, const int &y_pos,
const std::string& image_name,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent)
{
init(x_pos, y_pos, 0, 0, image_name, parent, shadow_mode, color_frame, color_background, color_shadow, transparent, NO_SCALE);
}
void CComponentsPicture::init( const int &x_pos, const int &y_pos, const int &w, const int &h,
const string& image_name,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent,
bool allow_scale)
{
//CComponents, CComponentsItem
cc_item_type.id = CC_ITEMTYPE_PICTURE;
cc_item_type.name = image_name.empty() ? "cc_image_box" : image_name;
cc_item_type.name = image.empty() ? "cc_image_box" : image;
cc_bg_image_tr_mode = transparency_mode;
//CComponents
x = x_old = x_pos;
y = y_old = y_pos;
width = width_old = dx = dxc = w;
height = height_old = dy = dyc = h;
dx_orig = dy_orig = 0;
pic_name = pic_name_old = image_name;
shadow = shadow_mode;
shadow_w = OFFSET_SHADOW;
col_frame = color_frame;
col_body_std = color_background;
col_shadow = color_shadow;
col_shadow_clean= col_body_std;
do_scale = allow_scale;
image_cache = NULL; //image
enable_cache = false;
is_image_painted= false;
do_paint = true;
image_transparent = transparent;
cc_paint_cache = false; //bg
keep_dx_aspect = false;
keep_dy_aspect = false;
need_init = true;
initCCItem();
setPicture(image, w, h);
initParent(parent);
if (!pic_name.empty() && pic_name == NEUTRINO_ICON_MUTED)
paintInit(false);
}
void CComponentsPicture::clearCache()
void CCPictureBase::setPicture(const std::string &name, const int &w, const int &h)
{
if (image_cache){
dprintf(DEBUG_DEBUG, "\033[32m[CComponentsPicture] %s - %d: clean up image cache %s\033[0m\n", __func__, __LINE__, pic_name.c_str());
delete[] image_cache;
image_cache = NULL;
}
}
setBodyBGImageName(name, "", "");
void CComponentsPicture::setPicture(const std::string& picture_name)
{
if (pic_name == picture_name)
return;
width = dx = dxc = 0;
height = dy = dyc = 0;
need_init = true;
clearCache();
pic_name = picture_name;
initCCItem();
}
dx_orig = 0;
dy_orig = 0;
int dx_tmp = dx_orig;
int dy_tmp = dy_orig;
void CComponentsPicture::setPicture(const char* picture_name)
{
string s_tmp = "";
if (picture_name)
s_tmp = string(picture_name);
setPicture(s_tmp);
}
void CComponentsPicture::setWidth(const int& w, bool keep_aspect)
{
if (w == width && keep_aspect == keep_dy_aspect)
return;
CComponentsItem::setWidth(w);
need_init = true;
do_scale = true;
keep_dy_aspect = keep_aspect;
initCCItem();
}
void CComponentsPicture::setHeight(const int& h, bool keep_aspect)
{
if (h == height && keep_aspect == keep_dx_aspect)
return;
CComponentsItem::setHeight(h);
need_init = true;
do_scale = true;
keep_dx_aspect = keep_aspect;
initCCItem();
}
void CComponentsPicture::setXPos(const int& xpos)
{
CComponentsItem::setXPos(xpos);
if (xpos == x)
return;
need_init = true;
initCCItem();
}
void CComponentsPicture::setYPos(const int& ypos)
{
CComponentsItem::setYPos(ypos);
if (ypos == y)
return;
need_init = true;
initCCItem();
}
void CComponentsPicture::initCCItem()
{
if (pic_name.empty() || !need_init){
dprintf(DEBUG_DEBUG, "[CComponentsPicture] %s - %d : no init required [file: %s] [need init: %d]...\n", __func__, __LINE__, pic_name.c_str(), need_init);
return;
}
//reset condition for new init
need_init = false;
//check for path or name, set icon or image with full path, has no path, then use as icon and disble scale mode
string::size_type pos = pic_name.find("/", 0);
if (pos == string::npos)
do_scale = false;
// always scale svg's
if (pic_name.find(".svg") == (pic_name.length() - 4))
do_scale = true;
//initial internal size
if (!do_scale){
//use image/icon size as object dimension values
frameBuffer->getIconSize(pic_name.c_str(), &width, &height);
/* frameBuffer->getIconSize() normally evaluates only icon names, no paths.
* So it is possible that we have wrong dimension values.
* So we fall back to picture viewer methode.
* That's always a cramp, why we don't have an unified solution in render classes?
* Anyway...this is only a workaround, otherwies it is possible, that dimension values are wrong or = 0 and
* this could lead to problems if external items are reliant on these values,
* and in worst case, no image would be painted!
*/
if (width == 0 || height == 0){
int dx_tmp, dy_tmp;
g_PicViewer->getSize(pic_name.c_str(), &dx_tmp, &dy_tmp);
if (width == 0)
width = dx_tmp;
if (height == 0)
height = dy_tmp;
}
dx_orig = width;
dy_orig = height;
/* leave init methode here if we in no scale mode
* otherwise goto next step!
*/
return;
}
else{ /* Here we are in scale mode
* first check current item dimensions (width/height) and for different values and
* check internal dimension values (dx/dy) and ensure that values are >0
* real image size
*/
g_PicViewer->getSize(pic_name.c_str(), &dx_orig, &dy_orig);
if ((dx != width || dy != height) || (dx == 0 || dy == 0)){
dx = dx_orig;
dy = dy_orig;
//g_PicViewer->getSize(pic_name.c_str(), &dx, &dy);
}
}
/* on next step check item dimensions (width/height) for 0 values
* and fill with current internal (dx/dy) dimension values.
* values <= 0 are not allowed
*/
if (width == 0)
width = dx;
if (height == 0)
height = dy;
/* on next step, check dimensions and
* leave if dimensions are equal
*/
if (width == dx && height == dy)
if (getBodyBGImage().empty())
return;
/* finally handle scale behavior
* This evaluates the parameters given
* by setters setWidth/setHeight
* these steps are required to assign the current image dimensions to item dimensions
*/
if (keep_dx_aspect && dy)
g_PicViewer->getSize(getBodyBGImage().c_str(), &dx_orig, &dy_orig);
float dx_ratio = static_cast<float>(dx_orig) / static_cast<float>(std::max(1, w));
float dy_ratio = static_cast<float>(dy_orig) / static_cast<float>(std::max(1, h));
dx_tmp = w;
dy_tmp = h;
if (w == 0 && h == 0)
{
float h_ratio = float(height)*100/(float)dy;
width = int(h_ratio*(float)dx/100);
if (frameBuffer->needAlign4Blit() &&
do_scale && (width > 10 || height > 10))
width = frameBuffer->getWidth4FB_HW_ACC(x+fr_thickness, width-2*fr_thickness)+2*fr_thickness;
keep_dx_aspect = false;
}
if (keep_dy_aspect && dx)
{
float w_ratio = float(width)*100/(float)dx;
height = int(w_ratio*(float)dy/100);
keep_dy_aspect = false;
}
//resize image and apply current assigned scale values
int w_2scale = width;
int h_2scale = height;
g_PicViewer->rescaleImageDimensions(&width, &height, w_2scale, h_2scale);
}
void CComponentsPicture::initPosition(int *x_position, int *y_position)
{
*x_position = x;
*y_position = y;
if (cc_parent){ //using of real x/y values to paint images if this picture object is bound in a parent form
*x_position = cc_xr;
*y_position = cc_yr;
}
}
void CComponentsPicture::getRealSize(int* dx_original, int *dy_original)
{
*dx_original = dx_orig;
*dy_original = dy_orig;
}
int CComponentsPicture::getWidth()
{
int w, h;
getSize(&w, &h);
return w;
}
int CComponentsPicture::getHeight()
{
int w, h;
getSize(&w, &h);
return h;
}
void CComponentsPicture::paintPicture()
{
is_image_painted = false;
//initialize image position
int x_pic = x;
int y_pic = y;
initPosition(&x_pic, &y_pic);
x_pic += fr_thickness;
y_pic += fr_thickness;
initCCItem();
if (pic_name.empty()){
clearCache();
return;
}
if (cc_allow_paint){
if (image_cache == NULL){
frameBuffer->SetTransparent(image_transparent);
if (do_scale)
is_image_painted = g_PicViewer->DisplayImage(pic_name, x_pic, y_pic, width-2*fr_thickness, height-2*fr_thickness);
else
is_image_painted = frameBuffer->paintIcon(pic_name, x_pic, y_pic, height, 1, do_paint, paint_bg, col_body_std);
if (is_image_painted){
frameBuffer->SetTransparentDefault();
if (enable_cache && do_scale){
dprintf(DEBUG_DEBUG, "\033[32m[CComponentsPicture] %s - %d: create cached image from pic_name=%s\033[0m\n", __func__, __LINE__, pic_name.c_str());
dxc = width-2*fr_thickness;
dyc = height-2*fr_thickness;
image_cache = getScreen(x_pic, y_pic, dxc, dyc);
}
dx_tmp = dx_orig;
dy_tmp = dy_orig;
}
else
dprintf(DEBUG_NORMAL, "\033[31m[CComponentsPicture] %s - %d: error: paint of image failed: %s\033[0m\n", __func__, __LINE__, pic_name.c_str());
}else{
dprintf(DEBUG_DEBUG, "\033[32m[CComponentsPicture] %s - %d: paint cached image from pic_name=%s\033[0m\n", __func__, __LINE__, pic_name.c_str());
frameBuffer->RestoreScreen(x_pic, y_pic, dxc, dyc, image_cache);
}
}
}
void CComponentsPicture::paint(const bool &do_save_bg)
{
if (pic_name.empty())
return;
paintInit(do_save_bg);
paintPicture();
if (w == 0)
dx_tmp = static_cast<int>(static_cast<float>(dx_orig) / dy_ratio);
if (h == 0)
dy_tmp = static_cast<int>(static_cast<float>(dy_orig) / dx_ratio);
}
void CComponentsPicture::hide()
CCDraw::setWidth(dx_tmp);
CCDraw::setHeight(dy_tmp);
}
void CCPictureBase::setPicture(const char *name, const int &w, const int &h)
{
CComponents::hide();
is_image_painted = false;
std::string s_tmp = "";
if (name)
s_tmp = std::string(name);
setPicture(s_tmp, w, h);
}
bool CComponentsPicture::hasChanges()
void CCPictureBase::setWidth(const int &w, bool keep_aspect)
{
bool ret = false;
if (pic_name != pic_name_old){
pic_name_old = pic_name;
ret = true;
}
if (CCDraw::hasChanges())
ret = true;
return ret;
setPicture(cc_bg_std_image, w, keep_aspect ? 0 : height);
}
void CComponentsPicture::paintTrigger()
void CCPictureBase::setHeight(const int &h, bool keep_aspect)
{
if (!is_painted && !isPicPainted())
paint1();
else
hide();
setPicture(cc_bg_std_image, keep_aspect ? 0 : width, h);
}
void CCPictureBase::getRealSize(int *dx, int *dy)
{
*dx = dx_orig;
*dy = dy_orig;
}
CComponentsChannelLogo::CComponentsChannelLogo( const int &x_pos, const int &y_pos, const int &w, const int &h,
CComponentsChannelLogo::CComponentsChannelLogo(const int &x_pos,
const int &y_pos,
const int &w,
const int &h,
const std::string &channelName,
const uint64_t &channelId,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent)
:CComponentsPicture(x_pos, y_pos, w, h,
"", parent, shadow_mode,
color_frame, color_background, color_shadow, transparent)
{
init(channelId, channelName, SCALE);
}
CComponentsChannelLogo::CComponentsChannelLogo( const int &x_pos, const int &y_pos,
const std::string& channelName,
const uint64_t& channelId,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame, fb_pixel_t color_background, fb_pixel_t color_shadow, int transparent)
:CComponentsPicture(x_pos, y_pos, 0, 0,
"", parent, shadow_mode,
color_frame, color_background, color_shadow, transparent)
{
init(channelId, channelName, NO_SCALE);
}
void CComponentsChannelLogo::init(const uint64_t& channelId, const std::string& channelName, bool allow_scale)
fb_pixel_t color_frame,
fb_pixel_t color_background,
fb_pixel_t color_shadow,
const int &transparency_mode)
: CCPictureBase(x_pos, y_pos, w, h, "", parent, shadow_mode, color_frame, color_background, color_shadow, transparency_mode)
{
cc_item_type.id = CC_ITEMTYPE_CHANNEL_LOGO;
cc_item_type.name = "cc_channel_logo_box";
channel_name = "";
channel_id = 0;
alt_pic_name = "";
enable_event_logo = false;
has_logo = false;
setChannel(channelId, channelName);
do_scale = allow_scale;
setChannel(channelId, channelName, w, h);
}
void CComponentsChannelLogo::setAltLogo(const std::string& picture_name)
void CComponentsChannelLogo::setChannel(const uint64_t &channelId, const std::string &channelName, const int &w, const int &h)
{
if (alt_pic_name == picture_name)
return;
need_init = true;
alt_pic_name = picture_name;
channel_id = 0;
channel_name = "";
has_logo = !alt_pic_name.empty();
if (has_logo)
initCCItem();
}
void CComponentsChannelLogo::setAltLogo(const char* picture_name)
{
string s_tmp = "";
if (picture_name)
s_tmp = string(picture_name);
this->setAltLogo(s_tmp);
}
void CComponentsChannelLogo::setChannel(const uint64_t& channelId, const std::string& channelName)
{
need_init = true;
string image = pic_name;
if (channelId || !channelName.empty()){
if ((channel_id == channelId) && (channel_name == channelName))
need_init = false;
}
std::string image = "";
channel_id = channelId;
channel_name = channelName;
int dummy;
//dimensions not required here, will be handled in member setPicture(), therefore here only dummy variables
int dmy_x, dmy_y;
has_logo = g_PicViewer->GetLogoName(channel_id, channel_name, image, &dmy_x, &dmy_y, false, enable_event_logo);
has_logo = g_PicViewer->GetLogoName(channel_id, channel_name, image, &dummy, &dummy, false, enable_event_logo);
if (!has_logo)//no logo was found, use altrenate icon or logo
//no logo was found, use alternate icon or logo
if (!has_logo)
image = alt_pic_name;
//if logo or alternate image still not available, set has logo to false
//if logo or alternate image not available, set has_logo to false
has_logo = !image.empty();
//refresh object
setPicture(image);
setPicture(image, w, h);
//set has_logo to false if no dimensions were detected
//for sure, if no dimensions were detected set value of has_logo = false
if (width && height)
has_logo = true;
doPaintBg(false);
}
void CComponentsChannelLogo::setAltLogo(const std::string &name, const int &w, const int &h)
{
if (alt_pic_name == name)
return;
alt_pic_name = name;
channel_id = 0;
channel_name = "";
has_logo = !alt_pic_name.empty();
if (has_logo)
setPicture(alt_pic_name, w, h);
}
void CComponentsChannelLogo::setAltLogo(const char *name, const int &w, const int &h)
{
std::string s_tmp = "";
if (name)
s_tmp = std::string(name);
setAltLogo(s_tmp, w, h);
}

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Classes for generic GUI-related components.
Copyright (C) 2012-2014, Thilo Graf 'dbt'
Copyright (C) 2012-2021, Thilo Graf 'dbt'
Copyright (C) 2012, Michael Liebmann 'micha-bbg'
License: GPL
@@ -18,182 +18,110 @@
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, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CC_ITEM_PICTURE_H__
#define __CC_ITEM_PICTURE_H__
#ifndef __CC_ITEM_PICTURE_V2_H__
#define __CC_ITEM_PICTURE_V2_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "cc_base.h"
#include "cc_item.h"
#include "cc_item_shapes.h"
#include <string>
#define NO_SCALE false
#define SCALE true
//! Sub class of CComponentsItem. Shows box with image with assigned attributes.
//! Sub class of CComponentsShapeSquare. Shows box with image with assigned attributes.
/*!
Picture is usable as an object like each other CCItems.
*/
class CComponentsPicture : public CComponentsItem
class CCPictureBase : public CComponentsShapeSquare
{
protected:
///possible image formats
std::vector<std::string> v_ext;
///option to enable disable cache, default = false
bool enable_cache;
///screen cache content for painted image
fb_pixel_t *image_cache;
///current image dimensions
int dx, dy;
///original image dimensions
private:
int dx_orig, dy_orig;
///cached image dimensions
int dxc, dyc;
///property: name of image (without extensionn) full path to image (with extension), icon names to find in /widget/icons.h, icons will paint never scaled
std::string pic_name, pic_name_old;
///indicate that image was sucessful painted
bool is_image_painted;
///sets that image may be painted, default = false
bool do_paint;
///set the transparency of pictures (default = CFrameBuffer::TM_NONE)
int image_transparent;
///set internel paint mode to allow/disallow scale an image, value is assigned with constructor, if defined dimensions w and h = 0, then image scale is enabled
bool do_scale;
///sets internal option for keeping aspect, see also setHeight(), setWidth(), default value = false
bool keep_dx_aspect;
bool keep_dy_aspect;
///helper: indicate for reinit
bool need_init;
///paint item with changed paint and hide effect
void paintTrigger();
void init( const int &x_pos, const int &y_pos, const int &w, const int &h,
const std::string& image_name,
CComponentsForm *parent,
int shadow_mode,
fb_pixel_t color_frame,
fb_pixel_t color_background,
fb_pixel_t color_shadow,
int transparent,
bool allow_scale);
///initialize all required attributes
void initCCItem();
///initialize position of picture object dependendly from settings
void initPosition(int *x_position, int *y_position);
///paint image
void paintPicture();
public:
/*!
Constructor for image objects: use this for scaled images.
Dimensions are defined with parameters w (width) and h (height).
Note: only dimension values >0 causes scaling of image!
Note: See also class CComponentsPictureScalable(). That does the same like this, but uses internal value 0 for parameters w (width) and h (height).
If scaling is not required, you should use overloaded version that comes without dimension parameters.
If no dimensions are defined (in constructor or e.g. with setWidth() or setHeight(),
width and height are defined by image itself and are retrievable e.g. with getWidth() or getHeight().
*/
CComponentsPicture( const int &x_pos, const int &y_pos, const int &w, const int &h,
const std::string& image_name,
CCPictureBase(const int &x_pos,
const int &y_pos,
const int &w,
const int &h,
const std::string &image,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparent = CFrameBuffer::TM_NONE);
const int &transparency_mode = CFrameBuffer::TM_EMPTY);
/*!
Constructor for image objects, use this for non scaled images. This is similar with known method paintIcon() from framebuffer class.
Dimensions are defined by image itself.
Note: you can use the dimension setters setWidth() or setHeight() too, but this has only effects for item body, not for image!
If scaling is required, you should use overloaded version above, that comes with dimension parameters or use
class CComponentsPictureScalable().
*/
CComponentsPicture( const int &x_pos, const int &y_pos,
const std::string& image_name,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparent = CFrameBuffer::TM_NONE);
virtual~CComponentsPicture()
{
clearCache();
}
virtual~CCPictureBase() {};
///sets an image name, full image path or url to an image file
void setPicture(const std::string &name, const int &w = 0, const int &h = 0);
///sets an image name, full image path or url to an image file
void setPicture(const char *name, const int &w = 0, const int &h = 0);
///sets an image name (unscaled icons only), full image path or url to an image file
void setPicture(const std::string& picture_name);
///sets an image name (unscaled icons only), full image path or url to an image file
void setPicture(const char* picture_name);
///returns current assigned image name
std::string getPictureName(){return pic_name;}
std::string getPictureName() {return cc_bg_std_image;}
void SetTransparent(const int &mode) {setBodyBGImageTranparencyMode(mode);}
///set width of object, keep_aspect = true keeps ratio related to height
void setWidth(const int &w, bool keep_aspect = true);
///set height of object, keep_aspect = true keeps ratio related to width
void setHeight(const int &h, bool keep_aspect = true);
///get original image size
void getRealSize(int* dx_orig, int *dy_orig);
///return width of item
int getWidth();
///return height of item
int getHeight();
///set width of object and image, value >0 causes scale of image, parameter keep_aspect = true causes scaling of height with same aspect, default = false
void setWidth(const int& w, bool keep_aspect = false);
///set height of object and image, value >0 causes scale of image, parameter keep_aspect = true causes scaling of width with same aspect, , default = false
void setHeight(const int& h, bool keep_aspect = false);
///set width of object and image related to current screen size, see also CComponentsItem::setWidthP(), parameter as uint8_t
void setWidthP(const uint8_t& w_percent){CComponentsItem::setWidthP(w_percent), do_scale = true; need_init = hasChanges(); initCCItem();}
///set height of object and image related to current screen size, see also CComponentsItem::setHeightP(), parameter as uint8_t
void setHeightP(const uint8_t& h_percent){CComponentsItem::setHeightP(h_percent), do_scale = true; need_init = hasChanges(); initCCItem();}
///set screen x-position, parameter as int
void setXPos(const int& xpos);
///set screen y-position, parameter as int
void setYPos(const int& ypos);
///return paint mode of internal image, true=image was painted, please do not to confuse with isPainted()! isPainted() is related to item itself.
bool isPicPainted(){return is_image_painted;};
/**sets transparency mode if icons
* @param[in] t Transparency mode
* @li t = CFrameBuffer::TM_BLACK : Transparency when black content ('pseudo' transparency)
* @li t = CFrameBuffer::TM_NONE : No 'pseudo' transparency
*/
void SetTransparent(int t){ image_transparent = t; }
///paint item
void paint(const bool &do_save_bg = CC_SAVE_SCREEN_YES);
///hide item, see also CComponents::hide();
void hide();
bool hasChanges();
///remove possible cache
void clearCache();
///enable/disable image cache
void enableCache(bool enable = true){if (enable_cache == enable) return; enable_cache = enable; if (!enable_cache) clearCache();}
///disable image cache, makes clean up too
void disableCache(){enableCache(false);}
void getRealSize(int *dx, int *dy);
};
class CComponentsChannelLogo : public CComponentsPicture
class CComponentsPicture : public CCPictureBase
{
public:
/*!
Use this for non scaled images.
Dimensions are defined by image itself.
If scaling is required, you should use class CComponentsPicture with dimension parameters see next.
width and height are defined by give image dimensions itself and are retrievable e.g. with getWidth() or getHeight().
*/
CComponentsPicture(const int &x_pos,
const int &y_pos,
const std::string &image,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparency_mode = CFrameBuffer::TM_EMPTY)
: CCPictureBase(x_pos, y_pos, 0, 0, image, parent, shadow_mode, color_frame, color_background, color_shadow, transparency_mode) {};
/*!
Use this for scaled images.
Dimensions are defined with parameters w (width) and h (height).
Only dimension values > 0 have a scale effect!
If one of the dimension parameters = 0, the ratio of image will be kept.
If scaling is not required, you should use overloaded class CComponentsPicture without dimension parameters or set values of w and h = 0.
width and height are retrievable e.g. with getWidth() or getHeight().
*/
CComponentsPicture(const int &x_pos,
const int &y_pos,
const int &w,
const int &h,
const std::string &image,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparency_mode = CFrameBuffer::TM_EMPTY)
: CCPictureBase(x_pos, y_pos, w, h, image, parent, shadow_mode, color_frame, color_background, color_shadow, transparency_mode) {};
virtual~CComponentsPicture() {};
};
class CComponentsChannelLogo : public CCPictureBase
{
private:
///channel id
@@ -210,7 +138,7 @@ class CComponentsChannelLogo : public CComponentsPicture
///indicates that logo is available, after paint or new instance, value = false
bool has_logo;
void init(const uint64_t& channelId, const std::string& channelName, bool allow_scale);
// void init(const uint64_t& channelId, const std::string &channelName, bool allow_scale);
public:
/*!
@@ -219,7 +147,10 @@ class CComponentsChannelLogo : public CComponentsPicture
Requires parameter channel_name or channelId instead image filename
NOTE: channel name string is prefered!
*/
CComponentsChannelLogo( const int &x_pos, const int &y_pos, const int &w, const int &h,
CComponentsChannelLogo(const int &x_pos,
const int &y_pos,
const int &w,
const int &h,
const std::string &channelName = "",
const uint64_t &channelId = 0,
CComponentsForm *parent = NULL,
@@ -227,7 +158,26 @@ class CComponentsChannelLogo : public CComponentsPicture
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparent = CFrameBuffer::TM_BLACK);
const int &transparency_mode = CFrameBuffer::TM_EMPTY);
virtual~CComponentsChannelLogo() {};
///set channel id and/or channel name, NOTE: channel name is prefered
void setChannel(const uint64_t &channelId, const std::string &channelName, const int &w = 0, const int &h = 0);
uint64_t getChannelID() {return channel_id;}
///set an alternate logo if no logo is available NOTE: value of has_logo will set to true
void setAltLogo(const std::string &name, const int &w = 0, const int &h = 0);
///set an alternate logo if no logo is available, NOTE: value of has_logo will set to true
void setAltLogo(const char *name, const int &w = 0, const int &h = 0);
///enable/disable eventlogo
void enableEventLogo(bool enable = true) {enable_event_logo = enable;}
void disableEventLogo() {enableEventLogo(false);}
///returns true, if any logo is available, also if an alternate logo was defined
bool hasLogo() {return has_logo;}
/*!
Constructor for channel image objects: use this for non scaled channel logos.
@@ -235,7 +185,8 @@ class CComponentsChannelLogo : public CComponentsPicture
Requires parameter channel_name or channelId instead image filename
NOTE: channel name string is prefered!
*/
CComponentsChannelLogo( const int &x_pos, const int &y_pos,
CComponentsChannelLogo(const int &x_pos,
const int &y_pos,
const std::string &channelName = "",
const uint64_t &channelId = 0,
CComponentsForm *parent = NULL,
@@ -243,49 +194,8 @@ class CComponentsChannelLogo : public CComponentsPicture
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparent = CFrameBuffer::TM_BLACK);
///set channel id and/or channel name, NOTE: channel name is prefered
void setChannel(const uint64_t& channelId, const std::string& channelName);
uint64_t getChannelID(){return channel_id;}
///set an alternate logo if no logo is available NOTE: value of has_logo will set to true
void setAltLogo(const std::string& picture_name);
///set an alternate logo if no logo is available, NOTE: value of has_logo will set to true
void setAltLogo(const char* picture_name);
///enable/disable eventlogo
void enableEventLogo(bool enable = true){enable_event_logo = enable;}
void disableEventLogo(){enableEventLogo(false);}
///returns true, if any logo is available, also if an alternate logo was setted
bool hasLogo(){return has_logo;};
const int &transparency_mode = CFrameBuffer::TM_EMPTY)
: CComponentsChannelLogo(x_pos, y_pos, 0, 0, channelName, channelId, parent, shadow_mode, color_frame, color_background, color_shadow, transparency_mode) {};
};
class CComponentsChannelLogoScalable : public CComponentsChannelLogo
{
public:
/*!
Constructor for channel image objects: use this for scaled channel logos.
Does the same like class CComponentsPictureScalable(), see above!
Requires parameter channel_name or channelId instead image filename.
NOTE: channel name string is prefered!
*/
CComponentsChannelLogoScalable( const int &x_pos, const int &y_pos,
const std::string& channelName = "",
const uint64_t& channelId =0,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
fb_pixel_t color_background = 0,
fb_pixel_t color_shadow = COL_SHADOW_PLUS_0,
int transparent = CFrameBuffer::TM_BLACK)
: CComponentsChannelLogo(x_pos, y_pos, 0, 0, channelName, channelId, parent, shadow_mode, color_frame, color_background, color_shadow, transparent)
{
cc_item_type.id = CC_ITEMTYPE_CHANNEL_LOGO_SCALABLE;
cc_item_type.name = "cc_scalable_channellogo_box";
};
};
#endif
#endif //__CC_ITEM_PICTURE_V2_H__

View File

@@ -85,7 +85,9 @@ CTestMenu::CTestMenu()
width = 50;
circle = NULL;
sq = NULL;
pic = chnl_pic = NULL;
pic = NULL;
picsvg = NULL;
chnl_pic = NULL;
form = NULL;
txt = NULL;
header = NULL;
@@ -104,6 +106,7 @@ CTestMenu::~CTestMenu()
delete sq;
delete circle;
delete pic;
delete picsvg;
delete form;
delete txt;
delete header;
@@ -430,11 +433,22 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
if (pic == NULL)
pic = new CComponentsPicture (100, 100, 200, 100, ICONSDIR "/mp3-5.jpg");
if (!pic->isPainted() && !pic->isPicPainted())
if (!pic->isPainted())
pic->paint();
else
pic->hide();
return res;
}
else if (actionKey == "picture_svg"){
if (picsvg == NULL)
picsvg = new CComponentsPicture (100, 100, 100, 0, "tux");
if (!picsvg->isPainted())
picsvg->paint();
else
picsvg->hide();
return res;
}
else if (actionKey == "blink"){
if (sq == NULL)
@@ -461,13 +475,25 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
return res;
}
else if (actionKey == "channellogo"){
if (chnl_pic == NULL)
chnl_pic = new CComponentsChannelLogo(100, 100, "ProSieben", 0);
uint64_t chid = CZapit::getInstance()->GetCurrentChannelID();
std::string chname = "";
if (CServiceManager::getInstance()->FindChannel(chid))
chname = CServiceManager::getInstance()->FindChannel(chid)->getName();
if (!chnl_pic->isPainted() && !chnl_pic->isPicPainted())
if (chnl_pic == NULL)
chnl_pic = new CComponentsChannelLogo(100, 100, 0, 50, chname, chid);
if (!chnl_pic->isPainted())
{
chnl_pic->paint();
ShowHint("Logotest", chnl_pic->getPictureName().c_str(), 700, 2);
}
else
{
chnl_pic->hide();
delete chnl_pic;
chnl_pic = NULL;
}
return res;
}
else if (actionKey == "form"){
@@ -602,14 +628,14 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
return res;
}
else if (actionKey == "header"){
int hh = 30;//g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight();
int hh = 0;//g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight();
if (header == NULL){
header = new CComponentsHeader (100, 50, 500, hh, "Test-Header"/*, NEUTRINO_ICON_INFO, CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU*/);
header->addContextButton(NEUTRINO_ICON_BUTTON_RED);
header->addContextButton(CComponentsHeader::CC_BTN_HELP | CComponentsHeader::CC_BTN_EXIT | CComponentsHeader::CC_BTN_MENU);
}
else{ //For existing instances it's recommended to remove old button icons before add new buttons,
//otherwise icons will be appended to already existant icons, alternatively use the setContextButton() methode
//otherwise icons will be appended to already existent icons, alternatively use the setContextButton() methode
header->removeContextButtons();
//enable clock in header with default format
header->enableClock(true, "%H:%M", "%H %M", true);
@@ -1278,6 +1304,7 @@ void CTestMenu::showCCTests(CMenuWidget *widget)
widget->addItem(new CMenuForwarder("Blinking-Square", true, NULL, this, "blink"));
widget->addItem(new CMenuForwarder("Blinking-Image", true, NULL, this, "blink_image"));
widget->addItem(new CMenuForwarder("Picture", true, NULL, this, "picture"));
widget->addItem(new CMenuForwarder("Picture SVG", true, NULL, this, "picture_svg"));
widget->addItem(new CMenuForwarder("Channel-Logo", true, NULL, this, "channellogo"));
widget->addItem(new CMenuForwarder("Form", true, NULL, this, "form"));
widget->addItem(new CMenuForwarder("Form with blinking item", true, NULL, this, "form_blink_item"));

View File

@@ -43,6 +43,7 @@ class CTestMenu : public CMenuTarget
CComponentsShapeCircle * circle;
CComponentsShapeSquare* sq;
CComponentsPicture *pic;
CComponentsPicture *picsvg;
CComponentsForm *form;
CComponentsText *txt;
CComponentsHeader *header;