build: Merge submodules into repo

This commit is contained in:
robshape 2023-04-15 10:36:01 +02:00
parent 540a30f719
commit 4c64279f90
422 changed files with 106715 additions and 8 deletions

View file

@ -0,0 +1,353 @@
#include <iostream>
#include <sstream>
#include "commander.h"
#include "resourceManager.h"
#include "sdlutils.h"
#include "def.h"
#include "dialog.h"
#include "fileutils.h"
#include "viewer.h"
#include "keyboard.h"
#define X_LEFT 1
#define X_RIGHT 162
CCommander::CCommander(const std::string &p_pathL, const std::string &p_pathR):
CWindow::CWindow(),
m_panelLeft(p_pathL, X_LEFT),
m_panelRight(p_pathR, X_RIGHT),
m_panelSource(NULL),
m_panelTarget(NULL),
m_background(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_BG))
{
m_panelSource = &m_panelLeft;
m_panelTarget = &m_panelRight;
}
CCommander::~CCommander(void)
{
}
void CCommander::render(const bool p_focus) const
{
INHIBIT(std::cout << "CCommander::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;)
// Draw background image
SDL_utils::applySurface(0, 0, m_background, Globals::g_screen);
// Draw panels
m_panelLeft.render(p_focus && (m_panelSource == &m_panelLeft));
m_panelRight.render(p_focus && (m_panelSource == &m_panelRight));
}
const bool CCommander::keyPress(const SDL_Event &p_event)
{
CWindow::keyPress(p_event);
bool l_ret(false);
switch (p_event.key.keysym.sym)
{
case MYKEY_SYSTEM:
case MYKEY_MENU:
if (openSystemMenu())
m_panelSource->refresh();
l_ret = true;
break;
case MYKEY_UP:
l_ret = m_panelSource->moveCursorUp(1);
break;
case MYKEY_DOWN:
l_ret = m_panelSource->moveCursorDown(1);
break;
case MYKEY_PAGEUP:
l_ret = m_panelSource->moveCursorUp(NB_VISIBLE_LINES - 1);
break;
case MYKEY_PAGEDOWN:
l_ret = m_panelSource->moveCursorDown(NB_VISIBLE_LINES - 1);
break;
case MYKEY_LEFT:
if (m_panelSource == &m_panelRight)
{
m_panelSource = &m_panelLeft;
m_panelTarget = &m_panelRight;
l_ret = true;
}
break;
case MYKEY_RIGHT:
if (m_panelSource == &m_panelLeft)
{
m_panelSource = &m_panelRight;
m_panelTarget = &m_panelLeft;
l_ret = true;
}
break;
case MYKEY_OPEN:
if (m_panelSource->isDirectoryHighlighted())
{
// It's a dir => open it
l_ret = m_panelSource->open();
}
else
{
// It's a file => open execute menu
openExecuteMenu();
l_ret = true;
}
break;
case MYKEY_PARENT:
l_ret = m_panelSource->goToParentDir();
break;
case MYKEY_OPERATION:
// If there's no file in the select list, add current file
if (m_panelSource->getSelectList().empty() && m_panelSource->getHighlightedItem() != "..")
m_panelSource->addToSelectList(false);
if (!m_panelSource->getSelectList().empty())
{
if (openCopyMenu())
{
// Refresh file lists
m_panelSource->refresh();
m_panelTarget->refresh();
}
else
{
if (m_panelSource->getSelectList().size() == 1 && (*m_panelSource->getSelectList().begin()) == m_panelSource->getHighlightedIndex())
m_panelSource->selectNone();
}
l_ret = true;
}
break;
case MYKEY_SELECT:
l_ret = m_panelSource->addToSelectList(true);
break;
case MYKEY_TRANSFER:
if (m_panelSource->isDirectoryHighlighted() && m_panelSource->getHighlightedItem() != "..")
l_ret = m_panelTarget->open(m_panelSource->getHighlightedItemFull());
else
l_ret = m_panelTarget->open(m_panelSource->getCurrentPath());
break;
default:
break;
}
return l_ret;
}
const bool CCommander::keyHold(void)
{
bool l_ret(false);
switch(m_lastPressed)
{
case MYKEY_UP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_UP]))
l_ret = m_panelSource->moveCursorUp(1);
break;
case MYKEY_DOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN]))
l_ret = m_panelSource->moveCursorDown(1);
break;
case MYKEY_PAGEUP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEUP]))
l_ret = m_panelSource->moveCursorUp(NB_VISIBLE_LINES - 1);
break;
case MYKEY_PAGEDOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEDOWN]))
l_ret = m_panelSource->moveCursorDown(NB_VISIBLE_LINES - 1);
break;
case MYKEY_SELECT:
if (tick(SDL_GetKeyState(NULL)[MYKEY_SELECT]))
l_ret = m_panelSource->addToSelectList(true);
break;
default:
break;
}
return l_ret;
}
const bool CCommander::openCopyMenu(void) const
{
bool l_ret(false);
int l_dialogRetVal(0);
bool l_rename(false);
// List of selected files
std::vector<std::string> l_list;
m_panelSource->getSelectList(l_list);
// The rename option appears only if one item is selected
l_rename = (l_list.size() == 1);
{
bool l_loop(false);
std::ostringstream l_stream;
l_stream << l_list.size() << " selected:";
// File operation dialog
CDialog l_dialog(l_stream.str(), 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT);
l_dialog.addOption(m_panelSource == &m_panelLeft ? "Copy >" : "< Copy");
l_dialog.addOption(m_panelSource == &m_panelLeft ? "Move >" : "< Move");
if (l_rename)
l_dialog.addOption("Rename");
l_dialog.addOption("Delete");
l_dialog.addOption("Disk used");
l_dialog.init();
do
{
l_loop = false;
l_dialogRetVal = l_dialog.execute();
if (l_dialogRetVal == 3 + l_rename)
{
CDialog l_dialog2("", l_dialog.getX() + l_dialog.getImage()->w - DIALOG_BORDER, l_dialog.getY() + DIALOG_BORDER + (l_dialog.getHighlightedIndex() + 1) * LINE_HEIGHT);
l_dialog2.addOption("Yes");
l_dialog2.addOption("No");
l_dialog2.init();
if (l_dialog2.execute() != 1)
l_loop = true;
}
}
while (l_loop);
}
// Perform operation
switch (l_dialogRetVal)
{
case 1:
// Copy
File_utils::copyFile(l_list, m_panelTarget->getCurrentPath());
l_ret = true;
break;
case 2:
// Move
File_utils::moveFile(l_list, m_panelTarget->getCurrentPath());
l_ret = true;
break;
case 3:
if (l_rename)
{
// Rename
CKeyboard l_keyboard(m_panelSource->getHighlightedItem());
if (l_keyboard.execute() == 1 && !l_keyboard.getInputText().empty() && l_keyboard.getInputText() != m_panelSource->getHighlightedItem())
{
File_utils::renameFile(m_panelSource->getHighlightedItemFull(), m_panelSource->getCurrentPath() + (m_panelSource->getCurrentPath() == "/" ? "" : "/") + l_keyboard.getInputText());
l_ret = true;
}
}
else
{
// Delete
File_utils::removeFile(l_list);
l_ret = true;
}
break;
case 4:
if (l_rename)
{
// Delete
File_utils::removeFile(l_list);
l_ret = true;
}
else
// Disk used
File_utils::diskUsed(l_list);
break;
case 5:
if (l_rename)
// Disk used
File_utils::diskUsed(l_list);
break;
default:
break;
}
return l_ret;
}
const bool CCommander::openSystemMenu(void)
{
bool l_ret(false);
int l_dialogRetVal(0);
// Selection dialog
{
CDialog l_dialog("System:", 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT);
l_dialog.addOption("Select all");
l_dialog.addOption("Select none");
l_dialog.addOption("New directory");
l_dialog.addOption("Disk info");
l_dialog.addOption("Quit");
l_dialog.init();
l_dialogRetVal = l_dialog.execute();
}
switch (l_dialogRetVal)
{
case 1:
// Select all
m_panelSource->selectAll();
break;
case 2:
// Select none
m_panelSource->selectNone();
break;
case 3:
// New dir
{
CKeyboard l_keyboard("");
if (l_keyboard.execute() == 1 && !l_keyboard.getInputText().empty())
{
File_utils::makeDirectory(m_panelSource->getCurrentPath() + (m_panelSource->getCurrentPath() == "/" ? "" : "/") + l_keyboard.getInputText());
l_ret = true;
}
}
break;
case 4:
// Disk info
File_utils::diskInfo();
break;
case 5:
// Quit
m_retVal = -1;
break;
default:
break;
}
return l_ret;
}
void CCommander::openExecuteMenu(void) const
{
int l_dialogRetVal(0);
// Dialog
{
CDialog l_dialog(m_panelSource->getHighlightedItem() + ":", 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT);
l_dialog.addOption("View");
l_dialog.addOption("Execute");
l_dialog.init();
l_dialogRetVal = l_dialog.execute();
}
// Perform operation
switch (l_dialogRetVal)
{
case 1:
// View
{
// Check size
const std::string l_file(m_panelSource->getHighlightedItemFull());
INHIBIT(std::cout << "File size: " << File_utils::getFileSize(l_file) << std::endl;)
if (File_utils::getFileSize(l_file) > VIEWER_SIZE_MAX)
{
// File is too big to be viewed!
CDialog l_dialog("Error:", 0, 0);
l_dialog.addLabel("File is too big!");
l_dialog.addOption("OK");
l_dialog.init();
l_dialog.execute();
}
else
{
CViewer l_viewer(m_panelSource->getHighlightedItemFull());
l_viewer.execute();
}
}
break;
case 2:
// Execute
File_utils::executeFile(m_panelSource->getHighlightedItemFull());
break;
default:
break;
}
}
const bool CCommander::isFullScreen(void) const
{
return true;
}

View file

@ -0,0 +1,54 @@
#ifndef _COMMANDER_H_
#define _COMMANDER_H_
#include <SDL/SDL.h>
#include "panel.h"
#include "window.h"
class CCommander : public CWindow
{
public:
// Constructor
CCommander(const std::string &p_pathL, const std::string &p_pathR);
// Destructor
virtual ~CCommander(void);
private:
// Forbidden
CCommander(void);
CCommander(const CCommander &p_source);
const CCommander &operator =(const CCommander &p_source);
// Key press management
virtual const bool keyPress(const SDL_Event &p_event);
// Key hold management
virtual const bool keyHold(void);
// Draw
virtual void render(const bool p_focus) const;
// Is window full screen?
virtual const bool isFullScreen(void) const;
// Open the file operation menus
const bool openCopyMenu(void) const;
void openExecuteMenu(void) const;
// Open the selection menu
const bool openSystemMenu(void);
// The two panels
CPanel m_panelLeft;
CPanel m_panelRight;
CPanel* m_panelSource;
CPanel* m_panelTarget;
// Pointers to resources
SDL_Surface *m_background;
};
#endif

View file

