Files
neutrino/src/gui/psisetup.cpp
2020-08-02 21:30:51 +02:00

313 lines
8.8 KiB
C++

/*
(C)2012-2013 by martii
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gui/psisetup.h>
#include <driver/fontrenderer.h>
#include <driver/rcinput.h>
#include <gui/color.h>
#include <gui/widget/msgbox.h>
#include <gui/widget/icons.h>
#include <driver/screen_max.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <global.h>
#include <neutrino.h>
#include <hardware/video.h>
extern cVideo * videoDecoder;
struct PSI_list
{
int control;
const neutrino_locale_t loc;
bool selected;
CProgressBar *scale;
unsigned char value;
unsigned char value_old;
int x;
int y;
int xLoc;
int yLoc;
int xBox;
int yBox;
};
#define PSI_SCALE_COUNT 5
static PSI_list
psi_list[PSI_SCALE_COUNT] = {
#define PSI_CONTRAST 0
{ VIDEO_CONTROL_CONTRAST, LOCALE_VIDEOMENU_PSI_CONTRAST, true, NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define PSI_SATURATION 1
, { VIDEO_CONTROL_SATURATION, LOCALE_VIDEOMENU_PSI_SATURATION, false, NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define PSI_BRIGHTNESS 2
, { VIDEO_CONTROL_BRIGHTNESS, LOCALE_VIDEOMENU_PSI_BRIGHTNESS, false, NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define PSI_TINT 3
, { VIDEO_CONTROL_HUE, LOCALE_VIDEOMENU_PSI_TINT, false, NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define PSI_RESET 4
, { -1, LOCALE_VIDEOMENU_PSI_RESET, false, NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
};
#define SLIDERWIDTH 200
#define SLIDERHEIGHT 15
#define LOCGAP 5
CPSISetup::CPSISetup (const neutrino_locale_t Name)
{
frameBuffer = CFrameBuffer::getInstance ();
name = Name;
selected = 0;
for (int i = 0; i < PSI_RESET; i++)
psi_list[i].scale = new CProgressBar();
psi_list[PSI_CONTRAST].value = g_settings.psi_contrast;
psi_list[PSI_SATURATION].value = g_settings.psi_saturation;
psi_list[PSI_BRIGHTNESS].value = g_settings.psi_brightness;
psi_list[PSI_TINT].value = g_settings.psi_tint;
for (int i = 0; i < PSI_RESET; i++)
videoDecoder->SetControl (psi_list[i].control, psi_list[i].value);
needsBlit = true;
}
void CPSISetup::blankScreen(bool blank) {
for (int i = 0; i < PSI_RESET; i++)
videoDecoder->SetControl(psi_list[i].control, blank ? 0 : psi_list[i].value);
}
int CPSISetup::exec (CMenuTarget * parent, const std::string &)
{
neutrino_msg_t msg;
neutrino_msg_data_t data;
locWidth = 0;
for (int i = 0; i < PSI_RESET; i++)
{
int w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth (g_Locale->getText(psi_list[i].loc)) + 3; // UTF-8
if (w > locWidth)
locWidth = w;
}
locHeight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight ();
if (locHeight < SLIDERHEIGHT)
locHeight = SLIDERHEIGHT + 2;
sliderOffset = (locHeight - SLIDERHEIGHT) >> 1;
// [ SLIDERWIDTH ][5][locwidth ]
// [locHeight][XXXXXXXXXXXXX] [XXXXXXXXXXXX]
// [locHeight][XXXXXXXXXXXXX] [XXXXXXXXXXXX]
// [locHeight][XXXXXXXXXXXXX] [XXXXXXXXXXXX]
// [locHeight][XXXXXXXXXXXXX] [XXXXXXXXXXXX]
// [locHeight] [XXXXXXXXXXXX]
dx = SLIDERWIDTH + LOCGAP + locWidth;
dy = PSI_SCALE_COUNT * locHeight + (PSI_SCALE_COUNT - 1) * 2;
x = frameBuffer->getScreenX() + ((frameBuffer->getScreenWidth() - dx) >> 1);
y = frameBuffer->getScreenY() + ((frameBuffer->getScreenHeight() - dy) >> 1);
int res = menu_return::RETURN_REPAINT;
if (parent)
parent->hide ();
for (int i = 0; i < PSI_SCALE_COUNT; i++)
{
psi_list[i].value = psi_list[i].value_old = 128;
psi_list[i].x = x;
psi_list[i].y = y + locHeight * i + i * 2;
psi_list[i].xBox = psi_list[i].x + SLIDERWIDTH + LOCGAP;
psi_list[i].yBox = psi_list[i].y;
psi_list[i].xLoc = psi_list[i].x + SLIDERWIDTH + LOCGAP + 2;
psi_list[i].yLoc = psi_list[i].y + locHeight - 1;
}
psi_list[PSI_RESET].xLoc = x + 20;
psi_list[PSI_RESET].xBox = x;
for (int i = 0; i < PSI_RESET; i++)
psi_list[i].scale->reset ();
psi_list[PSI_CONTRAST].value = g_settings.psi_contrast;
psi_list[PSI_SATURATION].value = g_settings.psi_saturation;
psi_list[PSI_BRIGHTNESS].value = g_settings.psi_brightness;
psi_list[PSI_TINT].value = g_settings.psi_tint;
for (int i = 0; i < PSI_RESET; i++)
psi_list[i].value_old = psi_list[i].value;
paint();
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] ? g_settings.timing[SNeutrinoSettings::TIMING_MENU] : 0xffff);
bool loop = true;
while (loop)
{
if(needsBlit) {
frameBuffer->blit();
needsBlit = false;
}
g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd, true);
if ( msg <= CRCInput::RC_MaxRC )
timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] ? g_settings.timing[SNeutrinoSettings::TIMING_MENU] : 0xffff);
int i;
int direction = 1; // down
switch (msg)
{
case CRCInput::RC_up:
direction = -1;
/* fall through */
case CRCInput::RC_down:
if (selected + direction > -1 && selected + direction < PSI_SCALE_COUNT)
{
psi_list[selected].selected = false;
paintSlider (selected);
selected += direction;
psi_list[selected].selected = true;
paintSlider (selected);
}
break;
case CRCInput::RC_right:
if (selected < PSI_RESET && psi_list[selected].value < 255)
{
int val = psi_list[selected].value + g_settings.psi_step;
psi_list[selected].value = (val > 255) ? 255 : val;
paintSlider (selected);
videoDecoder->SetControl(psi_list[selected].control, psi_list[selected].value);
}
break;
case CRCInput::RC_left:
if (selected < PSI_RESET && psi_list[selected].value > 0)
{
int val = psi_list[selected].value - g_settings.psi_step;
psi_list[selected].value = (val < 0) ? 0 : val;
paintSlider (selected);
videoDecoder->SetControl(psi_list[selected].control, psi_list[selected].value);
}
break;
case CRCInput::RC_home: // exit -> revert changes
for (i = 0; (i < PSI_RESET) && (psi_list[i].value == psi_list[i].value_old); i++);
if (ShowMsg(name, LOCALE_MESSAGEBOX_ACCEPT, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbCancel) == CMsgBox::mbrCancel)
for (i = 0; i < PSI_RESET; i++)
{
psi_list[i].value = psi_list[i].value_old;
videoDecoder->SetControl(psi_list[selected].control, psi_list[selected].value);
}
/* fall through */
case CRCInput::RC_ok:
if (selected != PSI_RESET)
{
loop = false;
g_settings.psi_contrast = psi_list[PSI_CONTRAST].value;
g_settings.psi_saturation = psi_list[PSI_SATURATION].value;
g_settings.psi_brightness = psi_list[PSI_BRIGHTNESS].value;
g_settings.psi_tint = psi_list[PSI_TINT].value;
break;
}
/* fall through */
case CRCInput::RC_red:
for (i = 0; i < PSI_RESET; i++)
{
psi_list[i].value = 128;
videoDecoder->SetControl(psi_list[i].control, psi_list[i].value);
paintSlider (i);
}
break;
default:
;
}
}
hide ();
return res;
}
void CPSISetup::hide ()
{
frameBuffer->paintBackgroundBoxRel (x, y, dx, dy);
frameBuffer->blit();
}
void CPSISetup::paint ()
{
for (int i = 0; i < PSI_SCALE_COUNT; i++)
paintSlider (i);
}
void CPSISetup::paintSlider (int i)
{
Font *f = g_Font[SNeutrinoSettings::FONT_TYPE_MENU];
fb_pixel_t fg_col[] = { COL_MENUCONTENTINACTIVE_TEXT, COL_MENUCONTENT_TEXT };
if (i < PSI_RESET)
{
psi_list[i].scale->setProgress(psi_list[i].x, psi_list[i].y + sliderOffset, SLIDERWIDTH, SLIDERHEIGHT, psi_list[i].value, 255);
psi_list[i].scale->paint();
f->RenderString (psi_list[i].xLoc, psi_list[i].yLoc, locWidth, g_Locale->getText(psi_list[i].loc), fg_col[psi_list[i].selected]);
}
else
{
int fh = f->getHeight();
f->RenderString (psi_list[i].x + 2 + fh + fh/8, psi_list[i].yLoc, dx - 2 - fh, g_Locale->getText(psi_list[i].loc), COL_MENUCONTENT_TEXT);
frameBuffer->paintIcon (NEUTRINO_ICON_BUTTON_RED, psi_list[i].x + 2, psi_list[i].yLoc - fh + fh/4, 0, (6 * fh)/8);
}
needsBlit = true;
}
bool CPSISetup::changeNotify (const neutrino_locale_t OptionName, void *Data)
{
for (int i = 0; i < PSI_RESET; i++)
if (OptionName == psi_list[i].loc)
{
psi_list[i].value = *((int *) Data);
videoDecoder->SetControl(psi_list[i].control, psi_list[i].value);
return true;
}
return false;
}
static CPSISetup *inst = NULL;
CPSISetup *CPSISetup::getInstance()
{
if (!inst)
inst = new CPSISetup(LOCALE_VIDEOMENU_PSI);
return inst;
}