Added horizontal scrolling of long filenames.

This commit is contained in:
Stephen White 2018-07-15 18:46:49 +10:00
parent f20105f011
commit 3346ef6cf5
12 changed files with 290 additions and 100 deletions

View file

@ -22,6 +22,9 @@
//ROM2 = Jiffy.bin
//ROM3 = d1541II
// The rate (in seconds) a long selection is scrolled
scrollHighlightRate = 0.07
// Enable RAMBoard emulation - 8k drive RAM expansion at 0x8000
//RAMBOard = 1

View file

@ -71,28 +71,16 @@ static const u32 palette[] =
RGBA(0x9F, 0x9F, 0x9F, 0xFF)
};
void FileBrowser::BrowsableListView::Refresh()
void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, bool selected)
{
char buffer1[128] = { 0 };
char buffer2[128] = { 0 };
u32 index;
u32 entryIndex;
u32 x = positionX;
u32 y = positionY;
char buffer2[256] = { 0 };
u32 colour;
RGBA BkColour = RGBA(0, 0, 0, 0xFF); //palette[VIC2_COLOUR_INDEX_BLUE];
u32 columnsMax = columns;
// Ensure the current selection is visible
if (list->currentIndex - offset >= rows)
{
//DEBUG_LOG("CI= %d O = %d R = %d\r\n", list->currentIndex, offset, rows);
offset = list->currentIndex - rows + 1;
if ((int)offset < 0) offset = 0;
}
for (index = 0; index < rows; ++index)
{
entryIndex = offset + index;
if (columnsMax > sizeof(buffer1))
columnsMax = sizeof(buffer1);
if (entryIndex < list->entries.size())
{
@ -101,24 +89,27 @@ void FileBrowser::BrowsableListView::Refresh()
{
if (entry->filImage.fattrib & AM_DIR)
{
snprintf(buffer2, columns + 1, "[%s]", entry->filImage.fname);
snprintf(buffer2, 256, "[%s]", entry->filImage.fname);
}
else
{
if (entry->caddyIndex != -1)
snprintf(buffer2, columns + 1, "%d>%s", entry->caddyIndex, entry->filImage.fname);
snprintf(buffer2, 256, "%d>%s", entry->caddyIndex, entry->filImage.fname);
else
snprintf(buffer2, columns + 1, "%s", entry->filImage.fname);
snprintf(buffer2, 256, "%s", entry->filImage.fname);
}
}
else
{
snprintf(buffer2, columns + 1, "%s", entry->filImage.fname);
snprintf(buffer2, 256, "%s", entry->filImage.fname);
}
memset(buffer1, ' ', columns);
buffer1[127] = 0;
strncpy(buffer1, buffer2, strlen(buffer2));
if (/*showSelected && */list->currentIndex == entryIndex)
int len = strlen(buffer2 + highlightScrollOffset);
strncpy(buffer1, buffer2 + highlightScrollOffset, sizeof(buffer1));
while (len < (int)columnsMax)
buffer1[len++] = ' ';
buffer1[columnsMax] = 0;
if (selected)
{
if (entry->filImage.fattrib & AM_DIR)
{
@ -153,12 +144,98 @@ void FileBrowser::BrowsableListView::Refresh()
memset(buffer1, ' ', 80);
screen->PrintText(false, x, y, buffer1, BkColour, BkColour);
}
}
void FileBrowser::BrowsableListView::Refresh()
{
u32 index;
u32 entryIndex;
u32 x = positionX;
u32 y = positionY;
highlightScrollOffset = 0;
// Ensure the current selection is visible
if (list->currentIndex - offset >= rows)
{
//DEBUG_LOG("CI= %d O = %d R = %d\r\n", list->currentIndex, offset, rows);
offset = list->currentIndex - rows + 1;
if ((int)offset < 0) offset = 0;
}
for (index = 0; index < rows; ++index)
{
entryIndex = offset + index;
RefreshLine(entryIndex, x, y, /*showSelected && */list->currentIndex == entryIndex);
y += 16;
}
screen->SwapBuffers();
}
void FileBrowser::BrowsableListView::RefreshHighlightScroll()
{
char buffer2[256] = { 0 };
FileBrowser::BrowsableList::Entry* entry = list->current;
if (screen->IsMonocrome())
{
if (entry->filImage.fattrib & AM_DIR)
{
snprintf(buffer2, 256, "[%s]", entry->filImage.fname);
}
else
{
if (entry->caddyIndex != -1)
snprintf(buffer2, 256, "%d>%s", entry->caddyIndex, entry->filImage.fname);
else
snprintf(buffer2, 256, "%s", entry->filImage.fname);
}
}
else
{
snprintf(buffer2, 256, "%s", entry->filImage.fname);
}
int len = strlen(buffer2);
if (len > (int)columns)
{
if (highlightScrollOffset == 0)
{
highlightScrollStartCount++;
if (highlightScrollStartCount > 10)
{
highlightScrollStartCount = 0;
highlightScrollOffset = 1;
}
}
else if (len - (int)(highlightScrollOffset + 1) <= (int)(columns - 1))
{
highlightScrollEndCount++;
if (highlightScrollEndCount > 10)
{
highlightScrollOffset = 0;
highlightScrollEndCount = 0;
}
}
else
{
highlightScrollOffset++;
}
int rowIndex = list->currentIndex - offset;
u32 y = positionY;
y += rowIndex * 16;
RefreshLine(list->currentIndex, 0, y, true);
screen->RefreshRows(rowIndex, 1);
}
}
bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
{
InputMappings* inputMappings = InputMappings::Instance();
@ -172,7 +249,7 @@ bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
if (!pageOnly)
{
list->currentIndex++;
list->current = &list->entries[list->currentIndex];
list->SetCurrent();
}
if (list->currentIndex >= (offset + rows) && (list->currentIndex < list->entries.size()))
offset++;
@ -186,7 +263,7 @@ bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
if (!pageOnly)
{
list->currentIndex--;
list->current = &list->entries[list->currentIndex];
list->SetCurrent();
}
if ((offset > 0) && (list->currentIndex < offset))
offset--;
@ -216,7 +293,7 @@ bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
else
list->currentIndex = offset + rowsMinus1; // Move the bottom of the screen
}
list->current = &list->entries[list->currentIndex];
list->SetCurrent();
dirty = true;
}
if ((lcdPgUpDown && inputMappings->BrowsePageUpLCD()) || (!lcdPgUpDown && inputMappings->BrowsePageUp()))
@ -233,7 +310,7 @@ bool FileBrowser::BrowsableListView::CheckBrowseNavigation(bool pageOnly)
{
list->currentIndex = offset; // Move the cursor to the top of the window
}
list->current = &list->entries[list->currentIndex];
list->SetCurrent();
dirty = true;
}
@ -259,6 +336,15 @@ void FileBrowser::BrowsableList::RefreshViews()
}
}
void FileBrowser::BrowsableList::RefreshViewsHighlightScroll()
{
u32 index;
for (index = 0; index < views.size(); ++index)
{
views[index].RefreshHighlightScroll();
}
}
bool FileBrowser::BrowsableList::CheckBrowseNavigation()
{
bool dirty = false;
@ -284,7 +370,7 @@ FileBrowser::BrowsableList::Entry* FileBrowser::BrowsableList::FindEntry(const c
return 0;
}
FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD)
FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate)
: state(State_Folders)
, diskCaddy(diskCaddy)
, selectionsMade(false)
@ -293,6 +379,7 @@ FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bo
, displayPNGIcons(displayPNGIcons)
, screenMain(screenMain)
, screenLCD(screenLCD)
, scrollHighlightRate(scrollHighlightRate)
{
u32 columns = screenMain->ScaleX(80);
u32 rows = (int)(38.0f * screenMain->GetScaleY());
@ -302,21 +389,24 @@ FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bo
if (rows < 1)
rows = 1;
folder.scrollHighlightRate = scrollHighlightRate;
folder.AddView(screenMain, columns, rows, positionX, positionY, false);
positionX = screenMain->ScaleX(1024 - 320);
caddySelections.AddView(screenMain, columns, rows, positionX, positionY, false);
caddySelections.AddView(screenMain, 6, rows, positionX, positionY, false);
columns = 128 / 8;
rows = 4;
if (screenLCD)
{
columns = screenLCD->Width() / 8;
rows = screenLCD->Height() / 16;
positionX = 0;
positionY = 0;
if (screenLCD)
folder.AddView(screenLCD, columns, rows, positionX, positionY, true);
}
}
u32 FileBrowser::Colour(int index)
{
@ -393,10 +483,8 @@ void FileBrowser::RefreshFolderEntries()
std::sort(folder.entries.begin(), folder.entries.end(), greater());
if (folder.entries.size() > 0) folder.current = &folder.entries[0];
else folder.current = 0;
folder.currentIndex = 0;
folder.SetCurrent();
}
else
{
@ -609,7 +697,51 @@ void FileBrowser::PopFolder()
RefeshDisplay();
}
void FileBrowser::UpdateInput()
void FileBrowser::UpdateCurrentHighlight()
{
if (folder.entries.size() > 0)
{
FileBrowser::BrowsableList::Entry* current = folder.current;
if (current && folder.currentHighlightTime > 0)
{
folder.currentHighlightTime -= 0.000001f;
if (folder.currentHighlightTime <= 0)
{
folder.RefreshViewsHighlightScroll();
}
if (folder.currentHighlightTime <= 0)
{
folder.currentHighlightTime = scrollHighlightRate;
}
}
}
if (folder.entries.size() > 0)
{
FileBrowser::BrowsableList::Entry* current = caddySelections.current;
if (current && caddySelections.currentHighlightTime > 0)
{
caddySelections.currentHighlightTime -= 0.000001f;
if (caddySelections.currentHighlightTime <= 0)
{
caddySelections.RefreshViewsHighlightScroll();
}
if (caddySelections.currentHighlightTime <= 0)
{
caddySelections.currentHighlightTime = scrollHighlightRate;
}
}
}
}
void FileBrowser::Update()
{
InputMappings* inputMappings = InputMappings::Instance();
Keyboard* keyboard = Keyboard::Instance();
@ -627,6 +759,8 @@ void FileBrowser::UpdateInput()
//else
// UpdateInputDiskCaddy();
}
UpdateCurrentHighlight();
}
bool FileBrowser::FillCaddyWithSelections()