@ -0,0 +1,124 @@
#ifndef _DEF_H_
#define _DEF_H_
//~ #define INHIBIT(X) X
#define INHIBIT(X) /* X */
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define SCREEN_BPP 16
#define SURFACE_FLAGS SDL_SWSURFACE
#define MS_PER_FRAME 33
// Panel
#define LINE_HEIGHT 15
#define NB_VISIBLE_LINES 14
#define Y_LIST 17
#define Y_HEADER 3
#if defined(PLATFORM_TRIMUI)
#define Y_OFFSET 2 // added for larger Commander-11.ttf
#else
#define Y_OFFSET 0
#endif
#define Y_FOOTER 228
#define H_FOOTER 13
// Dialogs
#define DIALOG_BORDER 2
#define DIALOG_MARGIN 8
// Colors
#define COLOR_KEY 255,0,255
#define COLOR_TEXT_NORMAL 70,27,10
#define COLOR_TEXT_TITLE 233,229,227
#define COLOR_TEXT_DIR 75,70,164
#define COLOR_TEXT_SELECTED 255,0,0
#define COLOR_CURSOR_1 232,152,80
#define COLOR_CURSOR_2 232,201,173
#define COLOR_BG_1 255,255,255
#define COLOR_BG_2 232,228,224
#define COLOR_BORDER 102,85,74
#define DINGOO_X SDLK_LSHIFT
#define DINGOO_Y SDLK_LALT
#if defined(PLATFORM_TRIMUI)
#define MYKEY_UP SDLK_UP // Up
#define MYKEY_RIGHT SDLK_RIGHT // Right
#define MYKEY_DOWN SDLK_DOWN // Down
#define MYKEY_LEFT SDLK_LEFT // Left
#define MYKEY_SYSTEM SDLK_LALT // Y
#define MYKEY_PAGEUP SDLK_TAB // L
#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R
#define MYKEY_OPEN SDLK_SPACE // A
#define MYKEY_PARENT SDLK_LCTRL // B
#define MYKEY_OPERATION SDLK_LSHIFT // X
#define MYKEY_SELECT SDLK_RCTRL // SELECT
#define MYKEY_TRANSFER SDLK_RETURN // START
#define MYKEY_MENU SDLK_ESCAPE // MENU
#define PATH_DEFAULT "/"
#define FILE_SYSTEM "/dev/mmcblk0p1"
#elif defined(PLATFORM_RG35XX)
#define MYKEY_UP SDLK_KATAKANA
#define MYKEY_RIGHT SDLK_KATAKANAHIRAGANA
#define MYKEY_DOWN SDLK_HIRAGANA
#define MYKEY_LEFT SDLK_HENKAN
#define MYKEY_SYSTEM SDLK_RCTRL // Y
#define MYKEY_PAGEUP SDLK_RALT // L
#define MYKEY_PAGEDOWN SDLK_BREAK // R
#define MYKEY_OPEN SDLK_MUHENKAN // A
#define MYKEY_PARENT SDLK_KP_JPCOMMA // B
#define MYKEY_OPERATION SDLK_KP_ENTER // X
#define MYKEY_SELECT SDLK_PRINT // SELECT
#define MYKEY_TRANSFER SDLK_KP_DIVIDE // START
#define MYKEY_MENU SDLK_PAGEUP // MENU
#define PATH_DEFAULT "/"
#define FILE_SYSTEM "/dev/mmcblk0p1"
#elif defined(PLATFORM_MIYOOMINI)
#define MYKEY_UP SDLK_UP // Up
#define MYKEY_RIGHT SDLK_RIGHT // Right
#define MYKEY_DOWN SDLK_DOWN // Down
#define MYKEY_LEFT SDLK_LEFT // Left
#define MYKEY_SYSTEM SDLK_LALT // Y
#define MYKEY_PAGEUP SDLK_e // L
#define MYKEY_PAGEDOWN SDLK_t // R
#define MYKEY_OPEN SDLK_SPACE // A
#define MYKEY_PARENT SDLK_LCTRL // B
#define MYKEY_OPERATION SDLK_LSHIFT // X
#define MYKEY_SELECT SDLK_RCTRL // SELECT
#define MYKEY_TRANSFER SDLK_RETURN // START
#define MYKEY_MENU SDLK_ESCAPE // MENU
#define PATH_DEFAULT "/"
#define FILE_SYSTEM "/dev/mmcblk0p1"
#elif defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA)
#define MYKEY_UP SDLK_UP // Up
#define MYKEY_RIGHT SDLK_RIGHT // Right
#define MYKEY_DOWN SDLK_DOWN // Down
#define MYKEY_LEFT SDLK_LEFT // Left
#define MYKEY_SYSTEM SDLK_LSHIFT // X
#define MYKEY_PAGEUP SDLK_TAB // L
#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R
#define MYKEY_OPEN SDLK_LCTRL // A
#define MYKEY_PARENT SDLK_LALT // B
#define MYKEY_OPERATION SDLK_SPACE // Y
#define MYKEY_SELECT SDLK_ESCAPE // SELECT
#define MYKEY_TRANSFER SDLK_RETURN // START
#define MYKEY_MENU SDLK_HOME // POWER
#define PATH_DEFAULT "/"
#define FILE_SYSTEM "/dev/mmcblk0p1"
#elif defined(PLATFORM_RETROFW)
#define MYKEY_UP SDLK_UP // Up
#define MYKEY_RIGHT SDLK_RIGHT // Right
#define MYKEY_DOWN SDLK_DOWN // Down
#define MYKEY_LEFT SDLK_LEFT // Left
#define MYKEY_SYSTEM SDLK_LSHIFT // X
#define MYKEY_PAGEUP SDLK_TAB // L
#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R
#define MYKEY_OPEN SDLK_LCTRL // A
#define MYKEY_PARENT SDLK_LALT // B
#define MYKEY_OPERATION SDLK_SPACE // Y
#define MYKEY_SELECT SDLK_ESCAPE // SELECT
#define MYKEY_TRANSFER SDLK_RETURN // START
#define MYKEY_MENU SDLK_END // POWER
#define PATH_DEFAULT "/"
#define FILE_SYSTEM "/dev/mmcblk0p1"
#endif
#endif

View file

@ -0,0 +1,260 @@
#include <iostream>
#include "dialog.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "def.h"
CDialog::CDialog(const std::string &p_title, const Sint16 p_x, const Sint16 p_y):
CWindow(),
m_nbTitle(false),
m_nbLabels(0),
m_nbOptions(0),
m_highlightedLine(0),
m_image(NULL),
m_cursor1(NULL),
m_cursor2(NULL),
m_x(p_x),
m_y(p_y),
m_cursorX(0),
m_cursorY(0),
m_font(CResourceManager::instance().getFont()),
m_font_sm(CResourceManager::instance().getSmallFont())
{
// Title
if (!p_title.empty())
{
m_nbTitle = true;
m_lines.push_back(p_title);
}
// Init clip
m_clip.x = 0;
m_clip.y = 0;
m_clip.w = 0;
m_clip.h = 0;
}
CDialog::~CDialog(void)
{
// Free surfaces
if (m_image != NULL)
{
SDL_FreeSurface(m_image);
m_image = NULL;
}
if (m_cursor1 != NULL)
{
SDL_FreeSurface(m_cursor1);
m_cursor1 = NULL;
}
if (m_cursor2 != NULL)
{
SDL_FreeSurface(m_cursor2);
m_cursor2 = NULL;
}
for (std::vector<SDL_Surface *>::iterator l_it = m_linesImg.begin(); l_it != m_linesImg.end(); ++l_it)
{
if (*l_it != NULL)
{
SDL_FreeSurface(*l_it);
*l_it = NULL;
}
}
}
void CDialog::addLabel(const std::string &p_label)
{
m_lines.push_back(p_label);
++m_nbLabels;
}
void CDialog::addOption(const std::string &p_option)
{
m_lines.push_back(p_option);
++m_nbOptions;
}
void CDialog::init(void)
{
// The width of the window depends on the width of the largest line
int l_width(0);
int l_cursorWidth(0);
SDL_Surface *l_surfaceTmp(NULL);
// Render every line
for (std::vector<std::string>::const_iterator l_it = m_lines.begin(); l_it != m_lines.end(); ++l_it)
{
// Render line
l_surfaceTmp = SDL_utils::renderText(m_font, *l_it, (m_nbTitle && l_it == m_lines.begin()) ? Globals::g_colorTextTitle : Globals::g_colorTextNormal);
if (l_surfaceTmp->w > l_width)
l_width = l_surfaceTmp->w;
m_linesImg.push_back(l_surfaceTmp);
}
// Cursor width
l_cursorWidth = l_width + 2 * DIALOG_MARGIN;
if (l_cursorWidth > SCREEN_WIDTH - 2 * DIALOG_BORDER)
l_cursorWidth = SCREEN_WIDTH - 2 * DIALOG_BORDER;
// Line clip
m_clip.h = m_linesImg.front()->h;
m_clip.w = l_cursorWidth - DIALOG_MARGIN - 1;
// Adjust image width
l_width = l_width + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER;
if (l_width > SCREEN_WIDTH)
l_width = SCREEN_WIDTH;
// Create dialog image
m_image = SDL_utils::createImage(l_width, m_linesImg.size() * LINE_HEIGHT + 2 * DIALOG_BORDER, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
{
SDL_Rect l_rect;
l_rect.x = DIALOG_BORDER;
l_rect.y = DIALOG_BORDER + m_nbTitle * LINE_HEIGHT;
l_rect.w = m_image->w - 2 * DIALOG_BORDER;
l_rect.h = m_image->h - 2 * DIALOG_BORDER - m_nbTitle * LINE_HEIGHT;
SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BG_1));
}
// Create cursor image
m_cursor1 = SDL_utils::createImage(l_cursorWidth, LINE_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
m_cursor2 = SDL_utils::createImage(l_cursorWidth, LINE_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2));
// Adjust dialog coordinates
if (!m_x)
m_x = (SCREEN_WIDTH - m_image->w) >> 1;
if (!m_y)
{
m_y = (SCREEN_HEIGHT - m_image->h) >> 1;
}
else
{
m_y = m_y - (m_image->h >> 1) + (LINE_HEIGHT >> 1);
if (m_y < Y_LIST)
m_y = Y_LIST;
if (m_y + m_image->h > Y_FOOTER + 1)
m_y = Y_FOOTER + 1 - m_image->h;
}
// Cursor coordinates
m_cursorX = m_x + DIALOG_BORDER;
m_cursorY = m_y + DIALOG_BORDER + (m_nbTitle + m_nbLabels) * LINE_HEIGHT;
}
void CDialog::render(const bool p_focus) const
{
INHIBIT(std::cout << "CDialog::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;)
// Draw background
SDL_utils::applySurface(m_x, m_y, m_image, Globals::g_screen);
// Draw cursor
SDL_utils::applySurface(m_cursorX, m_cursorY + m_highlightedLine * LINE_HEIGHT, p_focus ? m_cursor1 : m_cursor2, Globals::g_screen);
// Draw lines text
Sint16 l_y(m_y + 4);
for (std::vector<SDL_Surface *>::const_iterator l_it = m_linesImg.begin(); l_it != m_linesImg.end(); ++l_it)
{
SDL_utils::applySurface(m_cursorX + DIALOG_MARGIN, (m_nbTitle && l_it == m_linesImg.begin()) ? l_y - 1 - Y_OFFSET : l_y - Y_OFFSET, *l_it, Globals::g_screen, &m_clip);
l_y += LINE_HEIGHT;
}
}
const bool CDialog::keyPress(const SDL_Event &p_event)
{
CWindow::keyPress(p_event);
bool l_ret(false);
switch (p_event.key.keysym.sym)
{
case MYKEY_PARENT:
m_retVal = -1;
l_ret = true;
break;
case MYKEY_UP:
l_ret = moveCursorUp(true);
break;
case MYKEY_DOWN:
l_ret = moveCursorDown(true);
break;
case MYKEY_PAGEUP:
if (m_highlightedLine)
{
m_highlightedLine = 0;
l_ret = true;
}
break;
case MYKEY_PAGEDOWN:
if (m_highlightedLine + 1 < m_nbOptions)
{
m_highlightedLine = m_nbOptions - 1;
l_ret = true;
}
break;
case MYKEY_OPEN:
m_retVal = m_highlightedLine + 1;
l_ret = true;
break;
default:
break;
}
return l_ret;
}
const bool CDialog::moveCursorUp(const bool p_loop)
{
bool l_ret(false);
if (m_highlightedLine)
{
--m_highlightedLine;
l_ret = true;
}
else if (p_loop && m_highlightedLine + 1 < m_nbOptions)
{
m_highlightedLine = m_nbOptions - 1;
l_ret = true;
}
return l_ret;
}
const bool CDialog::moveCursorDown(const bool p_loop)
{
bool l_ret(false);
if (m_highlightedLine + 1 < m_nbOptions)
{
++m_highlightedLine;
l_ret = true;
}
else if (p_loop && m_highlightedLine)
{
m_highlightedLine = 0;
l_ret = true;
}
return l_ret;
}
const bool CDialog::keyHold(void)
{
bool l_ret(false);
switch(m_lastPressed)
{
case MYKEY_UP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_UP]))
l_ret = moveCursorUp(false);
break;
case MYKEY_DOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN]))
l_ret = moveCursorDown(false);
break;
default:
break;
}
return l_ret;
}
const Sint16 &CDialog::getX(void) const
{
return m_x;
}
const Sint16 &CDialog::getY(void) const
{
return m_y;
}
const SDL_Surface * const CDialog::getImage(void) const
{
return m_image;
}
const unsigned int &CDialog::getHighlightedIndex(void) const
{
return m_highlightedLine;
}

View file

