mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-28 16:01:20 +02:00
CComponentsFrmClock: add new class CComponentsFrmClock
This commit is contained in:
@@ -28,6 +28,7 @@ libneutrino_gui_components_a_SOURCES = \
|
||||
cc_detailsline.cpp \
|
||||
cc_frm_button.cpp \
|
||||
cc_frm.cpp \
|
||||
cc_frm_clock.cpp \
|
||||
cc_frm_header.cpp \
|
||||
cc_frm_icons.cpp \
|
||||
cc_frm_window.cpp \
|
||||
|
302
src/gui/components/cc_frm_clock.cpp
Normal file
302
src/gui/components/cc_frm_clock.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
Based up Neutrino-GUI - Tuxbox-Project
|
||||
Copyright (C) 2001 by Steffen Hehn 'McClean'
|
||||
|
||||
Generic GUI-related component.
|
||||
Copyright (C) 2013, 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, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <global.h>
|
||||
#include <neutrino.h>
|
||||
|
||||
#include "cc_frm_clock.h"
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
CComponentsFrmClock::CComponentsFrmClock( const int x_pos, const int y_pos, const int w, const int h,
|
||||
const char* format_str, bool has_shadow,
|
||||
fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow)
|
||||
|
||||
{
|
||||
initVarClock();
|
||||
|
||||
x = x_pos;
|
||||
y = y_pos;
|
||||
width = w;
|
||||
height = h;
|
||||
shadow = has_shadow;
|
||||
shadow_w = SHADOW_OFFSET;
|
||||
col_frame = color_frame;
|
||||
col_body = color_body;
|
||||
col_shadow = color_shadow;
|
||||
|
||||
cl_format_str = format_str;
|
||||
}
|
||||
|
||||
void CComponentsFrmClock::initVarClock()
|
||||
{
|
||||
initVarForm();
|
||||
cc_item_type = CC_ITEMTYPE_FRM_CLOCK;
|
||||
corner_rad = RADIUS_SMALL;
|
||||
|
||||
cl_font_type = SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO;
|
||||
cl_font = NULL;
|
||||
cl_format_str = "%H:%M";
|
||||
cl_align = CC_ALIGN_VER_CENTER | CC_ALIGN_HOR_CENTER;
|
||||
// cl_force_segment_paint = false;
|
||||
|
||||
cl_thread = 0;
|
||||
cl_interval = 1;
|
||||
}
|
||||
|
||||
CComponentsFrmClock::~CComponentsFrmClock()
|
||||
{
|
||||
cleanCCForm();
|
||||
if(cl_thread)
|
||||
pthread_cancel(cl_thread);
|
||||
cl_thread = 0;
|
||||
}
|
||||
|
||||
void CComponentsFrmClock::initTimeString()
|
||||
{
|
||||
time_t tm = time(0);
|
||||
strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format_str, localtime(&tm));
|
||||
}
|
||||
|
||||
// How does it works?
|
||||
// We don't paint complete date or time string at once, because of individual possible formats,
|
||||
// so we split timestring and assign only one char to one lable (segment)
|
||||
|
||||
// x/y width
|
||||
// +--------------------------+
|
||||
// ||lbl0|lbl1|lbl2|lbl3|lbl4||
|
||||
// || | | | | ||height
|
||||
// || | | | | ||
|
||||
// +--------------------------+
|
||||
|
||||
// So every item (lable or segment) contains only one char depending on specified format. eg: format %H:%M gives 5 items.
|
||||
// The effort is slightly greater and it's necessary to avoid flicker effect, but it's more flexible.
|
||||
|
||||
void CComponentsFrmClock::initCCLockItems()
|
||||
{
|
||||
initTimeString();
|
||||
string s_time = cl_timestr;
|
||||
|
||||
cl_font = g_Font[cl_font_type];
|
||||
|
||||
//get minimal required height, width from raw text
|
||||
int min_text_w = cl_font->getRenderWidth(s_time, true);;
|
||||
int min_text_h = cl_font->getHeight();
|
||||
height = max(height, min_text_h);
|
||||
width = max(width, min_text_w);
|
||||
|
||||
int cl_x = 0;
|
||||
int cl_h = min_text_h;
|
||||
int cl_y = 0;
|
||||
int w_lbl_tmp = 0;
|
||||
|
||||
//create label objects and add to container, ensure count of items = count of chars (one char = one segment)
|
||||
if (v_cc_items.size() != s_time.size()){
|
||||
|
||||
//clean up possible old items before add new items
|
||||
clearCCItems();
|
||||
|
||||
//create new empty label objects, set some general properties and add to container
|
||||
for (size_t i = 0; i < s_time.size(); i++){
|
||||
CComponentsLabel * lbl = new CComponentsLabel();
|
||||
addCCItem(lbl);
|
||||
|
||||
//background paint of item is not required
|
||||
lbl->doPaintBg(false);
|
||||
|
||||
//set corner properties of label item
|
||||
lbl->setCornerRadius(corner_rad-fr_thickness);
|
||||
lbl->setCornerType(corner_type);
|
||||
}
|
||||
}
|
||||
|
||||
//modifie available lable items with current segment chars
|
||||
for (size_t i = 0; i < v_cc_items.size(); i++)
|
||||
{
|
||||
//v_cc_items are only available as CComponent-items here, so we must cast them before
|
||||
CComponentsLabel *lbl = static_cast <CComponentsLabel*> (v_cc_items[i]);
|
||||
|
||||
//add rounded corners only to 1st and last segment
|
||||
if (corner_type) {
|
||||
if (i == 0)
|
||||
lbl->setCornerType(corner_type & CORNER_LEFT);// 1st label item
|
||||
else if (i == v_cc_items.size()-1)
|
||||
lbl->setCornerType(corner_type & CORNER_RIGHT);// last label item
|
||||
else
|
||||
lbl->setCornerType(0);// inner items
|
||||
}
|
||||
|
||||
//extract timestring segment (char)
|
||||
string stmp = s_time.substr(i, 1);
|
||||
|
||||
//get width of current segment
|
||||
int wtmp = cl_font->getRenderWidth(stmp, true);
|
||||
|
||||
//set size, text, color of current item
|
||||
lbl->setDimensionsAll(cl_x, cl_y, wtmp, cl_h);
|
||||
lbl->setTextColor(COL_MENUCONTENT);
|
||||
lbl->setText(stmp, CTextBox::CENTER, cl_font);
|
||||
|
||||
//use matching height for digits for better vertical centerring into form
|
||||
CTextBox* ctb = lbl->getCTextBoxObject();
|
||||
if (ctb)
|
||||
ctb->setFontUseDigitHeight();
|
||||
|
||||
//ensure paint of text and label bg on changed text or painted form background
|
||||
bool force_txt_and_bg = (lbl->textChanged() || this->paint_bg);
|
||||
lbl->forceTextPaint(force_txt_and_bg);
|
||||
lbl->doPaintTextBoxBg(force_txt_and_bg);
|
||||
|
||||
//set xpos of item
|
||||
cl_x += wtmp;
|
||||
|
||||
lbl->setWidth(wtmp);
|
||||
|
||||
//set current width for form
|
||||
w_lbl_tmp += wtmp;
|
||||
}
|
||||
|
||||
//set required width
|
||||
width = max(width, w_lbl_tmp);
|
||||
|
||||
initSegmentAlign(&w_lbl_tmp, &min_text_h);
|
||||
}
|
||||
|
||||
//handle alignment
|
||||
void CComponentsFrmClock::initSegmentAlign(int* segment_width, int* segment_height)
|
||||
{
|
||||
int wadd = 0;
|
||||
int hadd = 0;
|
||||
int* w_lbl_tmp = segment_width;
|
||||
int* min_text_h = segment_height;
|
||||
|
||||
//use first item as reference and set x and y position to the 1st segement item with definied alignment
|
||||
if (cl_align & CC_ALIGN_RIGHT){
|
||||
wadd = width-*w_lbl_tmp;
|
||||
v_cc_items[0]->setXPos(wadd);
|
||||
}
|
||||
else if (cl_align & CC_ALIGN_LEFT){
|
||||
v_cc_items[0]->setXPos(wadd);
|
||||
}
|
||||
else if (cl_align & CC_ALIGN_HOR_CENTER){
|
||||
hadd = height/2-*min_text_h/2;
|
||||
v_cc_items[0]->setYPos(hadd);
|
||||
}
|
||||
|
||||
if (cl_align & CC_ALIGN_TOP){
|
||||
v_cc_items[0]->setYPos(hadd);
|
||||
}
|
||||
else if (cl_align & CC_ALIGN_BOTTOM){
|
||||
hadd = height-*min_text_h;
|
||||
v_cc_items[0]->setYPos(hadd);
|
||||
}
|
||||
else if (cl_align & CC_ALIGN_VER_CENTER){
|
||||
wadd = width/2-*w_lbl_tmp/2;
|
||||
v_cc_items[0]->setXPos(wadd);
|
||||
}
|
||||
|
||||
//set all evaluated position values to all other segement items
|
||||
for (size_t i = 1; i < v_cc_items.size(); i++){
|
||||
wadd += v_cc_items[i-1]->getWidth();
|
||||
v_cc_items[i]->setPos(wadd, hadd);
|
||||
}
|
||||
}
|
||||
|
||||
//thread handle
|
||||
void* CComponentsFrmClock::initClockThread(void *arg)
|
||||
{
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,0);
|
||||
|
||||
CComponentsFrmClock *clock = static_cast<CComponentsFrmClock*>(arg);
|
||||
|
||||
//ensure paint of segements on first paint
|
||||
clock->paint();
|
||||
|
||||
//start loop for paint
|
||||
while(1) {
|
||||
sleep(clock->cl_interval);
|
||||
|
||||
//paint segements, but wihtout saved backgrounds
|
||||
clock->paint(CC_SAVE_SCREEN_NO);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//start up ticking clock with own thread, return true on succses
|
||||
bool CComponentsFrmClock::Start()
|
||||
{
|
||||
void *ptr = static_cast<void*>(this);
|
||||
|
||||
if(!cl_thread) {
|
||||
int res1 = pthread_create (&cl_thread, NULL, initClockThread, ptr) ;
|
||||
int res2 = pthread_detach(cl_thread);
|
||||
|
||||
if (res1 != 0){
|
||||
printf("[CComponentsFrmClock] [%s] pthread_create %s\n", __FUNCTION__, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (res2 != 0){
|
||||
printf("[CComponentsFrmClock] [%s] pthread_detach %s\n", __FUNCTION__, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//stop ticking clock and kill thread, return true on succses
|
||||
bool CComponentsFrmClock::Stop()
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if(cl_thread)
|
||||
res = pthread_cancel(cl_thread);
|
||||
|
||||
if (res != 0){
|
||||
printf("[CComponentsFrmClock] [%s] pthread_cancel %s\n", __FUNCTION__, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
cl_thread = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CComponentsFrmClock::paint(bool do_save_bg)
|
||||
{
|
||||
//prepare items before paint
|
||||
initCCLockItems();
|
||||
|
||||
//paint form contents
|
||||
paintForm(do_save_bg);
|
||||
}
|
104
src/gui/components/cc_frm_clock.h
Normal file
104
src/gui/components/cc_frm_clock.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Based up Neutrino-GUI - Tuxbox-Project
|
||||
Copyright (C) 2001 by Steffen Hehn 'McClean'
|
||||
|
||||
Classes for generic GUI-related components.
|
||||
Copyright (C) 2012, 2013, 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, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CC_CLOCK__
|
||||
#define __CC_CLOCK__
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "cc.h"
|
||||
#include "cc_frm.h"
|
||||
|
||||
|
||||
//! Sub class of CComponents. Show clock with digits on screen.
|
||||
/*!
|
||||
Usable as simple fixed display or as ticking clock.
|
||||
*/
|
||||
|
||||
class CComponentsFrmClock : public CComponentsForm
|
||||
{
|
||||
private:
|
||||
|
||||
// bool cl_force_segment_paint;
|
||||
|
||||
protected:
|
||||
///thread
|
||||
pthread_t cl_thread;
|
||||
///refresh interval in seconds
|
||||
int cl_interval;
|
||||
///init function to start clock in own thread
|
||||
static void* initClockThread(void *arg);
|
||||
|
||||
///raw time chars
|
||||
char cl_timestr[20];
|
||||
|
||||
///font
|
||||
int cl_font_type;
|
||||
///fontrenderer object
|
||||
Font *cl_font;
|
||||
///time format
|
||||
const char* cl_format_str;
|
||||
///time string align, default allign is ver and hor centered
|
||||
int cl_align;
|
||||
|
||||
///initialize all attributes and required objects
|
||||
void initVarClock();
|
||||
|
||||
///initialize clock contents
|
||||
void initCCLockItems();
|
||||
///initialize timestring, called in initCCLockItems()
|
||||
void initTimeString();
|
||||
///initialize of general alignment of timestring segments within form area
|
||||
void initSegmentAlign(int* segment_width, int* segment_height);
|
||||
|
||||
public:
|
||||
CComponentsFrmClock( const int x_pos, const int y_pos, const int w, const int h,
|
||||
const char* format_str = "%H:%M", bool has_shadow = CC_SHADOW_OFF,
|
||||
fb_pixel_t color_frame = COL_LIGHT_GRAY, fb_pixel_t color_body = COL_MENUCONTENT_PLUS_0, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0);
|
||||
~CComponentsFrmClock();
|
||||
|
||||
///set font type for segments
|
||||
void setClockFontType(const int& font_type){cl_font_type = font_type;};
|
||||
|
||||
///set alignment of timestring, possible modes see align types in cc_types.h
|
||||
void setClockAlignment(int align_type){cl_align = align_type;};
|
||||
|
||||
///use string expession: "%H:%M" = 12:22, "%H:%M:%S" = 12:22:12
|
||||
void setClockFormat(const char* format_str){cl_format_str = format_str;};
|
||||
|
||||
///start ticking clock thread, returns true on success, if false causes log output
|
||||
bool Start();
|
||||
///stop ticking clock thread, returns true on success, if false causes log output
|
||||
bool Stop();
|
||||
///returns true, if clock is running in thread
|
||||
bool isClockRun() const {return cl_thread == 0 ? false:true;};
|
||||
///set refresh interval in seconds, default value=1 (=1 sec)
|
||||
void setClockIntervall(const int& seconds){cl_interval = seconds;};
|
||||
|
||||
///show clock on screen
|
||||
void paint(bool do_save_bg = CC_SAVE_SCREEN_YES);
|
||||
};
|
||||
|
||||
#endif
|
@@ -40,6 +40,7 @@ typedef enum
|
||||
CC_ITEMTYPE_SHAPE_CIRCLE,
|
||||
CC_ITEMTYPE_PIP,
|
||||
CC_ITEMTYPE_FRM,
|
||||
CC_ITEMTYPE_FRM_CLOCK,
|
||||
CC_ITEMTYPE_FRM_HEADER,
|
||||
CC_ITEMTYPE_FRM_ICONFORM,
|
||||
CC_ITEMTYPE_FRM_WINDOW,
|
||||
|
@@ -71,6 +71,7 @@ CTestMenu::CTestMenu()
|
||||
iconform = NULL;
|
||||
window = NULL;
|
||||
button = NULL;
|
||||
clock = clock_r = NULL;
|
||||
}
|
||||
|
||||
CTestMenu::~CTestMenu()
|
||||
@@ -84,6 +85,8 @@ CTestMenu::~CTestMenu()
|
||||
delete iconform;
|
||||
delete window;
|
||||
delete button;
|
||||
delete clock;
|
||||
delete clock_r;
|
||||
}
|
||||
|
||||
int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
|
||||
@@ -527,6 +530,40 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
|
||||
|
||||
return res;
|
||||
}
|
||||
else if (actionKey == "running_clock"){
|
||||
if (clock_r == NULL){
|
||||
clock_r = new CComponentsFrmClock(100, 50, 0, 50, "%H.%M:%S");
|
||||
clock_r->setClockFontType(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME);
|
||||
clock_r->setClockIntervall(1);
|
||||
// clock_r->doPaintBg(false);
|
||||
}
|
||||
|
||||
if (!clock_r->isClockRun()){
|
||||
if (clock_r->Start())
|
||||
return menu_return::RETURN_EXIT_ALL;;
|
||||
}
|
||||
else if (clock_r->isClockRun()){
|
||||
if (clock_r->Stop()){
|
||||
clock_r->hide();
|
||||
delete clock;
|
||||
clock = NULL;
|
||||
return menu_return::RETURN_EXIT_ALL;;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (actionKey == "clock"){
|
||||
if (clock == NULL){
|
||||
clock = new CComponentsFrmClock(100, 50, 0, 50, "%H:%M");
|
||||
clock->setClockFontType(SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME);
|
||||
}
|
||||
|
||||
if (!clock->isPainted())
|
||||
clock->paint();
|
||||
else
|
||||
clock->hide();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
return showTestMenu();
|
||||
@@ -563,6 +600,8 @@ int CTestMenu::showTestMenu()
|
||||
void CTestMenu::showCCTests(CMenuWidget *widget)
|
||||
{
|
||||
widget->addIntroItems();
|
||||
widget->addItem(new CMenuForwarderNonLocalized("Running Clock", true, NULL, this, "running_clock"));
|
||||
widget->addItem(new CMenuForwarderNonLocalized("Clock", true, NULL, this, "clock"));
|
||||
widget->addItem(new CMenuForwarderNonLocalized("Button", true, NULL, this, "button"));
|
||||
widget->addItem(new CMenuForwarderNonLocalized("Circle", true, NULL, this, "circle"));
|
||||
widget->addItem(new CMenuForwarderNonLocalized("Square", true, NULL, this, "square"));
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <gui/components/cc.h>
|
||||
#include <gui/components/cc_frm.h>
|
||||
#include <gui/components/cc_frm_button.h>
|
||||
#include <gui/components/cc_frm_clock.h>
|
||||
#define TEST_MENU
|
||||
|
||||
#include <string>
|
||||
@@ -50,6 +51,7 @@ class CTestMenu : public CMenuTarget
|
||||
CComponentsIconForm *iconform;
|
||||
CComponentsWindow *window;
|
||||
CComponentsButton *button;
|
||||
CComponentsFrmClock *clock ,*clock_r;
|
||||
int width, selected;
|
||||
|
||||
int showTestMenu();
|
||||
|
Reference in New Issue
Block a user