Skip to content

Commit

Permalink
text icons, file drop, argument start and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
karwler committed Jun 6, 2018
1 parent 0673fd3 commit be8ea71
Show file tree
Hide file tree
Showing 26 changed files with 469 additions and 310 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ Settings files are being saved in "%AppData%\VertiRead".

## How to use it
The idea is that you have a library directory in which you have your comics saved in form of pictures. The location of this directory can be changed in the settings.
The last button in the book list allows you to navigate through files outside of the library directory.
Left clicking on a book in the book list wil take you to the file explorer, while right clicking on a book will take you to the last viewed page.
The last button in the book list allows you to navigate through files outside of the library directory. When in the book list or browser view, you can drag and drop a folder or file into the window to browse/open it. It's also possible to start the program with a file/directory path as a command line argument to start in the page browser or reader.
The reader has a hidden side panel on the left.

The program supports keyboard and controller bindings. DirectInput and XInput are handled separately. The bindings can be changed in the settings.
Expand Down
Binary file added rsc/data/textures/file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added rsc/data/textures/folder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 69 additions & 46 deletions src/engine/drawSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

// FONT SET

FontSet::FontSet(const string& FILE) {
init(FILE);
}

FontSet::~FontSet() {
for (const pair<int, TTF_Font*>& it : fonts)
TTF_CloseFont(it.second);
Expand Down Expand Up @@ -38,7 +34,11 @@ TTF_Font* FontSet::addSize(int size) {

TTF_Font* FontSet::getFont(int height) {
height = float(height) * heightScale;
return fonts.count(height) ? fonts.at(height) : addSize(height); // load font if it hasn't been loaded yet
try { // load font if it hasn't been loaded yet
return fonts.at(height);
} catch (std::out_of_range e) {
return addSize(height);
}
}

int FontSet::length(const string& text, int height) {
Expand All @@ -51,18 +51,30 @@ int FontSet::length(const string& text, int height) {

// DRAW SYS

DrawSys::DrawSys(SDL_Window* window, int driverIndex) :
colors(Filer::getColors(World::winSys()->sets.getTheme())),
fonts(Filer::findFont(World::winSys()->sets.getFont())),
trans(Filer::getTranslations(World::winSys()->sets.getLang()))
{
DrawSys::DrawSys(SDL_Window* window, int driverIndex) {
// create and set up renderer
renderer = SDL_CreateRenderer(window, driverIndex, Default::rendererFlags);
if (!renderer)
throw "Couldn't create renderer:\n" + string(SDL_GetError());
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

// load default textures with colors and initialize fonts and translations
for (string& it : Filer::listDir(Filer::dirTexs, FTYPE_FILE)) {
string file = Filer::dirTexs + it;
SDL_Texture* tex = IMG_LoadTexture(renderer, file.c_str());
if (tex)
texes.insert(make_pair(delExt(it), tex));
else
cerr << "Couldn't load texture " << file << endl << IMG_GetError << endl;
}
setTheme(World::winSys()->sets.getTheme());
setFont(World::winSys()->sets.getFont());
setLanguage(World::winSys()->sets.getLang());
}

DrawSys::~DrawSys() {
for (const pair<string, SDL_Texture*>& it : texes)
SDL_DestroyTexture(it.second);
SDL_DestroyRenderer(renderer);
}

Expand All @@ -72,8 +84,19 @@ SDL_Rect DrawSys::viewport() const {
return view;
}

vec2i DrawSys::viewSize() const {
SDL_Rect view;
SDL_RenderGetViewport(renderer, &view);
return vec2i(view.w, view.h);
}

void DrawSys::setTheme(const string& name) {
colors = Filer::getColors(World::winSys()->sets.setTheme(name));
SDL_Color clr = colors[static_cast<uint8>(Color::texture)];
for (const pair<string, SDL_Texture*>& it : texes) {
SDL_SetTextureColorMod(it.second, clr.r, clr.g, clr.b);
SDL_SetTextureAlphaMod(it.second, clr.a);
}
}

void DrawSys::setFont(const string& font) {
Expand Down Expand Up @@ -119,37 +142,33 @@ void DrawSys::drawWidgets() {
}

void DrawSys::drawButton(Button* wgt) {
drawRect(overlapRect(wgt->rect(), wgt->parentFrame()), wgt->color());
if (wgt->showBG)
drawRect(overlapRect(wgt->rect(), wgt->frame()), wgt->color());
if (wgt->tex)
drawImage(wgt->tex, wgt->texRect(), wgt->frame());
}

void DrawSys::drawCheckBox(CheckBox* wgt) {
SDL_Rect frame = wgt->parentFrame();
drawRect(overlapRect(wgt->rect(), frame), wgt->color()); // draw background
SDL_Rect frame = wgt->frame();
drawButton(wgt); // draw background
drawRect(overlapRect(wgt->boxRect(), frame), wgt->boxColor()); // draw checkbox
}

void DrawSys::drawSlider(Slider* wgt) {
SDL_Rect frame = wgt->parentFrame();
drawRect(overlapRect(wgt->rect(), frame), wgt->color()); // draw background
SDL_Rect frame = wgt->frame();
drawButton(wgt); // draw background
drawRect(overlapRect(wgt->barRect(), frame), Color::dark); // draw bar
drawRect(overlapRect(wgt->sliderRect(), frame), Color::light); // draw slider
}

void DrawSys::drawPicture(Picture* wgt) {
if (wgt->showBG)
drawRect(overlapRect(wgt->rect(), wgt->parentFrame()), wgt->color());
drawImage(wgt->tex, wgt->getRes(), wgt->texRect(), wgt->parentFrame());
}

void DrawSys::drawLabel(Label* wgt) {
SDL_Rect rect = overlapRect(wgt->rect(), wgt->parentFrame());
drawRect(rect, wgt->color()); // draw background

if (wgt->tex) { // modify frame and draw text if exists
rect.x += Default::textOffset;
rect.w -= Default::textOffset * 2;
drawText(wgt->tex, wgt->textRect(), rect);
}
SDL_Rect rect = overlapRect(wgt->rect(), wgt->frame());
if (wgt->showBG) // draw background
drawRect(rect, wgt->color());
if (wgt->tex) // draw left icon
drawImage(wgt->tex, wgt->texRect(), rect);
if (wgt->textTex) // draw text
drawText(wgt->textTex, wgt->textRect(), wgt->textFrame());
}

void DrawSys::drawScrollArea(ScrollArea* box) {
Expand Down Expand Up @@ -193,40 +212,44 @@ void DrawSys::drawText(SDL_Texture* tex, const SDL_Rect& rect, const SDL_Rect& f
SDL_RenderCopy(renderer, tex, &src, &dst);
}

void DrawSys::drawImage(SDL_Texture* tex, const vec2i& res, const SDL_Rect& rect, const SDL_Rect& frame) {
void DrawSys::drawImage(SDL_Texture* tex, const SDL_Rect& rect, const SDL_Rect& frame) {
// get destination rect and crop
SDL_Rect dst = rect;
SDL_Rect crop = cropRect(dst, frame);

// get cropped source rect
vec2i res;
SDL_QueryTexture(tex, nullptr, nullptr, &res.x, &res.y);
vec2f factor(float(res.x) / float(rect.w), float(res.y) / float(rect.h));
SDL_Rect src = {float(crop.x) * factor.x, float(crop.y) * factor.y, res.x - int(float(crop.w) * factor.x), res.y - int(float(crop.h) * factor.y)};

SDL_RenderCopy(renderer, tex, &src, &dst);
}

SDL_Texture* DrawSys::renderText(const string& text, int height, vec2i& size) {
if (text.empty()) {
size = 0;
SDL_Texture* DrawSys::renderText(const string& text, int height) {
if (text.empty())
return nullptr;
}

SDL_Surface* surf = TTF_RenderUTF8_Blended(fonts.getFont(height), text.c_str(), colors[static_cast<uint8>(Color::text)]);
SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, surf);
size = vec2i(surf->w, surf->h);
SDL_FreeSurface(surf);
return tex;
}

SDL_Texture* DrawSys::loadTexture(const string& file, vec2i& res) {
SDL_Texture* tex = IMG_LoadTexture(renderer, file.c_str());
if (tex) {
SDL_QueryTexture(tex, nullptr, nullptr, &res.x, &res.y);
SDL_Color clr = colors[static_cast<uint8>(Color::texture)];
SDL_SetTextureColorMod(tex, clr.r, clr.g, clr.b);
SDL_SetTextureAlphaMod(tex, clr.a);
} else {
cerr << "Couldn't load texture " << file << endl << IMG_GetError << endl;
res = 0;
vector<pair<string, SDL_Texture*>> DrawSys::loadTextures(string dir) {
dir = appendDsep(dir);
vector<pair<string, SDL_Texture*>> pics;
for (string& it : Filer::listDir(dir, FTYPE_FILE))
if (SDL_Texture* tex = IMG_LoadTexture(renderer, string(dir + it).c_str()))
pics.push_back(make_pair(it, tex));
return pics;
}

SDL_Texture* DrawSys::texture(const string& name) const {
try {
return texes.at(name);
} catch (std::out_of_range e) {
cerr << "Texture " << name << " doesn't exist." << endl;
return nullptr;
}
return tex;
}
14 changes: 7 additions & 7 deletions src/engine/drawSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// loads different font sizes from one file
class FontSet {
public:
FontSet(const string& FILE);
~FontSet();

void init(const string& path);
Expand All @@ -28,35 +27,36 @@ class DrawSys {
DrawSys(SDL_Window* window, int driverIndex);
~DrawSys();

SDL_Rect viewport() const; // not to be comfused with GraphView's viewport
SDL_Rect viewport() const;
vec2i viewSize() const;
void setTheme(const string& name);
int textLength(const string& text, int height) { return fonts.length(text, height); }
void setFont(const string& font);
void clearFonts() { fonts.clear(); }
SDL_Texture* texture(const string& name) const;
string translation(const string& line, bool firstCapital=true) const;
void setLanguage(const string& lang);

void drawWidgets();
void drawButton(Button* wgt);
void drawCheckBox(CheckBox* wgt);
void drawSlider(Slider* wgt);
void drawPicture(Picture* wgt);
void drawLabel(Label* wgt);
void drawScrollArea(ScrollArea* box);
void drawReaderBox(ReaderBox* box);
void drawPopup(Popup* box);

SDL_Texture* renderText(const string& text, int height, vec2i& size);
SDL_Texture* loadTexture(const string& file, vec2i& res);
SDL_Texture* renderText(const string& text, int height);
vector<pair<string, SDL_Texture*>> loadTextures(string dir);

SDL_Renderer* renderer;
private:

vector<SDL_Color> colors; // use Color as index
FontSet fonts;
umap<string, SDL_Texture*> texes; // name, texture data
umap<string, string> trans; // english keyword, translated word

void drawRect(const SDL_Rect& rect, Color color);
void drawText(SDL_Texture* tex, const SDL_Rect& rect, const SDL_Rect& frame);
void drawImage(SDL_Texture* tex, const vec2i& res, const SDL_Rect& rect, const SDL_Rect& frame);
void drawImage(SDL_Texture* tex, const SDL_Rect& rect, const SDL_Rect& frame);
};
47 changes: 37 additions & 10 deletions src/engine/filer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void IniLine::clear() {

// FILER

const string Filer::dirExec = appendDsep(Filer::getDirExec());
const string Filer::dirExec = appendDsep(Filer::getExecDir());
#ifdef _WIN32
const vector<string> Filer::dirFonts = {Filer::dirExec, string(std::getenv("SystemDrive")) + "\\Windows\\Fonts\\"};
const string Filer::dirSets = string(std::getenv("AppData")) + "\\"+Default::titleDefault+"\\";
Expand Down Expand Up @@ -461,6 +461,23 @@ FileType Filer::fileType(const string& path) {
return FTYPE_FILE;
}

bool Filer::isPicture(const string& file) {
if (SDL_Surface* img = IMG_Load(file.c_str())) {
SDL_FreeSurface(img);
return true;
}
return false;
}

bool Filer::isFont(const string& file) {
TTF_Font* tmp = TTF_OpenFont(file.c_str(), Default::fontTestHeight);
if (tmp) {
TTF_CloseFont(tmp);
return true;
}
return false;
}

#ifdef _WIN32
vector<char> Filer::listDrives() {
vector<char> letters;
Expand All @@ -473,28 +490,38 @@ vector<char> Filer::listDrives() {
}
#endif

string Filer::getDirExec() {
string Filer::getExecDir() {
string path;
#ifdef _WIN32
wchar buffer[MAX_PATH];
GetModuleFileNameW(0, buffer, MAX_PATH);
path = wtos(buffer);
return GetModuleFileNameW(GetModuleHandleW(nullptr), buffer, MAX_PATH) ? parentPath(wtos(buffer)) : getWorkingDir();
#else
char buffer[PATH_MAX];
if (ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer)-1)) {
buffer[len] = '\0';
return parentPath(buffer);
}
return getWorkingDir();
#endif
}

string Filer::getWorkingDir() {
#ifdef _WIN32
wchar buffer[MAX_PATH];
return GetCurrentDirectoryW(MAX_PATH, buffer) ? wtos(buffer) : "";
#else
char buffer[PATH_MAX];
int len = readlink("/proc/self/exe", buffer, PATH_MAX-1);
buffer[len] = '\0';
path = buffer;
return getcwd(buffer, sizeof(buffer)) ? buffer : "";
#endif
return parentPath(path);
}

string Filer::findFont(const string& font) {
if (isAbsolute(font) && fileType(font) == FTYPE_FILE) // check if font refers to a file
if (isAbsolute(font) && isFont(font)) // check if font refers to a file
return font;

for (const string& dir : dirFonts) // check font directories
for (string& it : listDirRecursively(dir))
if (strcmpCI(hasExt(it) ? delExt(filename(it)) : filename(it), font))
if (strcmpCI(hasExt(it) ? delExt(filename(it)) : filename(it), font) && isFont(it))
return it;
return ""; // nothing found
}
Expand Down
5 changes: 4 additions & 1 deletion src/engine/filer.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,14 @@ class Filer {
static vector<string> listDir(const string& dir, FileType filter=FTYPE_ANY);
static vector<string> listDirRecursively(string dir);
static FileType fileType(const string& path);
static bool isPicture(const string& file);
static bool isFont(const string& file);

#ifdef _WIN32
static vector<char> listDrives(); // get list of driver letters under windows
#endif
static string getDirExec(); // set dirExec
static string getExecDir();
static string getWorkingDir();
static string findFont(const string& font); // on success returns absolute path to font file, otherwise returns empty path

static const string dirExec; // directory in which the executable should currently be
Expand Down
5 changes: 2 additions & 3 deletions src/engine/windowSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,12 @@ void WindowSys::init() {
inputSys.reset(new InputSys);
scene.reset(new Scene);
program.reset(new Program);
program->init();
}

void WindowSys::exec() {
scene->resetLayouts();
uint32 oldTime = SDL_GetTicks();

// the loop :o
uint32 oldTime = SDL_GetTicks();
while (run) {
// get delta seconds
uint32 newTime = SDL_GetTicks();
Expand Down
1 change: 0 additions & 1 deletion src/engine/windowSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class WindowSys {
float getDSec() const { return dSec; }
vec2i resolution() const;
void moveCursor(const vec2i& mov);

void setFullscreen(bool on);
void setRenderer(const string& name);

Expand Down
Loading

0 comments on commit be8ea71

Please sign in to comment.