@ -0,0 +1,89 @@
#ifndef _DIALOG_H_
#define _DIALOG_H_
#include <string>
#include <vector>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "window.h"
class CDialog : public CWindow
{
public:
// Constructor
// Coordinates = 0 => centered
CDialog(const std::string &p_title, const Sint16 p_x, const Sint16 p_y);
// Destructor
virtual ~CDialog(void);
// Add a label
void addLabel(const std::string &p_label);
// Add a menu option
void addOption(const std::string &p_option);
// Init. Call after all options are added.
void init(void);
// Accessors
const Sint16 &getX(void) const;
const Sint16 &getY(void) const;
const SDL_Surface * const getImage(void) const;
const unsigned int &getHighlightedIndex(void) const;
private:
// Forbidden
CDialog(void);
CDialog(const CDialog &p_source);
const CDialog &operator =(const CDialog &p_source);
// Key press management
virtual const bool keyPress(const SDL_Event &p_event);
// Key hold management
virtual const bool keyHold(void);
// Draw
virtual void render(const bool p_focus) const;
// Move cursor
const bool moveCursorUp(const bool p_loop);
const bool moveCursorDown(const bool p_loop);
// Number of titles (0 or 1), labels, and options
bool m_nbTitle;
unsigned char m_nbLabels;
unsigned char m_nbOptions;
// List of lines
std::vector<std::string> m_lines;
std::vector<SDL_Surface *> m_linesImg;
// The highlighted item
unsigned int m_highlightedLine;
// The image representing the dialog
SDL_Surface *m_image;
// The cursor
SDL_Surface *m_cursor1;
SDL_Surface *m_cursor2;
// Coordinates
Sint16 m_x;
Sint16 m_y;
Sint16 m_cursorX;
Sint16 m_cursorY;
// Line clip
mutable SDL_Rect m_clip;
// Pointers to resources
TTF_Font *m_font;
TTF_Font *m_font_sm;
};
#endif

View file

@ -0,0 +1,115 @@
#include <iostream>
#include <dirent.h>
#include <sys/stat.h>
#include <algorithm>
#include <string.h>
#include "fileLister.h"
bool compareNoCase(const T_FILE& p_s1, const T_FILE& p_s2)
{
return strcasecmp(p_s1.m_name.c_str(), p_s2.m_name.c_str()) <= 0;
}
CFileLister::CFileLister(void)
{
}
CFileLister::~CFileLister(void)
{
}
const bool CFileLister::list(const std::string &p_path)
{
// Open dir
DIR *l_dir = opendir(p_path.c_str());
if (l_dir == NULL)
{
std::cerr << "CFileLister::list: Error opening dir " << p_path << std::endl;
return false;
}
// Clean up
m_listFiles.clear();
m_listDirs.clear();
// Read dir
std::string l_file("");
std::string l_fileFull("");
struct stat l_stat;
struct dirent *l_dirent = readdir(l_dir);
while (l_dirent != NULL)
{
l_file = l_dirent->d_name;
// Filter the '.' and '..' dirs
if (l_file != "." && l_file != "..")
{
// Stat the file
l_fileFull = p_path + "/" + l_file;
if (stat(l_fileFull.c_str(), &l_stat) == -1)
{
std::cerr << "CFileLister::list: Error stat " << l_fileFull << std::endl;
}
else
{
// Check type
if (S_ISDIR(l_stat.st_mode))
// It's a directory
m_listDirs.push_back(T_FILE(l_file, l_stat.st_size));
else
// It's a file
m_listFiles.push_back(T_FILE(l_file, l_stat.st_size));
}
}
// Next
l_dirent = readdir(l_dir);
}
// Close dir
closedir(l_dir);
// Sort lists
sort(m_listFiles.begin(), m_listFiles.end(), compareNoCase);
sort(m_listDirs.begin(), m_listDirs.end(), compareNoCase);
// Add "..", always at the first place
m_listDirs.insert(m_listDirs.begin(), T_FILE("..", 0));
return true;
}
const T_FILE &CFileLister::operator[](const unsigned int p_i) const
{
if (p_i < m_listDirs.size())
return m_listDirs[p_i];
else
return m_listFiles[p_i - m_listDirs.size()];
}
const unsigned int CFileLister::getNbDirs(void) const
{
return m_listDirs.size();
}
const unsigned int CFileLister::getNbFiles(void) const
{
return m_listFiles.size();
}
const unsigned int CFileLister::getNbTotal(void) const
{
return m_listDirs.size() + m_listFiles.size();
}
const bool CFileLister::isDirectory(const unsigned int p_i) const
{
return p_i < m_listDirs.size();
}
const unsigned int CFileLister::searchDir(const std::string &p_name) const
{
unsigned int l_ret = 0;
bool l_found = false;
// Search name in dirs
for (std::vector<T_FILE>::const_iterator l_it = m_listDirs.begin(); (!l_found) && (l_it != m_listDirs.end()); ++l_it)
{
if ((*l_it).m_name == p_name)
l_found = true;
else
++l_ret;
}
return l_found ? l_ret : 0;
}

View file

@ -0,0 +1,58 @@
#ifndef _FILE_LISTER_H_
#define _FILE_LISTER_H_
#include <vector>
#include <string>
// Class used to store file info
struct T_FILE
{
T_FILE(void): m_name(""), m_size(0) {}
T_FILE(const std::string &p_name, const unsigned long int &p_size): m_name(p_name), m_size(p_size) {}
T_FILE(const T_FILE &p_source): m_name(p_source.m_name), m_size(p_source.m_size) {}
~T_FILE(void) {}
const T_FILE &operator =(const T_FILE &p_source) { m_name = p_source.m_name; m_size = p_source.m_size; return *this; }
std::string m_name;
unsigned long int m_size;
};
class CFileLister
{
public:
// Constructor
CFileLister(void);
// Destructor
virtual ~CFileLister(void);
// Read the contents of the given path
// Returns false if the path does not exist
const bool list(const std::string &p_path);
// Get an element in the list (dirs and files combined)
const T_FILE &operator[](const unsigned int p_i) const;
// Get the number of dirs/files
const unsigned int getNbDirs(void) const;
const unsigned int getNbFiles(void) const;
const unsigned int getNbTotal(void) const;
// True => directory, false => file
const bool isDirectory(const unsigned int p_i) const;
// Get index of the given dir name, 0 if not found
const unsigned int searchDir(const std::string &p_name) const;
private:
// Forbidden
CFileLister(const CFileLister &p_source);
const CFileLister &operator =(const CFileLister &p_source);
// The list of files/dir
std::vector<T_FILE> m_listDirs;
std::vector<T_FILE> m_listFiles;
};
#endif

View file

@ -0,0 +1,356 @@
#include <sys/stat.h>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <sstream>
#include "fileutils.h"
#include "def.h"
#include "dialog.h"
#include "sdlutils.h"
#define SPECIAL_CHARS "\\`$();|{}&'\"*?<>[]!^~-#\n\r "
void File_utils::copyFile(const std::vector<std::string> &p_src, const std::string &p_dest)
{
std::string l_command("");
std::string l_destFile("");
std::string l_fileName("");
bool l_loop(true);
bool l_confirm(true);
bool l_execute(true);
for (std::vector<std::string>::const_iterator l_it = p_src.begin(); l_loop && (l_it != p_src.end()); ++l_it)
{
l_execute = true;
// Check if destination files already exists
if (l_confirm)
{
l_fileName = getFileName(*l_it);
l_destFile = p_dest + (p_dest.at(p_dest.size() - 1) == '/' ? "" : "/") + l_fileName;
if (fileExists(l_destFile))
{
INHIBIT(std::cout << "File " << l_destFile << " already exists => ask for confirmation" << std::endl;)
CDialog l_dialog("Question:", 0, 0);
l_dialog.addLabel("Overwrite " + l_fileName + "?");
l_dialog.addOption("Yes");
l_dialog.addOption("Yes to all");
l_dialog.addOption("No");
l_dialog.addOption("Cancel");
l_dialog.init();
switch (l_dialog.execute())
{
case 1:
// Yes
break;
case 2:
// Yes to all
l_confirm = false;
break;
case 3:
// No
l_execute = false;
break;
default:
// Cancel
l_execute = false;
l_loop = false;
break;
}
}
}
if (l_execute)
{
// Waiting message
SDL_utils::pleaseWait();
l_command = "\\cp -r " + specialChars(*l_it) + " " + specialChars(p_dest);
INHIBIT(std::cout << "Command: " << l_command << std::endl;)
system(l_command.c_str());
}
}
}
void File_utils::moveFile(const std::vector<std::string> &p_src, const std::string &p_dest)
{
std::string l_command("");
std::string l_destFile("");
std::string l_fileName("");
bool l_loop(true);
bool l_confirm(true);
bool l_execute(true);
for (std::vector<std::string>::const_iterator l_it = p_src.begin(); l_loop && (l_it != p_src.end()); ++l_it)
{
l_execute = true;
// Check if destination files already exists
if (l_confirm)
{
l_fileName = getFileName(*l_it);
l_destFile = p_dest + (p_dest.at(p_dest.size() - 1) == '/' ? "" : "/") + l_fileName;
if (fileExists(l_destFile))
{
INHIBIT(std::cout << "File " << l_destFile << " already exists => ask for confirmation" << std::endl;)
CDialog l_dialog("Question:", 0, 0);
l_dialog.addLabel("Overwrite " + l_fileName + "?");
l_dialog.addOption("Yes");
l_dialog.addOption("Yes to all");
l_dialog.addOption("No");
l_dialog.addOption("Cancel");
l_dialog.init();
switch (l_dialog.execute())
{
case 1:
// Yes
break;
case 2:
// Yes to all
l_confirm = false;
break;
case 3:
// No
l_execute = false;
break;
default:
// Cancel
l_execute = false;
l_loop = false;
break;
}
}
}
if (l_execute)
{
// Waiting message
SDL_utils::pleaseWait();
l_command = "\\mv " + specialChars(*l_it) + " " + specialChars(p_dest);
INHIBIT(std::cout << "Command: " << l_command << std::endl;)
system(l_command.c_str());
}
}
}
void File_utils::renameFile(const std::string &p_file1, const std::string &p_file2)
{
bool l_execute(true);
// Check if destination files already exists
if (fileExists(p_file2))
{
INHIBIT(std::cout << "File " << p_file2 << " already exists => ask for confirmation" << std::endl;)
CDialog l_dialog("Question:", 0, 0);
l_dialog.addLabel("Overwrite " + getFileName(p_file2) + "?");
l_dialog.addOption("Yes");
l_dialog.addOption("No");
l_dialog.init();
if (l_dialog.execute() != 1)
l_execute = false;
}
if (l_execute)
{
std::string l_command = "\\mv " + specialChars(p_file1) + " " + specialChars(p_file2);
INHIBIT(std::cout << "Command: " << l_command << std::endl;)
system(l_command.c_str());
}
}
void File_utils::removeFile(const std::vector<std::string> &p_files)
{
std::string l_command("");
for (std::vector<std::string>::const_iterator l_it = p_files.begin(); l_it != p_files.end(); ++l_it)
{
l_command = "\\rm -rf " + specialChars(*l_it);
INHIBIT(std::cout << "Command: " << l_command << std::endl;)
system(l_command.c_str());
}
}
void File_utils::makeDirectory(const std::string &p_file)
{
std::string l_command = "\\mkdir -p " + specialChars(p_file);
INHIBIT(std::cout << "Command: " << l_command << std::endl;)
system(l_command.c_str());
}
const bool File_utils::fileExists(const std::string &p_path)
{
struct stat l_stat;
return stat(p_path.c_str(), &l_stat) == 0;
}
const std::string File_utils::getFileName(const std::string &p_path)
{
size_t l_pos = p_path.rfind('/');
return p_path.substr(l_pos + 1);
}
const std::string File_utils::getPath(const std::string &p_path)
{
size_t l_pos = p_path.rfind('/');
return p_path.substr(0, l_pos);
}
void File_utils::executeFile(const std::string &p_file)
{
// Command
std::string l_command = "./" + specialChars(getFileName(p_file));
INHIBIT(std::cout << "File_utils::executeFile: " << l_command << " in " << getPath(p_file) << std::endl;)
// CD to the file's location
chdir(getPath(p_file).c_str());
// Quit
SDL_utils::hastalavista();
// Execute file
execlp("/bin/sh", "/bin/sh", "-c", l_command.c_str(), NULL);
// If we're here, there was an error with the execution
std::cerr << "Error executing file " << p_file << std::endl;
// Relaunch DinguxCommander
l_command = "./" + specialChars(getSelfExecutionName());
INHIBIT(std::cout << "File_utils::executeFile: " << l_command << " in " << getSelfExecutionPath() << std::endl;)
chdir(getSelfExecutionPath().c_str());
execlp(l_command.c_str(), l_command.c_str(), NULL);
}
const std::string File_utils::getSelfExecutionPath(void)
{
// Get execution path
std::string l_exePath("");
char l_buff[255];
int l_i = readlink("/proc/self/exe", l_buff, 255);
l_exePath = l_buff;
l_exePath = l_exePath.substr(0, l_i);
l_i = l_exePath.rfind("/");
l_exePath = l_exePath.substr(0, l_i);
return l_exePath;
}
const std::string File_utils::getSelfExecutionName(void)
{
// Get execution path
std::string l_exePath("");
char l_buff[255];
int l_i = readlink("/proc/self/exe", l_buff, 255);
l_exePath = l_buff;
l_exePath = l_exePath.substr(0, l_i);
l_i = l_exePath.rfind("/");
l_exePath = l_exePath.substr(l_i + 1);
return l_exePath;
}
void File_utils::stringReplace(std::string &p_string, const std::string &p_search, const std::string &p_replace)
{
// Replace all occurrences of p_search by p_replace in p_string
size_t l_pos = p_string.find(p_search, 0);
while (l_pos != std::string::npos)
{
p_string.replace(l_pos, p_search.length(), p_replace);
l_pos = p_string.find(p_search, l_pos + p_replace.length());
}
}
const std::string File_utils::specialChars(const std::string &p_string)
{
// Insert a '\' before special characters
std::string l_ret(p_string);
const std::string l_specialChars(SPECIAL_CHARS);
const size_t l_length = l_specialChars.size();
std::string l_char("");
for (unsigned int l_i = 0; l_i < l_length; ++l_i)
{
l_char = l_specialChars.substr(l_i, 1);
stringReplace(l_ret, l_char, "\\" + l_char);
}
return l_ret;
}
const unsigned long int File_utils::getFileSize(const std::string &p_file)
{
unsigned long int l_ret(0);
struct stat l_stat;
if (stat(p_file.c_str(), &l_stat) == -1)
std::cerr << "File_utils::getFileSize: Error stat " << p_file << std::endl;
else
l_ret = l_stat.st_size;
return l_ret;
}
void File_utils::diskInfo(void)
{
std::string l_line("");
// Execute command df -h
{
char l_buffer[256];
FILE *l_pipe = popen("df -h", "r");
if (l_pipe == NULL)
{
std::cerr << "File_utils::diskInfo: Error popen" << std::endl;
return;
}
while (l_line.empty() && fgets(l_buffer, sizeof(l_buffer), l_pipe) != NULL)
if (strstr(l_buffer, FILE_SYSTEM) != NULL)
l_line = l_buffer;
pclose(l_pipe);
}
if (!l_line.empty())
{
// Separate line by spaces
std::istringstream l_iss(l_line);
std::vector<std::string> l_tokens;
copy(std::istream_iterator<std::string>(l_iss), std::istream_iterator<std::string>(), std::back_inserter<std::vector<std::string> >(l_tokens));
// Display dialog
CDialog l_dialog("Disk information:", 0, 0);
l_dialog.addLabel("Size: " + l_tokens[1]);
l_dialog.addLabel("Used: " + l_tokens[2] + " (" + l_tokens[4] + ")");
l_dialog.addLabel("Available: " + l_tokens[3]);
l_dialog.addOption("OK");
l_dialog.init();
l_dialog.execute();
}
else
std::cerr << "File_utils::diskInfo: Unable to find " << FILE_SYSTEM << std::endl;
}
void File_utils::diskUsed(const std::vector<std::string> &p_files)
{
std::string l_line("");
// Waiting message
SDL_utils::pleaseWait();
// Build and execute command
{
std::string l_command("du -csh");
for (std::vector<std::string>::const_iterator l_it = p_files.begin(); l_it != p_files.end(); ++l_it)
l_command = l_command + " \"" + *l_it + "\"";
char l_buffer[256];
FILE *l_pipe = popen(l_command.c_str(), "r");
if (l_pipe == NULL)
{
std::cerr << "File_utils::diskUsed: Error popen" << std::endl;
return;
}
while (fgets(l_buffer, sizeof(l_buffer), l_pipe) != NULL);
l_line = l_buffer;
pclose(l_pipe);
}
// Separate line by spaces
{
std::istringstream l_iss(l_line);
std::vector<std::string> l_tokens;
copy(std::istream_iterator<std::string>(l_iss), std::istream_iterator<std::string>(), std::back_inserter<std::vector<std::string> >(l_tokens));
l_line = l_tokens[0];
}
// Dialog
std::ostringstream l_stream;
CDialog l_dialog("Disk used:", 0, 0);
l_stream << p_files.size() << " items selected";
l_dialog.addLabel(l_stream.str());
l_dialog.addLabel("Disk used: " + l_line);
l_dialog.addOption("OK");
l_dialog.init();
l_dialog.execute();
}
void File_utils::formatSize(std::string &p_size)
{
// Format 123456789 to 123,456,789
int l_i = p_size.size() - 3;
while (l_i > 0)
{
p_size.insert(l_i, ",");
l_i -= 3;
}
}