View file

@ -65,10 +65,16 @@ public:
, positionX(positionX)
, positionY(positionY)
, lcdPgUpDown(lcdPgUpDown)
, highlightScrollOffset(0)
, highlightScrollStartCount(0)
, highlightScrollEndCount(0)
, scrollHighlightRate()
{
}
void Refresh();
void RefreshLine(u32 entryIndex, u32 x, u32 y, bool selected);
void RefreshHighlightScroll();
bool CheckBrowseNavigation(bool pageOnly);
BrowsableList* list;
@ -80,6 +86,10 @@ public:
u32 positionX;
u32 positionY;
bool lcdPgUpDown;
u32 highlightScrollOffset;
u32 highlightScrollStartCount;
u32 highlightScrollEndCount;
float scrollHighlightRate;
};
class BrowsableList
@ -88,6 +98,8 @@ public:
BrowsableList()
: current(0)
, currentIndex(0)
, currentHighlightTime(0)
, scrollHighlightRate(0)
{
}
@ -111,6 +123,23 @@ public:
void ClearSelections();
void SetCurrent()
{
if (entries.size() > 0)
{
Entry* currentEntry = &entries[currentIndex];
if (currentEntry != current)
{
current = currentEntry;
currentHighlightTime = scrollHighlightRate;
}
}
else
{
current = 0;
}
}
struct Entry
{
Entry() : caddyIndex(-1)
@ -124,20 +153,23 @@ public:
Entry* FindEntry(const char* name);
void RefreshViews();
void RefreshViewsHighlightScroll();
bool CheckBrowseNavigation();
std::vector<Entry> entries;
Entry* current;
u32 currentIndex;
float currentHighlightTime;
float scrollHighlightRate;
std::vector<BrowsableListView> views;
};
FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD);
FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate);
void AutoSelectImage(const char* image);
void DisplayRoot();
void UpdateInput();
void Update();
void RefeshDisplay();
void DisplayDiskInfo(DiskImage* diskImage, const char* filenameForIcon);
@ -164,9 +196,10 @@ public:
static u32 Colour(int index);
bool SelectLST(const char* filenameLST);
void SetScrollHighlightRate(float value) { scrollHighlightRate = value; }
private:
void DisplayPNG(FILINFO& filIcon, int x, int y);
void RefreshFolderEntries();
@ -174,6 +207,8 @@ private:
void UpdateInputFolders();
void UpdateInputDiskCaddy();
void UpdateCurrentHighlight();
//void RefeshDisplayForBrowsableList(FileBrowser::BrowsableList* browsableList, int xOffset, bool showSelected = true);
bool FillCaddyWithSelections();
@ -202,6 +237,8 @@ private:
ScreenBase* screenMain;
ScreenBase* screenLCD;
float scrollHighlightRate;
char PNG[FILEBROWSER_MAX_PNG_SIZE];
};
#endif

