Switch to swkbd + update gfx

This commit is contained in:
J-D-K
2018-12-23 14:43:55 -05:00
parent fb02227965
commit bd78f186aa
16 changed files with 81 additions and 358 deletions

View File

@@ -38,7 +38,7 @@ INCLUDES := inc
EXEFS_SRC := exefs_src
APP_TITLE := JKSV
APP_AUTHOR := JK
APP_VERSION := 12/19/2018
APP_VERSION := 12/23/2018
ROMFS := romfs
#---------------------------------------------------------------------------------

View File

@@ -40,8 +40,8 @@ bool graphicsInit(int windowWidth, int windowHeight);
//Exits needed services
bool graphicsExit();
//Flush, swap buffers
void gfxHandleBuffs();
void gfxBeginFrame();
void gfxEndFrame();
//Creates color from uint32_t
inline clr clrCreateU32(uint32_t color)

View File

@@ -1,62 +0,0 @@
#ifndef KB_H
#define KB_H
#include <string>
#include <vector>
#include "miscui.h"
namespace ui
{
//The way it should have been. Inheritance drives me insane sometimes, but they're basically the same thing.
class key : button
{
public:
key(const std::string& _txt, const char& _l, unsigned _x, unsigned _y, unsigned _w, unsigned _h);
//Returns char assigned to key
char getLet() { return let; }
//Updates displayed text
void updateText(const std::string& txt);
//toUpper
void toCaps();
//toLower
void toLower();
void draw() { button::draw();}
void update(const touchPosition& p) { button::update(p);}
int getEvent() { return button::getEvent(); }
int getX() { return button::getX(); }
int getY() { return button::getY(); }
int getW() { return w; }
int getH() { return h; }
private:
char let;
};
class keyboard
{
public:
//Builds keyboard
keyboard();
~keyboard();
void draw();
//returns string
std::string getString(const std::string& def);
private:
std::vector<key> keys;
std::string str;
int selKey = 0;
uint8_t clrSh = 0;
bool clrAdd = true;
tex *backTemp = NULL;
};
}
#endif // KB_H

View File

@@ -81,7 +81,6 @@ namespace ui
//General use
void showMessage(const std::string& mess, const std::string& head);
void showError(const std::string& mess, const Result& r);
bool confirm(const std::string& q);
bool confirmTransfer(const std::string& f, const std::string& t);
bool confirmDelete(const std::string& p);

View File

@@ -8,7 +8,6 @@
#include "gfx.h"
//ui headers - split up to keep a bit more organized
#include "kb.h"
#include "menu.h"
#include "miscui.h"
#include "clsui.h"

View File

@@ -14,7 +14,7 @@ namespace util
DATE_FMT_HOYSTE
};
//Returns string with date + time
//Returns string with date S+ time
std::string getDateTime(int fmt);
//Creates Dir 'JKSV/[title]
@@ -36,6 +36,6 @@ namespace util
std::string getInfoString(data::user& u, data::titledata& d);
void debugPrintf(const char *out);
std::string getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[]);
}
#endif // UTIL_H

View File

@@ -206,9 +206,9 @@ namespace fs
i += f.gcount();
prog.update(i);
gfxBeginFrame();
prog.draw(from, "Copying File:");
gfxHandleBuffs();
gfxEndFrame();
}
delete[] buff;
@@ -244,9 +244,9 @@ namespace fs
i += f.gcount();
prog.update(i);
gfxBeginFrame();
prog.draw(from, "Copying File:");
gfxHandleBuffs();
gfxEndFrame();
}
delete[] buff;

View File

@@ -10,6 +10,10 @@
tex *frameBuffer;
clr textClr;
static NWindow *window;
static Framebuffer fb;
static bool framestarted = false;
static inline uint32_t blend(const clr px, const clr fb)
{
if(px.a == 0x00)
@@ -38,18 +42,17 @@ static inline uint32_t smooth(const clr px1, const clr px2)
bool graphicsInit(int windowWidth, int windowHeight)
{
gfxInitResolution((uint32_t)windowWidth, (uint32_t)windowHeight);
gfxInitDefault();
plInitialize();
consoleInit(NULL);
window = nwindowGetDefault();
nwindowSetDimensions(window, windowWidth, windowHeight);
gfxSetMode(GfxMode_LinearDouble);
framebufferCreate(&fb, window, windowWidth, windowHeight, PIXEL_FORMAT_RGBA_8888, 2);
framebufferMakeLinear(&fb);
plInitialize();
//Make a fake tex that points to framebuffer
frameBuffer = malloc(sizeof(tex));
frameBuffer->width = windowWidth;
frameBuffer->height = windowHeight;
frameBuffer->data = (uint32_t *)gfxGetFramebuffer(NULL, NULL);
frameBuffer->size = windowWidth * windowHeight;
return true;
@@ -60,16 +63,28 @@ bool graphicsExit()
free(frameBuffer);
plExit();
gfxExit();
framebufferClose(&fb);
nwindowClose(window);
return true;
}
void gfxHandleBuffs()
void gfxBeginFrame()
{
gfxFlushBuffers();
gfxSwapBuffers();
gfxWaitForVsync();
if(!framestarted)
{
frameBuffer->data = (uint32_t *)framebufferBegin(&fb, NULL);
framestarted = true;
}
}
void gfxEndFrame()
{
if(framestarted)
{
framebufferEnd(&fb);
framestarted = false;
}
}
static void drawGlyph(const FT_Bitmap *bmp, tex *target, int _x, int _y)

View File

@@ -69,10 +69,11 @@ int main(int argc, const char *argv[])
}
else if(down & KEY_PLUS)
break;
gfxBeginFrame();
ui::runApp(down, held, p);
gfxHandleBuffs();
gfxEndFrame();
}
#ifdef __debug__
socketExit();