View file

@ -0,0 +1,50 @@
#ifndef _FILEUTILS_H_
#define _FILEUTILS_H_
#include <string>
#include <vector>
namespace File_utils
{
// File operations
void copyFile(const std::vector<std::string> &p_src, const std::string &p_dest);
void moveFile(const std::vector<std::string> &p_src, const std::string &p_dest);
void removeFile(const std::vector<std::string> &p_files);
void executeFile(const std::string &p_file);
void makeDirectory(const std::string &p_file);
void renameFile(const std::string &p_file1, const std::string &p_file2);
// File utilities
const bool fileExists(const std::string &p_path);
const unsigned long int getFileSize(const std::string &p_file);
void formatSize(std::string &p_size);
const std::string getFileName(const std::string &p_path);
const std::string getPath(const std::string &p_path);
const std::string getSelfExecutionPath(void);
const std::string getSelfExecutionName(void);
void stringReplace(std::string &p_string, const std::string &p_search, const std::string &p_replace);
const std::string specialChars(const std::string &p_string);
// Dialogs
void diskInfo(void);
void diskUsed(const std::vector<std::string> &p_files);
}
#endif

View file

@ -0,0 +1,483 @@
#include <iostream>
#include "keyboard.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "def.h"
#define KB_X 28
#define KB_Y 128
#define FIELD_Y 98
#define FIELD_W 258
CKeyboard::CKeyboard(const std::string &p_inputText):
CWindow(),
m_imageKeyboard(NULL),
m_textField(NULL),
m_inputText(p_inputText),
m_selected(0),
m_footer(NULL),
m_keySet(0),
m_font(CResourceManager::instance().getFont()),
m_font_sm(CResourceManager::instance().getSmallFont())
{
// Key sets
m_keySets[0] = "abcdefghijklmnopqrstuvwxyz0123456789., ";
m_keySets[1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789., ";
m_keySets[2] = "!#$%&'()[]{}+-;=@^_`´~¡¿¢£¤¥¦§«»±×÷©®° ";
m_keySets[3] = "áàäâãåéèëêæœçíìïîóòöôõðøñþúùüûýÿøßµ¹²³ ";
m_keySets[4] = "ÁÀÄÂÃÅÉÈËÊÆŒÇÍÌÏÎÓÒÖÔÕÐØÑÞÚÙÜÛÝŸØßµ¼½¾ ";
// Create keyboard image
{
SDL_Rect l_rect;
// Create keyboard image
m_imageKeyboard = SDL_utils::createImage(265, 84, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2;
l_rect.y = 2;
l_rect.w = 261;
l_rect.h = 80;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_2));
// Keys
for (unsigned int l_y = 0; l_y < 3; ++l_y)
{
for (unsigned int l_x = 0; l_x < 13; ++l_x)
{
l_rect.x = 3 + 20 * l_x;
l_rect.y = 3 + 20 * l_y;
l_rect.w = 19;
l_rect.h = 18;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
++l_rect.x;
++l_rect.y;
l_rect.w -= 2;
l_rect.h -= 2;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
}
}
// Buttons Cancel and OK
l_rect.x = 3;
l_rect.y = 63;
l_rect.w = 129;
l_rect.h = 18;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
l_rect.x = 133;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER));
l_rect.w -= 2;
l_rect.h -= 2;
++l_rect.y;
l_rect.x = 4;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
l_rect.x = 134;
SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
// Create text field image
m_textField = SDL_utils::createImage(265, 19, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x = 2;
l_rect.y = 2;
l_rect.w = 261;
l_rect.h = 15;
SDL_FillRect(m_textField, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1));
}
// Create footer
m_footer = SDL_utils::createImage(SCREEN_WIDTH, H_FOOTER, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
SDL_utils::applyText(SCREEN_WIDTH >> 1, 1, m_footer, m_font_sm, "A-Input B-Cancel START-OK L/R-Change Y-Backspace X-Space", Globals::g_colorTextTitle, SDL_utils::T_TEXT_ALIGN_CENTER);
}
CKeyboard::~CKeyboard(void)
{
// Free surfaces
if (m_imageKeyboard != NULL)
{
SDL_FreeSurface(m_imageKeyboard);
m_imageKeyboard = NULL;
}
if (m_textField != NULL)
{
SDL_FreeSurface(m_textField);
m_textField = NULL;
}
if (m_footer != NULL)
{
SDL_FreeSurface(m_footer);
m_footer = NULL;
}
}
void CKeyboard::render(const bool p_focus) const
{
INHIBIT(std::cout << "CKeyboard::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;)
// Draw input text field
SDL_utils::applySurface(KB_X, FIELD_Y, m_textField, Globals::g_screen);
// Input text
if (!m_inputText.empty())
{
SDL_Surface *l_surfaceTmp = SDL_utils::renderText(m_font, m_inputText, Globals::g_colorTextNormal);
if (l_surfaceTmp->w > FIELD_W)
{
// Text is too big => clip it
SDL_Rect l_rect;
l_rect.x = l_surfaceTmp->w - FIELD_W;
l_rect.y = 0;
l_rect.w = FIELD_W;
l_rect.h = l_surfaceTmp->h;
SDL_utils::applySurface(KB_X + 5, FIELD_Y + 4 - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect);
}
else
SDL_utils::applySurface(KB_X + 5, FIELD_Y + 4 - Y_OFFSET, l_surfaceTmp, Globals::g_screen);
}
// Draw keyboard
SDL_utils::applySurface(KB_X, KB_Y, m_imageKeyboard, Globals::g_screen);
// Cursor
{
SDL_Rect l_rect;
if (m_selected < 39)
{
// A letter is selected
l_rect.w = 17;
l_rect.h = 16;
l_rect.x = KB_X + 4;
if (m_selected >= 26)
{
l_rect.x = KB_X + 4 + (m_selected - 26) * 20;
l_rect.y = KB_Y + 44;
}
else if (m_selected >= 13)
{
l_rect.x = KB_X + 4 + (m_selected - 13) * 20;
l_rect.y = KB_Y + 24;
}
else
{
l_rect.x = KB_X + 4 + m_selected * 20;
l_rect.y = KB_Y + 4;
}
}
else
{
l_rect.w = 127;
l_rect.h = 16;
l_rect.x = KB_X + 4 + (m_selected == 40) * 130;
l_rect.y = KB_Y + 64;
}
SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
}
// Draw keys text
{
unsigned int l_i(0);
unsigned int l_x(0);
unsigned int l_y(0);
std::string l_text("");
for (l_y = 0; l_y < 3; ++l_y)
{
for (l_x = 0; l_x < 13; ++l_x)
{
if (utf8Code(m_keySets[m_keySet].at(l_i)))
{
l_text = m_keySets[m_keySet].substr(l_i, 2);
l_i += 2;
}
else
{
l_text = m_keySets[m_keySet].substr(l_i, 1);
l_i += 1;
}
SDL_utils::applyText(KB_X + 20 * l_x + 13, KB_Y + 7 + 20 * l_y - Y_OFFSET, Globals::g_screen, m_font, l_text, Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER);
}
}
}
// Buttons text
SDL_utils::applyText(KB_X + 67, KB_Y + 67 - Y_OFFSET, Globals::g_screen, m_font, "Cancel", Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER);
SDL_utils::applyText(KB_X + 197, KB_Y + 67 - Y_OFFSET, Globals::g_screen, m_font, "OK", Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER);
// Draw footer
SDL_utils::applySurface(0, 227, m_footer, Globals::g_screen);
}
const bool CKeyboard::keyPress(const SDL_Event &p_event)
{
CWindow::keyPress(p_event);
bool l_ret(false);
switch (p_event.key.keysym.sym)
{
case MYKEY_PARENT:
// B => Cancel
m_retVal = -1;
l_ret = true;
break;
case MYKEY_UP:
l_ret = moveCursorUp(true);
break;
case MYKEY_DOWN:
l_ret = moveCursorDown(true);
break;
case MYKEY_LEFT:
l_ret = moveCursorLeft(true);
break;
case MYKEY_RIGHT:
l_ret = moveCursorRight(true);
break;
case MYKEY_SYSTEM:
// Y => Backspace
l_ret = backspace();
break;
case MYKEY_OPERATION:
// X => Space
l_ret = type(" ");
break;
case MYKEY_OPEN:
// A => Button pressed
if (m_selected == 39)
{
// Button Cancel
m_retVal = -1;
l_ret = true;
}
else if (m_selected == 40)
{
// Button OK
m_retVal = 1;
l_ret = true;
}
else
// A letter button
l_ret = type();
break;
case MYKEY_PAGEDOWN:
// R => Change keys forward
m_keySet = (m_keySet + 1) % NB_KEY_SETS;
l_ret = true;
break;
case MYKEY_PAGEUP:
// L => Change keys backward
m_keySet = m_keySet ? m_keySet - 1 : NB_KEY_SETS - 1;
l_ret = true;
break;
case MYKEY_TRANSFER:
// START => OK
m_retVal = 1;
l_ret = true;
default:
break;
}
return l_ret;
}
const bool CKeyboard::keyHold(void)
{
bool l_ret(false);
switch(m_lastPressed)
{
case MYKEY_UP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_UP]))
l_ret = moveCursorUp(false);
break;
case MYKEY_DOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN]))
l_ret = moveCursorDown(false);
break;
case MYKEY_LEFT:
if (tick(SDL_GetKeyState(NULL)[MYKEY_LEFT]))
l_ret = moveCursorLeft(false);
break;
case MYKEY_RIGHT:
if (tick(SDL_GetKeyState(NULL)[MYKEY_RIGHT]))
l_ret = moveCursorRight(false);
break;
case MYKEY_OPEN:
// A => Add letter
if (tick(SDL_GetKeyState(NULL)[MYKEY_OPEN]))
l_ret = type();
break;
case MYKEY_SYSTEM:
// Y => Backspace
if (tick(SDL_GetKeyState(NULL)[MYKEY_SYSTEM]))
l_ret = backspace();
break;
case MYKEY_OPERATION:
// X => Space
if (tick(SDL_GetKeyState(NULL)[MYKEY_OPERATION]))
l_ret = type(" ");
break;
default:
break;
}
return l_ret;
}
const bool CKeyboard::moveCursorUp(const bool p_loop)
{
bool l_ret(false);
if (m_selected == 39)
{
m_selected = 29;
l_ret = true;
}
else if (m_selected == 40)
{
m_selected = 35;
l_ret = true;
}
else if (m_selected >= 13)
{
m_selected -= 13;
l_ret = true;
}
else if (m_selected >= 6)
{
if (p_loop)
{
m_selected = 40;
l_ret = true;
}
}
else
{
if (p_loop)
{
m_selected = 39;
l_ret = true;
}
}
return l_ret;
}
const bool CKeyboard::moveCursorDown(const bool p_loop)
{
bool l_ret(false);
if (m_selected == 39)
{
if (p_loop)
{
m_selected = 3;
l_ret = true;
}
}
else if (m_selected == 40)
{
if (p_loop)
{
m_selected = 9;
l_ret = true;
}
}
else if (m_selected >= 32)
{
m_selected = 40;
l_ret = true;
}
else if (m_selected >= 26)
{
m_selected = 39;
l_ret = true;
}
else
{
m_selected += 13;
l_ret = true;
}
return l_ret;
}
const bool CKeyboard::moveCursorLeft(const bool p_loop)
{
bool l_ret(false);
switch (m_selected)
{
case 0:
case 13:
case 26:
if (p_loop)
{
m_selected += 12;
l_ret = true;
}
break;
case 39:
if (p_loop)
{
m_selected = 40;
l_ret = true;
}
break;
default:
--m_selected;
l_ret = true;
break;
}
return l_ret;
}
const bool CKeyboard::moveCursorRight(const bool p_loop)
{
bool l_ret(false);
switch (m_selected)
{
case 12:
case 25:
case 38:
if (p_loop)
{
m_selected -= 12;
l_ret = true;
}
break;
case 40:
if (p_loop)
{
m_selected = 39;
l_ret = true;
}
break;
default:
++m_selected;
l_ret = true;
break;
}
return l_ret;
}
const bool CKeyboard::type(const std::string &p_text)
{
if (p_text.empty())
{
// Append selected character to the input text
if (m_selected < 39)
{
// Get real index
unsigned char l_index(0);
for (unsigned char l_c = 0; l_c < m_selected; ++l_c)
l_index += 1 + utf8Code(m_keySets[m_keySet].at(l_index));
// Get size
size_t l_size = 1 + utf8Code(m_keySets[m_keySet].at(l_index));
// Append text
m_inputText += m_keySets[m_keySet].substr(l_index, l_size);
}
else
std::cerr << "CKeyboard::type : unexpected value: " << m_selected << std::endl;
}
else
// Append given text
m_inputText += p_text;
return true;
}
const std::string &CKeyboard::getInputText(void) const
{
return m_inputText;
}
const bool CKeyboard::backspace(void)
{
bool l_ret(false);
if (!m_inputText.empty())
{
if (m_inputText.size() >= 2 && utf8Code(m_inputText.at(m_inputText.size() - 2)))
m_inputText.resize(m_inputText.size() - 2);
else
m_inputText.resize(m_inputText.size() - 1);
l_ret = true;
}
return l_ret;
}
const bool CKeyboard::utf8Code(const unsigned char p_c) const
{
return (p_c >= 194 && p_c <= 198) || p_c == 208 || p_c == 209;
}