View file

@ -143,15 +143,19 @@ void SSD1306::RefreshScreen()
}
}
void SSD1306::RefreshRows(u8 start, u8 amountOfRows)
void SSD1306::RefreshRows(u32 start, u32 amountOfRows)
{
MoveCursorCharacter(start, 0);
start *= 128;
int i;
start <<= 1;
amountOfRows <<= 1;
MoveCursorCharacter(start, 0);
start *= 128;
int end = start + amountOfRows * 128;
for (i = start * 128; i < end; i++)
for (i = start; i < end; i++)
{
SendData(frame[i]);
}

View file

@ -90,7 +90,7 @@ public:
void ClearScreen();
void RefreshScreen();
void RefreshRows(u8 start, u8 amountOfRows);
void RefreshRows(u32 start, u32 amountOfRows);
void SetDisplayWindow(u8 x1, u8 y1, u8 x2, u8 y2);
void PlotPixel(int x, int y, int c);
void PlotImage(const unsigned char * source);

View file

@ -24,8 +24,6 @@
#include "Petscii.h"
#include "stb_image_config.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
extern "C"
{
#include "rpi-mailbox-interface.h"

View file

@ -30,6 +30,8 @@ typedef u32 RGBA;
#define RGBA(r, g, b, a) ( ((u32)((u8)(r))) | ((u32)((u8)(g)) << 8) | ((u32)((u8)(b)) << 16) | ((u32)((u8)(a)) << 24) )
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
class ScreenBase
{
@ -66,9 +68,11 @@ public:
virtual u32 ScaleX(u32 x) { return x; }
virtual u32 ScaleY(u32 y) { return y; }
virtual u32 GetFontWidth() { return 8; }
virtual u32 GetFontHeight() = 0;
virtual void SwapBuffers() = 0;
virtual void RefreshRows(u32 start, u32 amountOfRows) {}
bool IsMonocrome() const { return bpp == 1; }

View file

@ -124,7 +124,8 @@ void ScreenLCD::SwapBuffers()
ssd1306->RefreshScreen();
}
void ScreenLCD::RefreshRows(u8 start, u8 amountOfRows)
void ScreenLCD::RefreshRows(u32 start, u32 amountOfRows)
{
if (ssd1306)
ssd1306->RefreshRows(start, amountOfRows);
}

View file

@ -57,7 +57,7 @@ public:
void SwapBuffers();
void RefreshScreen();
void RefreshRows(u8 start, u8 amountOfRows);
void RefreshRows(u32 start, u32 amountOfRows);
private:
SSD1306* ssd1306 = 0;

View file

@ -336,7 +336,6 @@ void InitialiseHardware()
RPI_GpioVirtInit();
RPI_TouchInit();
#endif
RPI_AuxMiniUartInit(115200, 8);
screen.Open(screenWidth, screenHeight, 16);
@ -568,7 +567,7 @@ void UpdateScreen()
{
screenLCD->PrintText(false, 0, 0, tempBuffer, RGBA(0xff, 0xff, 0xff, 0xff), RGBA(0xff, 0xff, 0xff, 0xff));
// screenLCD->SetContrast(255.0/79.0*track);
screenLCD->RefreshRows(0, 2);
screenLCD->RefreshRows(0, 1);
}
}
@ -673,7 +672,7 @@ void emulator()
roms.lastManualSelectedROMIndex = 0;
diskCaddy.SetScreen(&screen, screenLCD);
fileBrowser = new FileBrowser(&diskCaddy, &roms, deviceID, options.DisplayPNGIcons(), &screen, screenLCD);
fileBrowser = new FileBrowser(&diskCaddy, &roms, deviceID, options.DisplayPNGIcons(), &screen, screenLCD, options.ScrollHighlightRate());
fileBrowser->DisplayRoot();
pi1541.Initialise();
@ -725,7 +724,7 @@ void emulator()
break;
case IEC_Commands::NONE:
{
fileBrowser->UpdateInput();
fileBrowser->Update();
// Check selections made via FileBrowser
if (fileBrowser->SelectionsMade())
@ -792,6 +791,7 @@ void emulator()
default:
break;
}
usDelay(1);
}
}
else
@ -800,10 +800,11 @@ void emulator()
{
if (keyboard->CheckChanged())
{
fileBrowser->UpdateInput();
fileBrowser->Update();
if (fileBrowser->SelectionsMade())
emulating = BeginEmulating(fileBrowser, fileBrowser->LastSelectionName());
}
usDelay(1);
}
}
}
@ -1225,6 +1226,8 @@ extern "C"
m_EMMC.Initialize();
f_mount(&fileSystem, "", 1);
RPI_AuxMiniUartInit(115200, 8);
LoadOptions();
InitialiseHardware();