View File

@@ -11,7 +11,7 @@
#include "util.h"
#include "file.h"
#define VER_STRING "v. 12/19/2018"
#define VER_STRING "v. 12/22/2018"
//background that can be drawn from "/JKSV/back.jpg"
//txtSide and fldSide are to fake alpha blending so the framerate doesn't suffer

View File

@@ -188,8 +188,7 @@ void performCopyMenuOps()
if(saveMenu.getSelected() > 1)
{
int selSave = saveMenu.getSelected() - 2;
ui::keyboard getName;
std::string newName = getName.getString(saveList.getItem(selSave));
std::string newName = util::getStringInput(saveList.getItem(selSave), "Rename", 256, 0, NULL);
if(!newName.empty())
{
std::string b4Path = savePath + saveList.getItem(selSave);
@@ -209,8 +208,7 @@ void performCopyMenuOps()
if(sdMenu.getSelected() > 1)
{
int sdSel = sdMenu.getSelected() - 2;
ui::keyboard getName;
std::string newName = getName.getString(sdList.getItem(sdSel));
std::string newName = util::getStringInput(sdList.getItem(sdSel), "Rename", 256, 0, NULL);
if(!newName.empty())
{
std::string b4Path = sdPath + sdList.getItem(sdSel);
@@ -234,8 +232,7 @@ void performCopyMenuOps()
{
if(data::curData.getType() != FsSaveDataType_SystemSaveData)
{
ui::keyboard getFolder;
std::string newFolder = util::safeString(getFolder.getString(""));
std::string newFolder = util::getStringInput("", "New Folder", 256, 0, NULL);
if(!newFolder.empty())
{
std::string folderPath = savePath + newFolder;
@@ -249,8 +246,7 @@ void performCopyMenuOps()
//sd
case 1:
{
ui::keyboard getFolder;
std::string newFolder = getFolder.getString("");
std::string newFolder = util::getStringInput("", "New Folder", 256, 0, NULL);
if(!newFolder.empty())
{
std::string folderPath = sdPath + newFolder;
@@ -499,6 +495,8 @@ namespace ui
else
mstate = FLD_SEL;
}
else if(down & KEY_L)
data::curData.setType(FsSaveDataType_SaveData);
//draw copy menu if it's supposed to be up
if(advMenuCtrl == 2)

View File

@@ -144,8 +144,7 @@ namespace ui
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE);
else
{
ui::keyboard key;
folder = util::safeString(key.getString(""));
folder = util::getStringInput("", "New Folder", 256, 0, NULL);
}
if(!folder.empty())
{
@@ -340,10 +339,10 @@ namespace ui
ui::showMessage("Something went wrong while dumping your NAND.", "*ERROR*");
break;
}
gfxBeginFrame();
nandProg.update(offset);
nandProg.draw("", "Copying NAND");
gfxHandleBuffs();
gfxEndFrame();
}
delete[] nandBuff;
@@ -395,9 +394,10 @@ namespace ui
break;
}
gfxBeginFrame();
nandProg.update(offset);
nandProg.draw("", "Copying NAND");
gfxHandleBuffs();
gfxEndFrame();
}
delete[] nandBuff;
@@ -432,8 +432,7 @@ namespace ui
case 8:
{
fsdevUnmountDevice("sv");
ui::keyboard getID;
std::string idStr = getID.getString("0100000000000000");
std::string idStr = util::getStringInput("0100000000000000", "Enter Process ID", 18, 0, NULL);
if(!idStr.empty())
{
uint64_t termID = std::strtoull(idStr.c_str(), NULL, 16);
@@ -448,8 +447,7 @@ namespace ui
case 9:
{
fsdevUnmountDevice("sv");
ui::keyboard getID;
std::string idStr = getID.getString("8000000000000000");
std::string idStr = util::getStringInput("8000000000000000", "Enter Sys Save ID", 18, 0, NULL);
uint64_t mountID = std::strtoull(idStr.c_str(), NULL, 16);
if(R_SUCCEEDED(fsMount_SystemSaveData(&sv, mountID)))
{

View File

@@ -56,8 +56,15 @@ namespace ui
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE);
else
{
ui::keyboard key;
folder = util::safeString(key.getString(""));
const std::string dict[] =
{
util::getDateTime(util::DATE_FMT_YMD),
util::getDateTime(util::DATE_FMT_YDM),
util::getDateTime(util::DATE_FMT_HOYSTE),
data::curUser.getUsernameSafe(),
data::curData.getTitleSafe()
};
folder = util::getStringInput("", "Enter a folder name", 64, 5, dict);
}
if(!folder.empty())
{

View File

@@ -1,219 +0,0 @@
#include <switch.h>
#include "gfx.h"
#include "kb.h"
#include "util.h"
static const char qwerty[] =
{
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '_',
'z', 'x', 'c', 'v', 'b', 'n', 'm', ':', '.', '/'
};
namespace ui
{
key::key(const std::string& _txt, const char& _l, unsigned _x, unsigned _y, unsigned _w, unsigned _h) : button(_txt, _x, _y, _w, _h)
{
let = _l;
}
void key::updateText(const std::string& txt)
{
text = txt;
}
void key::toCaps()
{
let = toupper(let);
char tmp[2];
sprintf(tmp, "%c", let);
updateText(tmp);
}
void key::toLower()
{
let = tolower(let);
char tmp[2];
sprintf(tmp, "%c", let);
updateText(tmp);
}
keyboard::keyboard()
{
for(int y = 256, i = 0; i < 40; y += 96)
{
int endRow = i + 10;
for(int x = 160; i < endRow; x += 96, i++)
{
char tmp[2];
sprintf(tmp, "%c", qwerty[i]);
key newKey(tmp, qwerty[i], x, y, 80, 80);
keys.push_back(newKey);
}
}
//spc key
key shift("Shift", ' ', 16, 544, 128, 80);
//Space bar needs to be trimmed back so we don't try to draw off buffer
key space(" ", ' ', 240, 640, 800, 72);
key bckSpc("Back", ' ', 1120, 256, 128, 80);
key enter("Enter", ' ', 1120, 352, 128, 80);
key cancel("Cancel", ' ', 1120, 448, 128, 80);
keys.push_back(space);
keys.push_back(shift);
keys.push_back(bckSpc);
keys.push_back(enter);
keys.push_back(cancel);
}
keyboard::~keyboard()
{
keys.clear();
}
void keyboard::draw()
{
if(clrAdd)
{
clrSh += 4;
if(clrSh > 63)
clrAdd = false;
}
else
{
clrSh--;
if(clrSh == 0)
clrAdd = true;
}
texDraw(backTemp, frameBuffer, 0, 0);
clr rectClr = clrCreateRGBA(0x00, 0x60 + clrSh, 0xBB + clrSh, 0xFF);
//Draw sel rectangle around key for controller
drawRect(frameBuffer, keys[selKey].getX() - 4, keys[selKey].getY() - 4, keys[selKey].getW() + 8, keys[selKey].getH() + 8, rectClr);
for(unsigned i = 0; i < keys.size(); i++)
keys[i].draw();
drawText(str.c_str(), frameBuffer, ui::shared, 16, 104, 32, ui::mnuTxt);
}
std::string keyboard::getString(const std::string& def)
{
str = def;
//Trick to not kill framerate
backTemp = texCreate(1280, 720);
memcpy(backTemp->data, frameBuffer->data, 1280 * 720 * sizeof(uint32_t));
//draw alpha rect over top
clr topRect = ui::rectSh;
clr botRect = ui::clearClr;
topRect.a = 0xDD;
botRect.a = 0xDD;
drawRectAlpha(backTemp, 0, 0, 1280, 240, topRect);
drawRectAlpha(backTemp, 0, 240, 1280, 480, botRect);
while(true)
{
hidScanInput();
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
if(down & KEY_R)
str += util::getDateTime(util::DATE_FMT_YMD);
else if(down & KEY_L)
str += util::getDateTime(util::DATE_FMT_YDM);
else if(down & KEY_ZL)
str += util::getDateTime(util::DATE_FMT_HOYSTE);
touchPosition p;
hidTouchRead(&p, 0);
//Controller input for keyboard
if(down & KEY_RIGHT)
selKey++;
else if(down & KEY_LEFT && selKey > 0)
selKey--;
else if(down & KEY_DOWN)
{
selKey += 10;
if(selKey > 40)
selKey = 40;
}
else if(down & KEY_UP)
{
selKey -= 10;
if(selKey < 0)
selKey = 0;
}
else if(down & KEY_A)
{
if(selKey < 41)
{
str += keys[selKey].getLet();
}
}
else if(down & KEY_X)
{
str += ' ';
}
//Stndrd key
for(unsigned i = 0; i < 41; i++)
{
keys[i].update(p);
if(keys[i].getEvent() == BUTTON_RELEASED)
{
str += keys[i].getLet();
}
}
for(unsigned i = 41; i < 45; i++)
keys[i].update(p);
//shift
if(keys[41].getEvent() == BUTTON_RELEASED || down & KEY_LSTICK)
{
if(keys[10].getLet() == 'q')
{
for(unsigned i = 10; i < 41; i++)
keys[i].toCaps();
}
else
{
for(unsigned i = 10; i < 41; i++)
keys[i].toLower();
}
}
//bckspace
else if(keys[42].getEvent() == BUTTON_RELEASED || down & KEY_Y)
{
if(!str.empty())
str.erase(str.end() - 1, str.end());
}
//enter
else if(keys[43].getEvent() == BUTTON_RELEASED || down & KEY_PLUS)
break;
//cancel
else if(keys[44].getEvent() == BUTTON_RELEASED || down & KEY_B)
{
str.erase(str.begin(), str.end());
break;
}
draw();
gfxHandleBuffs();
}
texDestroy(backTemp);
return str;
}
}

View File

@@ -168,40 +168,14 @@ namespace ui
if(down & KEY_A || down & KEY_B || ok.getEvent() == BUTTON_RELEASED)
break;
gfxBeginFrame();
ui::drawTextbox(256, 128, 768, 464);
drawText(head.c_str(), frameBuffer, ui::shared, headX, 144, 24, txtClr);
drawRect(frameBuffer, 256, 184, 768, 2, clrCreateU32(0xFF6D6D6D));
drawTextWrap(mess.c_str(), frameBuffer, ui::shared, 272, 200, 24, txtClr, 752);
ok.draw();
texDrawInvert(ui::buttonA, frameBuffer, ok.getTx() + 56, ok.getTy() - 4);
gfxHandleBuffs();
}
}
void showError(const std::string& mess, const Result& r)
{
button ok("OK (A)", 256, 496, 768, 96);
char tmp[512];
sprintf(tmp, "%s\n0x%08X", mess.c_str(), (unsigned)r);
while(true)
{
hidScanInput();
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
touchPosition p;
hidTouchRead(&p, 0);
ok.update(p);
if(down & KEY_A || down & KEY_B || ok.getEvent() == BUTTON_RELEASED)
break;
ui::drawTextbox(256, 128, 768, 464);
drawTextWrap(tmp, frameBuffer, shared, 272, 144, 48, txtClr, 752);
ok.draw();
gfxHandleBuffs();
gfxEndFrame();
}
}
@@ -237,6 +211,7 @@ namespace ui
break;
}
gfxBeginFrame();
ui::drawTextbox(256, 128, 768, 464);
drawText("Confirm", frameBuffer, ui::shared, headX, 144, 24, txtClr);
drawRect(frameBuffer, 256, 184, 768, 2, clrCreateU32(0xFF6D6D6D));
@@ -245,8 +220,7 @@ namespace ui
texDrawInvert(ui::buttonA, frameBuffer, yes.getTx() + 64, yes.getTy() - 4);
no.draw();
texDrawInvert(ui::buttonB, frameBuffer, no.getTx() + 56, no.getTy() - 4);
gfxHandleBuffs();
gfxEndFrame();
}
return ret;

View File

@@ -150,10 +150,23 @@ namespace util
return ret;
}
void debugPrintf(const char *out)
std::string getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
{
#ifdef __debug__
printf("%s", out);
#endif
SwkbdConfig swkbd;
swkbdCreate(&swkbd, dictCnt);
swkbdConfigMakePresetDefault(&swkbd);
swkbdConfigSetInitialText(&swkbd, def.c_str());
swkbd.arg.arg.type = SwkbdType_QWERTY;
swkbdConfigSetHeaderText(&swkbd, head.c_str());
swkbdConfigSetOkButtonText(&swkbd, "Done");
swkbd.arg.arg.initialCursorPos = 1;
swkbd.arg.arg.stringLenMax = maxLength;
char out[maxLength];
memset(out, 0, maxLength);
swkbdShow(&swkbd, out, maxLength);
swkbdClose(&swkbd);
return std::string(out);
}
}