View file

@ -0,0 +1,79 @@
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
#include <string>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "window.h"
#define NB_KEY_SETS 5
class CKeyboard : public CWindow
{
public:
// Constructor
CKeyboard(const std::string &p_inputText);
// Destructor
virtual ~CKeyboard(void);
// Get input text
const std::string &getInputText(void) const;
private:
// Forbidden
CKeyboard(void);
CKeyboard(const CKeyboard &p_source);
const CKeyboard &operator =(const CKeyboard &p_source);
// Key press management
virtual const bool keyPress(const SDL_Event &p_event);
// Key hold management
virtual const bool keyHold(void);
// Draw
virtual void render(const bool p_focus) const;
// Move cursor
const bool moveCursorUp(const bool p_loop);
const bool moveCursorDown(const bool p_loop);
const bool moveCursorLeft(const bool p_loop);
const bool moveCursorRight(const bool p_loop);
// Type a letter
const bool type(const std::string &p_text = "");
// Remove last letter
const bool backspace(void);
// UTF8 character or not
const bool utf8Code(const unsigned char p_c) const;
// The image representing the keyboard
SDL_Surface *m_imageKeyboard;
// The image representing the input text field
SDL_Surface *m_textField;
// The input text
std::string m_inputText;
// The cursor index
unsigned char m_selected;
// The footer
SDL_Surface *m_footer;
// Key sets
std::string m_keySets[NB_KEY_SETS];
unsigned char m_keySet;
// Pointers to resources
TTF_Font *m_font;
TTF_Font *m_font_sm;
};
#endif

View file

@ -0,0 +1,89 @@
#include <cstdlib>
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "def.h"
#include "sdlutils.h"
#include "resourceManager.h"
#include "commander.h"
// Globals
SDL_Surface *Globals::g_screen = NULL;
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
SDL_Surface *Globals::g_scaled = NULL;
#endif
const SDL_Color Globals::g_colorTextNormal = {COLOR_TEXT_NORMAL};
const SDL_Color Globals::g_colorTextTitle = {COLOR_TEXT_TITLE};
const SDL_Color Globals::g_colorTextDir = {COLOR_TEXT_DIR};
const SDL_Color Globals::g_colorTextSelected = {COLOR_TEXT_SELECTED};
std::vector<CWindow *> Globals::g_windows;
int main(int argc, char** argv)
{
// Avoid crash due to the absence of mouse
{
char l_s[]="SDL_NOMOUSE=1";
putenv(l_s);
}
#if defined(PLATFORM_RG35XX)
// we launch in an overclocked state on rg35xx
system("echo 504000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed");
#endif
// Init SDL
SDL_Init(SDL_INIT_VIDEO);
// Hide cursor
SDL_ShowCursor(SDL_DISABLE);
SDL_EnableKeyRepeat(300,100);
// Screen
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
Globals::g_scaled = SDL_SetVideoMode(640, 480, SCREEN_BPP, SURFACE_FLAGS);
if (Globals::g_scaled == NULL)
{
std::cerr << "SDL_SetVideoMode failed: " << SDL_GetError() << std::endl;
return 1;
}
Globals::g_screen = SDL_CreateRGBSurface(SURFACE_FLAGS, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0,0,0,0);
if (Globals::g_screen == NULL)
{
std::cerr << "SDL_CreateRGBSurface (screen) failed: " << SDL_GetError() << std::endl;
return 1;
}
#else
Globals::g_screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SURFACE_FLAGS);
if (Globals::g_screen == NULL)
{
std::cerr << "SDL_SetVideoMode failed: " << SDL_GetError() << std::endl;
return 1;
}
#endif
// Init font
if (TTF_Init() == -1)
{
std::cerr << "TTF_Init failed: " << SDL_GetError() << std::endl;
return 1;
}
#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA)
SDL_utils::checkIPU();
SDL_utils::setIPUSharpness("0");
#endif
// Create instances
CResourceManager::instance();
char *home = getenv("HOME");
std::string l_path = home ? home : PATH_DEFAULT;
CCommander l_commander(l_path, l_path);
// Main loop
l_commander.execute();
//Quit
SDL_utils::hastalavista();
return 0;
}

View file