View file

@ -145,6 +145,7 @@ Options::Options(void)
, i2cLcdFlip(0)
, i2cLcdOnContrast(127)
, i2cLcdModel(0)
, scrollHighlightRate(0.125f)
, keyboardBrowseLCDScreen(0)
{
autoMountImageName[0] = 0;
@ -171,9 +172,9 @@ Options::Options(void)
#define ELSE_CHECK_FLOAT_OPTION(Name) \
else if (strcasecmp(pOption, #Name) == 0) \
{ \
unsigned nValue = 0; \
if ((nValue = GetFloat(pValue)) != INVALID_VALUE) \
Name = nValue; \
float value = 0; \
if ((value = GetFloat(pValue)) != INVALID_VALUE) \
Name = value; \
}
void Options::Process(char* buffer)
@ -219,6 +220,7 @@ void Options::Process(char* buffer)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdOnContrast)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimContrast)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimTime)
ELSE_CHECK_FLOAT_OPTION(scrollHighlightRate)
ELSE_CHECK_DECIMAL_OPTION(keyboardBrowseLCDScreen)
else if ((strcasecmp(pOption, "StarFileName") == 0))
{

View file

@ -79,6 +79,8 @@ public:
inline unsigned int I2CLcdModel() const { return i2cLcdModel; }
inline const char* GetLcdLogoName() const { return LcdLogoName; }
inline float ScrollHighlightRate() const { return scrollHighlightRate; }
// Page up and down will jump a different amount based on the maximum number rows displayed.
// Perhaps we should use some keyboard modifier to the the other screen?
inline unsigned int KeyboardBrowseLCDScreen() const { return keyboardBrowseLCDScreen; }
@ -118,6 +120,8 @@ private:
unsigned int i2cLcdDimTime;
unsigned int i2cLcdModel;
float scrollHighlightRate;
unsigned int keyboardBrowseLCDScreen;
char starFileName[256];