Some fixes to the FileSelector

* Enter pad should behave like the regular Enter key
* Added navigation with Ctrl (or Cmd) + arrow keys
This commit is contained in:
David Capello 2014-09-09 23:42:47 -03:00
parent 886ff676f6
commit 43dbeb02b8
3 changed files with 62 additions and 28 deletions

View File

@ -175,24 +175,29 @@ bool FileList::onProcessMessage(Message* msg)
int bottom = m_list.size(); int bottom = m_list.size();
switch (scancode) { switch (scancode) {
case kKeyUp: case kKeyUp:
if (select >= 0) if (select >= 0)
select--; select--;
else else
select = 0; select = 0;
break; break;
case kKeyDown: case kKeyDown:
if (select >= 0) if (select >= 0)
select++; select++;
else else
select = 0; select = 0;
break; break;
case kKeyHome: case kKeyHome:
select = 0; select = 0;
break; break;
case kKeyEnd: case kKeyEnd:
select = bottom-1; select = bottom-1;
break; break;
case kKeyPageUp: case kKeyPageUp:
case kKeyPageDown: { case kKeyPageDown: {
int sgn = (scancode == kKeyPageUp) ? -1: 1; int sgn = (scancode == kKeyPageUp) ? -1: 1;
@ -202,6 +207,7 @@ bool FileList::onProcessMessage(Message* msg)
select += sgn * vp.h / (getTextHeight()+4*jguiscale()); select += sgn * vp.h / (getTextHeight()+4*jguiscale());
break; break;
} }
case kKeyLeft: case kKeyLeft:
case kKeyRight: case kKeyRight:
if (select >= 0) { if (select >= 0) {
@ -212,14 +218,16 @@ bool FileList::onProcessMessage(Message* msg)
view->setViewScroll(scroll); view->setViewScroll(scroll);
} }
break; break;
case kKeyEnter: case kKeyEnter:
case kKeyEnterPad:
if (m_selected) { if (m_selected) {
if (m_selected->isBrowsable()) { if (m_selected->isBrowsable()) {
setCurrentFolder(m_selected); setCurrentFolder(m_selected);
return true; return true;
} }
if (m_selected->isFolder()) { if (m_selected->isFolder()) {
// Do nothing (is a folder but not browseable. // Do nothing (is a folder but not browseable).
return true; return true;
} }
else { else {
@ -230,15 +238,17 @@ bool FileList::onProcessMessage(Message* msg)
} }
else else
return Widget::onProcessMessage(msg); return Widget::onProcessMessage(msg);
case kKeyBackspace: case kKeyBackspace:
goUp(); goUp();
return true; return true;
default: default:
if (unicodeChar == ' ' || if (unicodeChar == ' ' ||
(utolower(unicodeChar) >= 'a' && (utolower(unicodeChar) >= 'a' &&
utolower(unicodeChar) <= 'z') || utolower(unicodeChar) <= 'z') ||
(utolower(unicodeChar) >= '0' && (unicodeChar >= '0' &&
utolower(unicodeChar) <= '9')) { unicodeChar <= '9')) {
if (ui::clock() - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS) if (ui::clock() - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS)
m_isearch.clear(); m_isearch.clear();

View File

@ -115,12 +115,6 @@ protected:
virtual bool onProcessMessage(Message* msg) override { virtual bool onProcessMessage(Message* msg) override {
if (msg->type() == kKeyUpMessage && if (msg->type() == kKeyUpMessage &&
static_cast<KeyMessage*>(msg)->unicodeChar() >= 32) { static_cast<KeyMessage*>(msg)->unicodeChar() >= 32) {
// Check if all keys are released
for (int c=0; c<KEY_MAX; ++c) {
if (key[c])
return false;
}
// String to be autocompleted // String to be autocompleted
std::string left_part = getText(); std::string left_part = getText();
if (left_part.empty()) if (left_part.empty())
@ -128,15 +122,12 @@ protected:
const FileItemList& children = m_fileList->getFileList(); const FileItemList& children = m_fileList->getFileList();
for (FileItemList::const_iterator for (IFileItem* child : children) {
it=children.begin(); it!=children.end(); ++it) {
IFileItem* child = *it;
std::string child_name = child->getDisplayName(); std::string child_name = child->getDisplayName();
std::string::iterator it1, it2; std::string::iterator it1, it2;
for (it1 = child_name.begin(), it2 = left_part.begin(); for (it1 = child_name.begin(), it2 = left_part.begin();
it1!=child_name.end() && it2!=left_part.end(); it1 != child_name.end() && it2 != left_part.end();
++it1, ++it2) { ++it1, ++it2) {
if (std::tolower(*it1) != std::tolower(*it2)) if (std::tolower(*it1) != std::tolower(*it2))
break; break;
@ -146,7 +137,6 @@ protected:
if (it2 == left_part.end()) { if (it2 == left_part.end()) {
setText(left_part + child_name.substr(left_part.size())); setText(left_part + child_name.substr(left_part.size()));
selectText(child_name.size(), left_part.size()); selectText(child_name.size(), left_part.size());
clear_keybuf();
return true; return true;
} }
} }
@ -259,6 +249,13 @@ FileSelector::FileSelector()
m_fileList->FileSelected.connect(Bind<void>(&FileSelector::onFileListFileSelected, this)); m_fileList->FileSelected.connect(Bind<void>(&FileSelector::onFileListFileSelected, this));
m_fileList->FileAccepted.connect(Bind<void>(&FileSelector::onFileListFileAccepted, this)); m_fileList->FileAccepted.connect(Bind<void>(&FileSelector::onFileListFileAccepted, this));
m_fileList->CurrentFolderChanged.connect(Bind<void>(&FileSelector::onFileListCurrentFolderChanged, this)); m_fileList->CurrentFolderChanged.connect(Bind<void>(&FileSelector::onFileListCurrentFolderChanged, this));
getManager()->addMessageFilter(kKeyDownMessage, this);
}
FileSelector::~FileSelector()
{
getManager()->removeMessageFilter(kKeyDownMessage, this);
} }
std::string FileSelector::show(const std::string& title, std::string FileSelector::show(const std::string& title,
@ -367,7 +364,7 @@ again:
std::string fn = m_fileName->getText(); std::string fn = m_fileName->getText();
std::string buf; std::string buf;
IFileItem* enter_folder = NULL; IFileItem* enter_folder = m_fileList->getSelectedFileItem();
// up a level? // up a level?
if (fn == "..") { if (fn == "..") {
@ -375,7 +372,12 @@ again:
if (!enter_folder) if (!enter_folder)
enter_folder = folder; enter_folder = folder;
} }
else if (!fn.empty()) { else if (fn.empty()) {
// show the window again
setVisible(true);
goto again;
}
else {
// check if the user specified in "fn" a item of "fileview" // check if the user specified in "fn" a item of "fileview"
const FileItemList& children = m_fileList->getFileList(); const FileItemList& children = m_fileList->getFileList();
@ -384,16 +386,14 @@ again:
fn2 = base::string_to_lower(fn2); fn2 = base::string_to_lower(fn2);
#endif #endif
for (FileItemList::const_iterator for (IFileItem* child : children) {
it=children.begin(); it!=children.end(); ++it) {
IFileItem* child = *it;
std::string child_name = child->getDisplayName(); std::string child_name = child->getDisplayName();
#ifdef WIN32 #ifdef WIN32
child_name = base::string_to_lower(child_name); child_name = base::string_to_lower(child_name);
#endif #endif
if (child_name == fn2) { if (child_name == fn2) {
enter_folder = *it; enter_folder = child;
buf = enter_folder->getFileName(); buf = enter_folder->getFileName();
break; break;
} }
@ -437,11 +437,6 @@ again:
enter_folder = fs->getFileItemFromPath(buf); enter_folder = fs->getFileItemFromPath(buf);
} }
} }
else {
// show the window again
setVisible(true);
goto again;
}
// did we find a folder to enter? // did we find a folder to enter?
if (enter_folder && if (enter_folder &&
@ -478,6 +473,31 @@ again:
return result; return result;
} }
bool FileSelector::onProcessMessage(ui::Message* msg)
{
switch (msg->type()) {
case kKeyDownMessage:
if (msg->ctrlPressed() || msg->cmdPressed()) {
KeyMessage* keyMsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keyMsg->scancode();
switch (scancode) {
case kKeyUp: onGoUp(); return true;
case kKeyLeft: onGoBack(); return true;
case kKeyRight: onGoForward(); return true;
case kKeyDown:
if (m_fileList->getSelectedFileItem() &&
m_fileList->getSelectedFileItem()->isBrowsable()) {
m_fileList->setCurrentFolder(
m_fileList->getSelectedFileItem());
}
return true;
}
}
break;
}
return Window::onProcessMessage(msg);
}
// Updates the content of the combo-box that shows the current // Updates the content of the combo-box that shows the current
// location in the file-system. // location in the file-system.
void FileSelector::updateLocation() void FileSelector::updateLocation()
@ -701,7 +721,7 @@ void FileSelector::onFileTypeChange()
if (!currentExtension.empty()) { if (!currentExtension.empty()) {
m_fileName->setText((fileName.substr(0, fileName.size()-currentExtension.size())+newExtension).c_str()); m_fileName->setText((fileName.substr(0, fileName.size()-currentExtension.size())+newExtension).c_str());
m_fileName->selectText(0, -1); m_fileName->selectAllText();
} }
} }
@ -713,7 +733,7 @@ void FileSelector::onFileListFileSelected()
std::string filename = base::get_file_name(fileitem->getFileName()); std::string filename = base::get_file_name(fileitem->getFileName());
m_fileName->setText(filename.c_str()); m_fileName->setText(filename.c_str());
m_fileName->selectText(0, -1); m_fileName->selectAllText();
selectFileTypeFromFileName(); selectFileTypeFromFileName();
} }
} }

View File

@ -39,12 +39,16 @@ namespace app {
class FileSelector : public ui::Window { class FileSelector : public ui::Window {
public: public:
FileSelector(); FileSelector();
~FileSelector();
// Shows the dialog to select a file in the program. // Shows the dialog to select a file in the program.
std::string show(const std::string& title, std::string show(const std::string& title,
const std::string& initialPath, const std::string& initialPath,
const std::string& showExtensions); const std::string& showExtensions);
protected:
bool onProcessMessage(ui::Message* msg) override;
private: private:
void updateLocation(); void updateLocation();
void updateNavigationButtons(); void updateNavigationButtons();