@ -0,0 +1,339 @@
#include <iostream>
#include <sstream>
#include "panel.h"
#include "resourceManager.h"
#include "sdlutils.h"
#include "fileutils.h"
#define PANEL_SIZE 158
#define NAME_SIZE 140
CPanel::CPanel(const std::string &p_path, const Sint16 p_x):
m_currentPath(""),
m_camera(0),
m_x(p_x),
m_highlightedLine(0),
m_iconDir(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_FOLDER)),
m_iconFile(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_FILE)),
m_iconUp(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_UP)),
m_cursor1(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_CURSOR1)),
m_cursor2(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_CURSOR2)),
m_font(CResourceManager::instance().getFont())
{
// List the given path
if (m_fileLister.list(p_path))
{
// Path OK
m_currentPath = p_path;
}
else
{
// The path is wrong => take default
m_fileLister.list(PATH_DEFAULT);
m_currentPath = PATH_DEFAULT;
}
}
CPanel::~CPanel(void)
{
}
void CPanel::render(const bool p_active) const
{
// Draw cursor
SDL_utils::applySurface(m_x - 1, Y_LIST + (m_highlightedLine - m_camera) * LINE_HEIGHT, p_active ? m_cursor1 : m_cursor2, Globals::g_screen);
// Draw panel
const Sint16 l_x = m_x + m_iconDir->w + 2;
const unsigned int l_nbTotal = m_fileLister.getNbTotal();
Sint16 l_y = Y_LIST;
SDL_Surface *l_surfaceTmp = NULL;
const SDL_Color *l_color = NULL;
SDL_Rect l_rect;
// Current dir
l_surfaceTmp = SDL_utils::renderText(m_font, m_currentPath, Globals::g_colorTextTitle);
if (l_surfaceTmp->w > PANEL_SIZE)
{
l_rect.x = l_surfaceTmp->w - PANEL_SIZE;
l_rect.y = 0;
l_rect.w = PANEL_SIZE;
l_rect.h = l_surfaceTmp->h;
SDL_utils::applySurface(m_x, Y_HEADER - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect);
}
else
{
SDL_utils::applySurface(m_x, Y_HEADER - Y_OFFSET, l_surfaceTmp, Globals::g_screen);
}
SDL_FreeSurface(l_surfaceTmp);
// Content
for (unsigned int l_i = m_camera; l_i < m_camera + NB_VISIBLE_LINES && l_i < l_nbTotal; ++l_i)
{
// Icon and color
if (m_fileLister.isDirectory(l_i))
{
// Icon
if (m_fileLister[l_i].m_name == "..")
l_surfaceTmp = m_iconUp;
else
l_surfaceTmp = m_iconDir;
// Color
if (m_selectList.find(l_i) != m_selectList.end())
l_color = &Globals::g_colorTextSelected;
else
l_color = &Globals::g_colorTextDir;
}
else
{
// Icon
l_surfaceTmp = m_iconFile;
// Color
if (m_selectList.find(l_i) != m_selectList.end())
l_color = &Globals::g_colorTextSelected;
else
l_color = &Globals::g_colorTextNormal;
}
SDL_utils::applySurface(m_x, l_y, l_surfaceTmp, Globals::g_screen);
// Text
l_surfaceTmp = SDL_utils::renderText(m_font, m_fileLister[l_i].m_name, *l_color);
if (l_surfaceTmp->w > NAME_SIZE)
{
l_rect.x = 0;
l_rect.y = 0;
l_rect.w = NAME_SIZE;
l_rect.h = l_surfaceTmp->h;
SDL_utils::applySurface(l_x, l_y + 2 - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect);
}
else
{
SDL_utils::applySurface(l_x, l_y + 2 - Y_OFFSET, l_surfaceTmp, Globals::g_screen);
}
SDL_FreeSurface(l_surfaceTmp);
// Next line
l_y += LINE_HEIGHT;
}
// Footer
std::string l_footer("-");
if (!m_fileLister.isDirectory(m_highlightedLine))
{
std::ostringstream l_s;
l_s << m_fileLister[m_highlightedLine].m_size;
l_footer = l_s.str();
File_utils::formatSize(l_footer);
}
SDL_utils::applyText(m_x + 2, Y_FOOTER - Y_OFFSET, Globals::g_screen, m_font, "Size:", Globals::g_colorTextTitle);
SDL_utils::applyText(m_x + PANEL_SIZE - 2, Y_FOOTER - Y_OFFSET, Globals::g_screen, m_font, l_footer, Globals::g_colorTextTitle, SDL_utils::T_TEXT_ALIGN_RIGHT);
}
const bool CPanel::moveCursorUp(unsigned char p_step)
{
bool l_ret(false);
if (m_highlightedLine)
{
// Move cursor
if (m_highlightedLine > p_step)
m_highlightedLine -= p_step;
else
m_highlightedLine = 0;
// Adjust camera
adjustCamera();
// Return true for new render
l_ret = true;
}
return l_ret;
}
const bool CPanel::moveCursorDown(unsigned char p_step)
{
bool l_ret(false);
const unsigned int l_nb = m_fileLister.getNbTotal();
if (m_highlightedLine < l_nb - 1)
{
// Move cursor
if (m_highlightedLine + p_step > l_nb - 1)
m_highlightedLine = l_nb - 1;
else
m_highlightedLine += p_step;
// Adjust camera
adjustCamera();
// Return true for new render
l_ret = true;
}
return l_ret;
}
const bool CPanel::open(const std::string &p_path)
{
bool l_ret(false);
std::string l_newPath("");
std::string l_oldDir("");
if (p_path.empty())
{
// Open highlighted dir
if (m_fileLister[m_highlightedLine].m_name == "..")
{
// Go to parent dir
size_t l_pos = m_currentPath.rfind('/');
// Remove the last dir in the path
l_newPath = m_currentPath.substr(0, l_pos);
if (l_newPath.empty())
// We're at /
l_newPath = "/";
l_oldDir = m_currentPath.substr(l_pos + 1);
}
else
{
l_newPath = m_currentPath + (m_currentPath == "/" ? "" : "/") + m_fileLister[m_highlightedLine].m_name;
}
}
else
{
// Open given dir
if (p_path == m_currentPath)
return false;
l_newPath = p_path;
}
// List the new path
if (m_fileLister.list(l_newPath))
{
// Path OK
m_currentPath = l_newPath;
// If it's a back movement, restore old dir
if (!l_oldDir.empty())
m_highlightedLine = m_fileLister.searchDir(l_oldDir);
else
m_highlightedLine = 0;
// Camera
adjustCamera();
// Clear select list
m_selectList.clear();
// New render
l_ret = true;
}
INHIBIT(std::cout << "open - new current path: " << m_currentPath << std::endl;)
return l_ret;
}
const bool CPanel::goToParentDir(void)
{
bool l_ret(false);
// Select ".." and open it
if (m_currentPath != "/")
{
m_highlightedLine = 0;
l_ret = open();
}
return l_ret;
}
void CPanel::adjustCamera(void)
{
if (m_fileLister.getNbTotal() <= NB_VISIBLE_LINES)
m_camera = 0;
else if (m_highlightedLine < m_camera)
m_camera = m_highlightedLine;
else if (m_highlightedLine > m_camera + NB_VISIBLE_LINES - 1)
m_camera = m_highlightedLine - NB_VISIBLE_LINES + 1;
}
const std::string &CPanel::getHighlightedItem(void) const
{
return m_fileLister[m_highlightedLine].m_name;
}
const std::string CPanel::getHighlightedItemFull(void) const
{
return m_currentPath + (m_currentPath == "/" ? "" : "/") + m_fileLister[m_highlightedLine].m_name;
}
const std::string &CPanel::getCurrentPath(void) const
{
return m_currentPath;
}
const unsigned int &CPanel::getHighlightedIndex(void) const
{
return m_highlightedLine;
}
const unsigned int CPanel::getHighlightedIndexRelative(void) const
{
return m_highlightedLine - m_camera;
}
void CPanel::refresh(void)
{
// List current path
if (m_fileLister.list(m_currentPath))
{
// Adjust selected line
if (m_highlightedLine > m_fileLister.getNbTotal() - 1)
m_highlightedLine = m_fileLister.getNbTotal() - 1;
}
else
{
// Current path doesn't exist anymore => default
m_fileLister.list(PATH_DEFAULT);
m_currentPath = PATH_DEFAULT;
m_highlightedLine = 0;
}
// Camera
adjustCamera();
// Clear select list
m_selectList.clear();
}
const bool CPanel::addToSelectList(const bool p_step)
{
if (m_fileLister[m_highlightedLine].m_name != "..")
{
// Search highlighted element in select list
std::set<unsigned int>::iterator l_it = m_selectList.find(m_highlightedLine);
if (l_it == m_selectList.end())
// Element not present => we add it
m_selectList.insert(m_highlightedLine);
else
// Element present => we remove it from the list
m_selectList.erase(m_highlightedLine);
if (p_step)
moveCursorDown(1);
return true;
}
else
{
return false;
}
}
const std::set<unsigned int> &CPanel::getSelectList(void) const
{
return m_selectList;
}
void CPanel::getSelectList(std::vector<std::string> &p_list) const
{
p_list.clear();
// Insert full path of selected files
for (std::set<unsigned int>::const_iterator l_it = m_selectList.begin(); l_it != m_selectList.end(); ++l_it)
{
if (m_currentPath == "/")
p_list.push_back(m_currentPath + m_fileLister[*l_it].m_name);
else
p_list.push_back(m_currentPath + "/" + m_fileLister[*l_it].m_name);
}
}
void CPanel::selectAll(void)
{
const unsigned int l_nb = m_fileLister.getNbTotal();
for (unsigned int l_i = 1; l_i < l_nb; ++l_i)
m_selectList.insert(l_i);
}
void CPanel::selectNone(void)
{
m_selectList.clear();
}
const bool CPanel::isDirectoryHighlighted(void) const
{
return m_fileLister.isDirectory(m_highlightedLine);
}

View file

@ -0,0 +1,101 @@
#ifndef _PANEL_H_
#define _PANEL_H_
#include <string>
#include <set>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "fileLister.h"
#include "def.h"
class CPanel
{
public:
// Constructor
CPanel(const std::string &p_path, const Sint16 p_x);
// Destructor
virtual ~CPanel(void);
// Draw the panel on the screen
void render(const bool p_active) const;
// Move cursor
const bool moveCursorUp(unsigned char p_step);
const bool moveCursorDown(unsigned char p_step);
// Open selected item
const bool open(const std::string &p_path = "");
// Refresh current directory
void refresh(void);
// Go to parent dir
const bool goToParentDir(void);
// Selected file with just the name
const std::string &getHighlightedItem(void) const;
// Selected file with full path
const std::string getHighlightedItemFull(void) const;
// Current path
const std::string &getCurrentPath(void) const;
// Selected index
const unsigned int &getHighlightedIndex(void) const;
const unsigned int getHighlightedIndexRelative(void) const;
// True => directory, false => file, or dir ".."
const bool isDirectoryHighlighted(void) const;
// Add/remove current file to the select list
const bool addToSelectList(const bool p_step);
// Get select list
const std::set<unsigned int> &getSelectList(void) const;
void getSelectList(std::vector<std::string> &p_list) const;
// Clear select list
void selectAll(void);
void selectNone(void);
private:
// Forbidden
CPanel(void);
CPanel(const CPanel &p_source);
const CPanel &operator =(const CPanel &p_source);
// Adjust camera
void adjustCamera(void);
// File lister
CFileLister m_fileLister;
// Current path
std::string m_currentPath;
// Index of the first displayed line
unsigned int m_camera;
// X coordinate
const Sint16 m_x;
// Highlighted line
unsigned int m_highlightedLine;
// Selection list
std::set<unsigned int> m_selectList;
// Pointers to resources
SDL_Surface *m_iconDir;
SDL_Surface *m_iconFile;
SDL_Surface *m_iconUp;
SDL_Surface *m_cursor1;
SDL_Surface *m_cursor2;
TTF_Font *m_font;
};
#endif

View file

@ -0,0 +1,71 @@
#include <iostream>
#include "resourceManager.h"
#include "def.h"
#include "sdlutils.h"
#include "def.h"
CResourceManager& CResourceManager::instance(void)
{
static CResourceManager l_singleton;
return l_singleton;
}
CResourceManager::CResourceManager(void) :
m_font(NULL)
{
// Load images
m_surfaces[T_SURFACE_BG] = SDL_utils::loadImage(RESDIR "/background.png");
m_surfaces[T_SURFACE_FILE] = SDL_utils::loadImage(RESDIR "/file.png");
m_surfaces[T_SURFACE_FOLDER] = SDL_utils::loadImage(RESDIR "/folder.png");
m_surfaces[T_SURFACE_UP] = SDL_utils::loadImage(RESDIR "/up.png");
m_surfaces[T_SURFACE_CURSOR1] = SDL_utils::createImage(159, 15, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1));
m_surfaces[T_SURFACE_CURSOR2] = SDL_utils::createImage(159, 15, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2));
// Load fonts
#if defined(PLATFORM_TRIMUI)
m_font = SDL_utils::loadFont(RESDIR "/Commander-11.ttf", 11);
#else
m_font = SDL_utils::loadFont(RESDIR "/Fiery_Turk.ttf", 8);
#endif
m_font_sm = SDL_utils::loadFont(RESDIR "/Fiery_Turk.ttf", 8);
}
void CResourceManager::sdlCleanup(void)
{
INHIBIT(std::cout << "CResourceManager::sdlCleanup" << std::endl;)
int l_i(0);
// Free surfaces
for (l_i = 0; l_i < NB_SURFACES; ++l_i)
{
if (m_surfaces[l_i] != NULL)
{
SDL_FreeSurface(m_surfaces[l_i]);
m_surfaces[l_i] = NULL;
}
}
// Free fonts
if (m_font != NULL)
{
TTF_CloseFont(m_font);
m_font = NULL;
}
if (m_font_sm != NULL)
{
TTF_CloseFont(m_font_sm);
m_font_sm = NULL;
}
}
SDL_Surface *CResourceManager::getSurface(const T_SURFACE p_surface) const
{
return m_surfaces[p_surface];
}
TTF_Font *CResourceManager::getFont(void) const
{
return m_font;
}
TTF_Font *CResourceManager::getSmallFont(void) const
{
return m_font_sm;
}

View file

@ -0,0 +1,52 @@
#ifndef _RESOURCEMANAGER_H_
#define _RESOURCEMANAGER_H_
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#define NB_SURFACES 6
class CResourceManager
{
public:
typedef enum
{
T_SURFACE_BG = 0,
T_SURFACE_FILE,
T_SURFACE_FOLDER,
T_SURFACE_UP,
T_SURFACE_CURSOR1,
T_SURFACE_CURSOR2
}
T_SURFACE;
// Method to get the instance
static CResourceManager& instance(void);
// Cleanup all resources
void sdlCleanup(void);
// Get a loaded surface
SDL_Surface *getSurface(const T_SURFACE p_surface) const;
// Get the loaded fonts
TTF_Font *getFont(void) const;
TTF_Font *getSmallFont(void) const;
private:
// Forbidden
CResourceManager(void);
CResourceManager(const CResourceManager &p_source);
const CResourceManager &operator =(const CResourceManager &p_source);
// Images
SDL_Surface *m_surfaces[NB_SURFACES];
// Fonts
TTF_Font *m_font;
TTF_Font *m_font_sm;
};
#endif

View file

@ -0,0 +1,322 @@
#include <iostream>
#include "sdlutils.h"
#include <SDL/SDL_image.h>
#include "def.h"
#include "resourceManager.h"
#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA)
#include <dirent.h>
std::string ipuscaling = "NONE";
// copied from gambatte-dms
void SDL_utils::checkIPU(void) {
FILE *aspect_ratio_file = NULL;
DIR *ipu_dir = NULL;
std::string ipu_OpenDinguxLegacy = ("/sys/devices/platform/jz-lcd.0/keep_aspect_ratio");
std::string ipu_RetroFW10 = ("/proc/jz/ipu_ratio");
std::string ipu_RetroFW20 = ("/proc/jz/ipu");
std::string ipu_OpenDingux = ("/sys/devices/platform/13080000.ipu");
aspect_ratio_file = fopen(ipu_OpenDinguxLegacy.c_str(), "r+");
if (aspect_ratio_file != NULL) {
fclose(aspect_ratio_file);
ipuscaling = ipu_OpenDinguxLegacy;
printf("Detected IPU scaling - OpenDinguxLegacy\n");
return;
}
aspect_ratio_file = fopen(ipu_RetroFW10.c_str(), "r+");
if (aspect_ratio_file != NULL) {
fclose(aspect_ratio_file);
ipuscaling = ipu_RetroFW10;
printf("Detected IPU scaling - RetroFW 1.X\n");
return;
}
aspect_ratio_file = fopen("/proc/jz/gpio", "r+"); //workaround to check if the fw is retrofw2
if (aspect_ratio_file != NULL) {
fclose(aspect_ratio_file);
ipuscaling = ipu_RetroFW20;
printf("Detected IPU scaling - RetroFW 2.X\n");
return;
}
ipu_dir = opendir("/sys/devices/platform/13080000.ipu");
if (ipu_dir != NULL) {
closedir(ipu_dir);
ipuscaling = "NEW_OD_IPU";
printf("Detected IPU scaling - OpenDingux\n");
return;
}
printf("Could not detect IPU scaling\n");
return;
}
void SDL_utils::setIPUSharpness(const char *svalue){
if (ipuscaling == "NONE") return;
else if (ipuscaling == "NEW_OD_IPU") {
if(svalue == "0"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=0");
} else if(svalue == "1"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=1");
} else if(svalue == "2"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=2");
} else if(svalue == "3"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=3");
} else if(svalue == "4"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=4");
} else if(svalue == "5"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=5");
} else if(svalue == "6"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=6");
} else if(svalue == "7"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=7");
} else if(svalue == "8"){
SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=8");
}
return;
}
FILE *sharpness_file = NULL;
sharpness_file = fopen("/sys/devices/platform/jz-lcd.0/sharpness_upscaling", "r+");
if (sharpness_file != NULL) {
fclose(sharpness_file);
sharpness_file = fopen("/sys/devices/platform/jz-lcd.0/sharpness_upscaling", "w");
fwrite(svalue, 1, 1, sharpness_file);
fclose(sharpness_file);
}
}
#endif
// Load an image using SDL_image
SDL_Surface *SDL_utils::loadImage(const std::string &p_filename)
{
INHIBIT(std::cout << "SDL_utils::loadImage(" << p_filename << ")" << std::endl;)
// Load image
SDL_Surface* l_img = IMG_Load(p_filename.c_str());
SDL_Surface* l_img2 = NULL;
if(l_img != NULL)
{
// Optimize the image
l_img2 = SDL_DisplayFormat(l_img);
// Free the first image
SDL_FreeSurface(l_img);
// Set color key
if (l_img2 != NULL)
SDL_SetColorKey(l_img2, SDL_SRCCOLORKEY, SDL_MapRGB(l_img2->format, COLOR_KEY));
}
// Check errors
if (l_img2 == NULL)
std::cerr << "SDL_utils::loadImage: " << SDL_GetError() << std::endl;
return l_img2;
}
void SDL_utils::applySurface(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_source, SDL_Surface* p_destination, SDL_Rect *p_clip)
{
// Rectangle to hold the offsets
SDL_Rect l_offset;
// Set offsets
l_offset.x = p_x;
l_offset.y = p_y;
//Blit the surface
SDL_BlitSurface(p_source, p_clip, p_destination, &l_offset);
}
TTF_Font *SDL_utils::loadFont(const std::string &p_font, const int p_size)
{
INHIBIT(std::cout << "SDL_utils::loadFont(" << p_font << ", " << p_size << ")" << std::endl;)
TTF_Font *l_font = TTF_OpenFont(p_font.c_str(), p_size);
if (l_font == NULL)
std::cerr << "SDL_utils::loadFont: " << SDL_GetError() << std::endl;
return l_font;
}
SDL_Surface *SDL_utils::renderText(TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg)
{
return TTF_RenderUTF8_Solid(p_font, p_text.c_str(), p_fg);
}
void SDL_utils::applyText(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_destination, TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg, const T_TEXT_ALIGN p_align)
{
SDL_Surface *l_text = renderText(p_font, p_text, p_fg);
switch (p_align)
{
case T_TEXT_ALIGN_LEFT:
applySurface(p_x, p_y, l_text, p_destination);
break;
case T_TEXT_ALIGN_RIGHT:
applySurface(p_x - l_text->w, p_y, l_text, p_destination);
break;
case T_TEXT_ALIGN_CENTER:
applySurface(p_x - l_text->w / 2, p_y, l_text, p_destination);
break;
default:
break;
}
SDL_FreeSurface(l_text);
}
SDL_Surface *SDL_utils::createImage(const int p_width, const int p_height, const Uint32 p_color)
{
// Create image in the same format as the screen
SDL_Surface *l_ret = SDL_CreateRGBSurface(SURFACE_FLAGS, p_width, p_height, Globals::g_screen->format->BitsPerPixel, Globals::g_screen->format->Rmask, Globals::g_screen->format->Gmask, Globals::g_screen->format->Bmask, Globals::g_screen->format->Amask);
if (l_ret == NULL)
std::cerr << "SDL_utils::createImage: " << SDL_GetError() << std::endl;
// Fill image with the given color
SDL_FillRect(l_ret, NULL, p_color);
return l_ret;
}
void SDL_utils::renderAll(void)
{
if (Globals::g_windows.empty())
return;
// First window to draw is the last fullscreen
unsigned int l_i = Globals::g_windows.size() - 1;
while (l_i && !Globals::g_windows[l_i]->isFullScreen())
--l_i;
// Draw windows
for (std::vector<CWindow *>::iterator l_it = Globals::g_windows.begin() + l_i; l_it != Globals::g_windows.end(); ++l_it)
(*l_it)->render(l_it + 1 == Globals::g_windows.end());
}
void SDL_utils::hastalavista(void)
{
// Destroy all dialogs except the first one (the commander)
while (Globals::g_windows.size() > 1)
delete Globals::g_windows.back();
// Free resources
CResourceManager::instance().sdlCleanup();
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
SDL_FreeSurface(Globals::g_screen);
#endif
// Quit SDL
TTF_Quit();
SDL_Quit();
}
void SDL_utils::pleaseWait(void)
{
SDL_Surface *l_surfaceTmp = renderText(CResourceManager::instance().getFont(), "Please wait...", Globals::g_colorTextNormal);
SDL_Rect l_rect;
l_rect.x = (SCREEN_WIDTH - (l_surfaceTmp->w + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER)) >> 1;
l_rect.y = (SCREEN_HEIGHT - (l_surfaceTmp->h + 9)) >> 1;
l_rect.w = l_surfaceTmp->w + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER;
l_rect.h = l_surfaceTmp->h + 9;
SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER));
l_rect.x += DIALOG_BORDER;
l_rect.y += DIALOG_BORDER;
l_rect.w -= 2 * DIALOG_BORDER;
l_rect.h -= 2 * DIALOG_BORDER;
SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_BG_1));
applySurface((SCREEN_WIDTH - l_surfaceTmp->w) >> 1, (SCREEN_HEIGHT - l_surfaceTmp->h) >> 1, l_surfaceTmp, Globals::g_screen);
SDL_FreeSurface(l_surfaceTmp);
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
upscale16NEON(Globals::g_screen->pixels, Globals::g_scaled->pixels);
SDL_Flip(Globals::g_scaled);
#else
SDL_Flip(Globals::g_screen);
#endif
}
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
// eggs amazing SW integer scaler
void upscale16NEON(void* src, void* dst) {
asm volatile (
" vmov.u64 d1,#0xFFFFFFFF ;"
" vmvn.u64 d0,#0xFFFFFFFF ;"
" add r2,%0,#(320*240*2) ;"
"1: add r3,%1,#(640*1*2) ;"
" add lr,%1,#(640*2*2) ;"
"2: vldmia %0!,{q8-q11} ;"
" vdup.16 d2,d23[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d23[2] ;"
" vand d3,d3,d1 ;"
" vorr d31,d2,d3 ;"
" vdup.16 d2,d23[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d23[0] ;"
" vand d3,d3,d1 ;"
" vorr d30,d2,d3 ;"
" vdup.16 d2,d22[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d22[2] ;"
" vand d3,d3,d1 ;"
" vorr d29,d2,d3 ;"
" vdup.16 d2,d22[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d22[0] ;"
" vand d3,d3,d1 ;"
" vorr d28,d2,d3 ;"
" vdup.16 d2,d21[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d21[2] ;"
" vand d3,d3,d1 ;"
" vorr d27,d2,d3 ;"
" vdup.16 d2,d21[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d21[0] ;"
" vand d3,d3,d1 ;"
" vorr d26,d2,d3 ;"
" vdup.16 d2,d20[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d20[2] ;"
" vand d3,d3,d1 ;"
" vorr d25,d2,d3 ;"
" vdup.16 d2,d20[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d20[0] ;"
" vand d3,d3,d1 ;"
" vorr d24,d2,d3 ;"
" vdup.16 d2,d19[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d19[2] ;"
" vand d3,d3,d1 ;"
" vorr d23,d2,d3 ;"
" vdup.16 d2,d19[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d19[0] ;"
" vand d3,d3,d1 ;"
" vorr d22,d2,d3 ;"
" vdup.16 d2,d18[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d18[2] ;"
" vand d3,d3,d1 ;"
" vorr d21,d2,d3 ;"
" vdup.16 d2,d18[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d18[0] ;"
" vand d3,d3,d1 ;"
" vorr d20,d2,d3 ;"
" vdup.16 d2,d17[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d17[2] ;"
" vand d3,d3,d1 ;"
" vorr d19,d2,d3 ;"
" vdup.16 d2,d17[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d17[0] ;"
" vand d3,d3,d1 ;"
" vorr d18,d2,d3 ;"
" vdup.16 d2,d16[3] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d16[2] ;"
" vand d3,d3,d1 ;"
" vorr d17,d2,d3 ;"
" vdup.16 d2,d16[1] ;"
" vand d2,d2,d0 ;"
" vdup.16 d3,d16[0] ;"
" vand d3,d3,d1 ;"
" vorr d16,d2,d3 ;"
" vstmia %1!,{q8-q15} ;"
" vstmia r3!,{q8-q15} ;"
" cmp r3,lr ;"
" bne 2b ;"
" cmp %0,r2 ;"
" mov %1,lr ;"
" bne 1b "
:: "r"(src), "r"(dst)
: "r2","r3","lr","q0","q1","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc"
);
}
#endif

View file

@ -0,0 +1,76 @@
#ifndef _SDLUTILS_H_
#define _SDLUTILS_H_
#include <string>
#include <vector>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "window.h"
namespace SDL_utils
{
// Text alignment
typedef enum
{
T_TEXT_ALIGN_LEFT = 0,
T_TEXT_ALIGN_RIGHT,
T_TEXT_ALIGN_CENTER
}
T_TEXT_ALIGN;
#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA)
// identify IPU if available
void checkIPU(void);
void setIPUSharpness(const char *svalue);
#endif
// Load an image using SDL_image
SDL_Surface *loadImage(const std::string &p_filename);
// Load a TTF font
TTF_Font *loadFont(const std::string &p_font, const int p_size);
// Apply a surface on another surface
void applySurface(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_source, SDL_Surface* p_destination, SDL_Rect *p_clip = NULL);
// Render a text
SDL_Surface *renderText(TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg);
// Render a text and apply on a given surface
void applyText(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_destination, TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg, const T_TEXT_ALIGN p_align = T_TEXT_ALIGN_LEFT);
// Create an image filled with the given color
SDL_Surface *createImage(const int p_width, const int p_height, const Uint32 p_color);
// Render all opened windows
void renderAll(void);
// Cleanup and quit
void hastalavista(void);
// Display a waiting window
void pleaseWait(void);
}
// Globals
namespace Globals
{
// Screen
extern SDL_Surface *g_screen;
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
extern SDL_Surface *g_scaled;
#endif
// Colors
extern const SDL_Color g_colorTextNormal;
extern const SDL_Color g_colorTextTitle;
extern const SDL_Color g_colorTextDir;
extern const SDL_Color g_colorTextSelected;
// The list of opened windows
extern std::vector<CWindow *> g_windows;
}
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
void upscale16NEON(void* src, void* dst);
#endif
#endif

View file

@ -0,0 +1,219 @@
#include <iostream>
#include <fstream>
#include "viewer.h"
#include "resourceManager.h"
#include "def.h"
#include "sdlutils.h"
CViewer::CViewer(const std::string &p_fileName):
CWindow(),
m_fileName(p_fileName),
m_firstLine(0),
m_image(NULL),
m_font(CResourceManager::instance().getFont())
{
// Init clip rect
m_clip.x = 0;
m_clip.y = 0;
m_clip.w = SCREEN_WIDTH - 2 * VIEWER_MARGIN;
// Create background image
m_image = SDL_utils::createImage(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_BG_1));
{
SDL_Rect l_rect;
l_rect.x = 0;
l_rect.y = 0;
l_rect.w = SCREEN_WIDTH;
l_rect.h = Y_LIST;
SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BORDER));
}
// Print title
SDL_Surface *l_surfaceTmp = SDL_utils::renderText(m_font, m_fileName, Globals::g_colorTextTitle);
if (l_surfaceTmp->w > m_image->w - 2 * VIEWER_MARGIN)
{
SDL_Rect l_rect;
l_rect.x = l_surfaceTmp->w - (m_image->w - 2 * VIEWER_MARGIN);
l_rect.y = 0;
l_rect.w = m_image->w - 2 * VIEWER_MARGIN;
l_rect.h = l_surfaceTmp->h;
SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image, &l_rect);
}
else
{
SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image);
}
m_clip.h = l_surfaceTmp->h;
SDL_FreeSurface(l_surfaceTmp);
// Read file
std::ifstream l_file(m_fileName.c_str());
if (l_file.is_open())
{
std::string l_line("");
while (std::getline(l_file, l_line))
{
m_lines.push_back(l_line);
}
l_file.close();
}
else
std::cerr << "Error: unable to open file " << m_fileName << std::endl;
INHIBIT(std::cout << "CViewer: " << m_lines.size() << " lines read" << std::endl;)
}
CViewer::~CViewer(void)
{
// Free surfaces
if (m_image != NULL)
{
SDL_FreeSurface(m_image);
m_image = NULL;
}
}
void CViewer::render(const bool p_focus) const
{
INHIBIT(std::cout << "CViewer::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;)
// Draw background
SDL_utils::applySurface(0, 0, m_image, Globals::g_screen);
// Draw lines
SDL_Surface *l_surfaceTmp(NULL);
unsigned int l_i(0);
std::vector<std::string>::const_iterator l_it = m_lines.begin() + m_firstLine;
while (l_it != m_lines.end() && l_i < VIEWER_NB_LINES)
{
if (!l_it->empty())
{
l_surfaceTmp = SDL_utils::renderText(m_font, *l_it, Globals::g_colorTextNormal);
SDL_utils::applySurface(VIEWER_MARGIN, VIEWER_Y_LIST + l_i * VIEWER_LINE_HEIGHT - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &m_clip);
SDL_FreeSurface(l_surfaceTmp);
}
// Next line
++l_it;
++l_i;
}
}
const bool CViewer::keyPress(const SDL_Event &p_event)
{
CWindow::keyPress(p_event);
bool l_ret(false);
switch (p_event.key.keysym.sym)
{
case MYKEY_PARENT:
case MYKEY_MENU:
m_retVal = -1;
l_ret = true;
break;
case MYKEY_UP:
l_ret = moveUp(1);
break;
case MYKEY_DOWN:
l_ret = moveDown(1);
break;
case MYKEY_PAGEUP:
l_ret = moveUp(VIEWER_NB_LINES - 1);
break;
case MYKEY_PAGEDOWN:
l_ret = moveDown(VIEWER_NB_LINES - 1);
break;
case MYKEY_LEFT:
l_ret = moveLeft();
break;
case MYKEY_RIGHT:
moveRight();
l_ret = true;
break;
default:
break;
}
return l_ret;
}
const bool CViewer::keyHold(void)
{
bool l_ret(false);
switch(m_lastPressed)
{
case MYKEY_UP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_UP]))
l_ret = moveUp(1);
break;
case MYKEY_DOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN]))
l_ret = moveDown(1);
break;
case MYKEY_PAGEUP:
if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEUP]))
l_ret = moveUp(VIEWER_NB_LINES - 1);
break;
case MYKEY_PAGEDOWN:
if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEDOWN]))
l_ret = moveDown(VIEWER_NB_LINES - 1);
break;
case MYKEY_LEFT:
if (tick(SDL_GetKeyState(NULL)[MYKEY_LEFT]))
l_ret = moveLeft();
break;
case MYKEY_RIGHT:
if (tick(SDL_GetKeyState(NULL)[MYKEY_RIGHT]))
{
moveRight();
l_ret = true;
}
break;
default:
break;
}
return l_ret;
}
const bool CViewer::isFullScreen(void) const
{
return true;
}
const bool CViewer::moveUp(const unsigned int p_step)
{
bool l_ret(false);
if (m_firstLine)
{
if (m_firstLine > p_step)
m_firstLine -= p_step;
else
m_firstLine = 0;
l_ret = true;
}
return l_ret;
}
const bool CViewer::moveDown(const unsigned int p_step)
{
bool l_ret(false);
if (m_firstLine + VIEWER_NB_LINES + 1 < m_lines.size())
{
if (m_firstLine + VIEWER_NB_LINES + 1 + p_step > m_lines.size())
m_firstLine = m_lines.size() - VIEWER_NB_LINES - 1;
else
m_firstLine += p_step;
l_ret = true;
}
return l_ret;
}
const bool CViewer::moveLeft(void)
{
bool l_ret(false);
if (m_clip.x > 0)
{
if (m_clip.x > VIEWER_X_STEP)
m_clip.x -= VIEWER_X_STEP;
else
m_clip.x = 0;
l_ret = true;
}
return l_ret;
}
void CViewer::moveRight(void)
{
m_clip.x += VIEWER_X_STEP;
}

View file

@ -0,0 +1,69 @@
#ifndef _VIEWER_H_
#define _VIEWER_H_
#include <string>
#include <vector>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "window.h"
#define VIEWER_LINE_HEIGHT 13
#define VIEWER_NB_LINES 17
#define VIEWER_Y_LIST 18
#define VIEWER_MARGIN 1
#define VIEWER_X_STEP 32
#define VIEWER_SIZE_MAX 16777216 // = 16 MB
class CViewer : public CWindow
{
public:
// Constructor
CViewer(const std::string &p_fileName);
// Destructor
virtual ~CViewer(void);
private:
// Forbidden
CViewer(void);
CViewer(const CViewer &p_source);
const CViewer &operator =(const CViewer &p_source);
// Key press management
virtual const bool keyPress(const SDL_Event &p_event);
// Key hold management
virtual const bool keyHold(void);
// Draw
virtual void render(const bool p_focus) const;
// Is window full screen?
virtual const bool isFullScreen(void) const;
// Scroll
const bool moveUp(const unsigned int p_step);
const bool moveDown(const unsigned int p_step);
const bool moveLeft(void);
void moveRight(void);
// The viewed file name
std::string m_fileName;
// Coordinates
unsigned int m_firstLine;
mutable SDL_Rect m_clip;
// Background image
SDL_Surface *m_image;
// List of read lines
std::vector<std::string> m_lines;
// Pointers to resources
TTF_Font *m_font;
};
#endif

View file

@ -0,0 +1,138 @@
#include <iostream>
#include "window.h"
#include "def.h"
#include "sdlutils.h"
#define KEYHOLD_TIMER_FIRST 6
#define KEYHOLD_TIMER 2
CWindow::CWindow(void):
m_timer(0),
#if defined(PLATFORM_RG35XX)
m_lastPressed(0),
#else
m_lastPressed(SDLK_0),
#endif
m_retVal(0)
{
// Add window to the lists for render
Globals::g_windows.push_back(this);
}
CWindow::~CWindow(void)
{
// Remove last window
Globals::g_windows.pop_back();
}
const int CWindow::execute(void)
{
m_retVal = 0;
Uint32 l_time(0);
SDL_Event l_event;
bool l_loop(true);
bool l_render(true);
// Main loop
while (l_loop)
{
l_time = SDL_GetTicks();
// Handle key press
while (SDL_PollEvent(&l_event))
{
if (l_event.type == SDL_KEYDOWN)
{
l_render = this->keyPress(l_event);
if (m_retVal)
l_loop = false;
}
else if (l_event.type == SDL_QUIT)
{
// Re-insert event so we exit from nested menus
SDL_PushEvent(&l_event);
l_loop = false;
break;
}
}
// Handle key hold
if (l_loop)
l_render = this->keyHold() || l_render;
// Render if necessary
if (l_render && l_loop)
{
SDL_utils::renderAll();
#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX)
upscale16NEON(Globals::g_screen->pixels, Globals::g_scaled->pixels);
SDL_Flip(Globals::g_scaled);
#else
SDL_Flip(Globals::g_screen);
#endif
l_render = false;
INHIBIT(std::cout << "Render time: " << SDL_GetTicks() - l_time << "ms"<< std::endl;)
}
// Cap the framerate
l_time = MS_PER_FRAME - (SDL_GetTicks() - l_time);
if (l_time <= MS_PER_FRAME) SDL_Delay(l_time);
}
return m_retVal;
}
const bool CWindow::keyPress(const SDL_Event &p_event)
{
// Reset timer if running
if (m_timer)
m_timer = 0;
#if defined(PLATFORM_RG35XX)
m_lastPressed = p_event.key.keysym.scancode;
#else
m_lastPressed = p_event.key.keysym.sym;
#endif
return false;
}
const bool CWindow::keyHold(void)
{
// Default behavior
return false;
}
const bool CWindow::tick(const Uint8 p_held)
{
bool l_ret(false);
if (p_held)
{
if (m_timer)
{
--m_timer;
if (!m_timer)
{
// Trigger!
l_ret = true;
// Timer continues
m_timer = KEYHOLD_TIMER;
}
}
else
{
// Start timer
m_timer = KEYHOLD_TIMER_FIRST;
}
}
else
{
// Stop timer if running
if (m_timer)
m_timer = 0;
}
return l_ret;
}
const int CWindow::getReturnValue(void) const
{
return m_retVal;
}
const bool CWindow::isFullScreen(void) const
{
// Default behavior
return false;
}

View file

@ -0,0 +1,58 @@
#ifndef _WINDOW_H_
#define _WINDOW_H_
#include <SDL/SDL.h>
class CWindow
{
public:
// Destructor
virtual ~CWindow(void);
// Execute main loop of the window
const int execute(void);
// Return value
const int getReturnValue(void) const;
// Draw window
virtual void render(const bool p_focus) const = 0;
// Is window full screen?
virtual const bool isFullScreen(void) const;
protected:
// Constructor
CWindow(void);
// Key press management
virtual const bool keyPress(const SDL_Event &p_event);
// Key hold management
virtual const bool keyHold(void);
// Timer tick
const bool tick(const Uint8 p_held);
// Timer for key hold
unsigned int m_timer;
#if defined(PLATFORM_RG35XX)
uint8_t m_lastPressed;
#else
SDLKey m_lastPressed;
#endif
// Return value
int m_retVal;
private:
// Forbidden
CWindow(const CWindow &p_source);
const CWindow &operator =(const CWindow &p_source);
};
#endif