Keep Files commands focused during pane navigation
This commit is contained in:
1 parent
983e6f7b1a
commit
b5c803df87
4 files changed
+279
-75
No files matched your search
+250
-63
@@ -22,6 +22,7 @@
|
||||
#include "files_terminal_view.h"
|
||||
#include "files_lan_ipc.h"
|
||||
#include "lan_files.h"
|
||||
#include "platform.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -336,7 +337,8 @@ bool refreshDriveAddresses{};
|
||||
ULONGLONG driveOpened{};
|
||||
int drivePickerWidth{};
|
||||
int pickerPanel{};
|
||||
bool altAlone{};
|
||||
std::wstring panelSearchPrefix;
|
||||
HWND panelSearchPopup{};
|
||||
enum Color { PanelBlue, Text, Frame, Dialog, Selection, Footer, PanelCursor, ColorCount };
|
||||
constexpr std::array<COLORREF,ColorCount> defaultColors{RGB(0,0,128), RGB(230,255,255), RGB(0,255,255),
|
||||
RGB(0,128,128), RGB(0,0,0), RGB(0,128,128), RGB(0,128,128)};
|
||||
@@ -738,6 +740,24 @@ void paintScrollPosition(HWND parent, HDC dc, HWND list, COLORREF background)
|
||||
FillRect(dc, &track, static_cast<HBRUSH>(GetStockObject(DC_BRUSH)));
|
||||
}
|
||||
|
||||
void placePanelSearch(HWND window)
|
||||
{
|
||||
RECT panel{};
|
||||
GetWindowRect(panels[active].list,&panel);
|
||||
MapWindowPoints(nullptr,window,reinterpret_cast<POINT *>(&panel),2);
|
||||
const auto frame=dialogFrameMetrics(GetDpiForWindow(window));
|
||||
const int width=std::min(static_cast<int>(panel.right-panel.left),24*cellWidth+2*frame.content());
|
||||
const int height=textHeight+2*frame.content();
|
||||
SetWindowPos(panelSearchPopup,HWND_TOP,(panel.left+panel.right-width)/2,
|
||||
std::max(panel.top,panel.bottom+textHeight-height),width,height,SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
void closePanelSearch()
|
||||
{
|
||||
panelSearchPrefix.clear();
|
||||
if(IsWindowVisible(panelSearchPopup)) ShowWindow(panelSearchPopup,SW_HIDE);
|
||||
}
|
||||
|
||||
void layout(HWND window)
|
||||
{
|
||||
RECT rect{};
|
||||
@@ -804,6 +824,7 @@ void layout(HWND window)
|
||||
const int count=static_cast<int>(std::size(commands));
|
||||
place(commands[i],i*width/count,height-textHeight,(i+1)*width/count-i*width/count,textHeight);
|
||||
}
|
||||
if(IsWindowVisible(panelSearchPopup)) placePanelSearch(window);
|
||||
RedrawWindow(window,nullptr,nullptr,RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
|
||||
}
|
||||
|
||||
@@ -823,6 +844,76 @@ void showTerminal(HWND owner,bool show)
|
||||
|
||||
void open(Panel &panel,const fs::path &directory,bool offerElevation);
|
||||
|
||||
void activatePanel(int index)
|
||||
{
|
||||
const auto previous=active;
|
||||
active=index;
|
||||
showFileDetails(panels[index]);
|
||||
if(previous==active) return;
|
||||
for(const auto &panel:panels)
|
||||
{
|
||||
InvalidateRect(panel.path,nullptr,FALSE);
|
||||
InvalidateRect(panel.list,nullptr,FALSE);
|
||||
}
|
||||
layout(GetParent(panels[index].list));
|
||||
}
|
||||
|
||||
std::wstring terminalInputText()
|
||||
{
|
||||
std::wstring value(GetWindowTextLengthW(terminalInput)+1,L'\0');
|
||||
value.resize(GetWindowTextW(terminalInput,value.data(),static_cast<int>(value.size())));
|
||||
return value;
|
||||
}
|
||||
|
||||
void copyTerminalInput(HWND owner)
|
||||
{
|
||||
const auto value=terminalInputText();
|
||||
if(value.empty()) return;
|
||||
try { ks::writeClipboard(owner,ks::textClip(value)); }
|
||||
catch(const std::exception &) { setStatus(L"Could not copy the command line."); }
|
||||
}
|
||||
|
||||
LRESULT currentPanelRow(const Panel &panel)
|
||||
{
|
||||
const auto row=SendMessageW(panel.list,LB_GETCURSEL,0,0);
|
||||
return row>=0 && static_cast<size_t>(row)<panel.rows.size()?row:LB_ERR;
|
||||
}
|
||||
|
||||
std::wstring powerShellPath(const fs::path &path)
|
||||
{
|
||||
std::wstring quoted=L"'";
|
||||
for(const auto character:path.native())
|
||||
{
|
||||
// PowerShell recognizes typographic apostrophes as quote delimiters too.
|
||||
if(character==L'\'' || character==L'\u2018' || character==L'\u2019') quoted+=character;
|
||||
quoted+=character;
|
||||
}
|
||||
return quoted+L"'";
|
||||
}
|
||||
|
||||
void insertCurrentPanelPath()
|
||||
{
|
||||
const auto &panel=panels[active];
|
||||
const auto row=currentPanelRow(panel);
|
||||
if(row==LB_ERR) return;
|
||||
const auto &path=panel.rows[row].native();
|
||||
std::wstring quoted;
|
||||
if(path.find(L' ')!=std::wstring::npos)
|
||||
{
|
||||
quoted=L"\"";
|
||||
for(const auto character:path)
|
||||
{
|
||||
if(character==L'`' || character==L'$' || character==L'"' ||
|
||||
character==L'\u201c' || character==L'\u201d') quoted+=L'`';
|
||||
quoted+=character;
|
||||
}
|
||||
quoted+=L'"';
|
||||
}
|
||||
SetFocus(terminalInput);
|
||||
SendMessageW(terminalInput,EM_REPLACESEL,TRUE,
|
||||
reinterpret_cast<LPARAM>(quoted.empty()?path.c_str():quoted.c_str()));
|
||||
}
|
||||
|
||||
bool startTerminal(HWND owner)
|
||||
{
|
||||
if(terminal.alive()) return true;
|
||||
@@ -865,6 +956,8 @@ bool startTerminal(HWND owner)
|
||||
{
|
||||
if(GetForegroundWindow()==owner) SetFocus(terminalInput);
|
||||
}
|
||||
else if(message==L"insert-path") insertCurrentPanelPath();
|
||||
else if(message==L"copy-command-line") SendMessageW(terminalInput,WM_COPY,0,0);
|
||||
else if(message==L"toggle") showTerminal(owner,!terminalVisible);
|
||||
else if(!terminalVisible && (message==L"grow" || message==L"shrink"))
|
||||
{
|
||||
@@ -928,6 +1021,12 @@ bool submitTerminalCommand(const Panel &panel,const std::wstring &value)
|
||||
|
||||
LRESULT CALLBACK terminalInputKeys(HWND input,UINT message,WPARAM wp,LPARAM lp,UINT_PTR,DWORD_PTR)
|
||||
{
|
||||
if(message==WM_COPY || (message==WM_CHAR && wp==3))
|
||||
{
|
||||
copyTerminalInput(GetParent(input));
|
||||
return 0;
|
||||
}
|
||||
if(message==WM_CHAR && wp==VK_TAB && !terminalVisible) return 0;
|
||||
if(message==WM_CHAR && wp==VK_ESCAPE)
|
||||
{
|
||||
recallCommand(terminalHistory.size());
|
||||
@@ -962,31 +1061,24 @@ LRESULT CALLBACK terminalInputKeys(HWND input,UINT message,WPARAM wp,LPARAM lp,U
|
||||
SendMessageW(panels[active].list,WM_KEYDOWN,VK_RETURN,lp);
|
||||
return 0;
|
||||
}
|
||||
std::wstring value(GetWindowTextLengthW(input)+1,L'\0');
|
||||
value.resize(GetWindowTextW(input,value.data(),static_cast<int>(value.size())));
|
||||
const auto value=terminalInputText();
|
||||
if(!submitTerminalCommand(panels[active],value)) return 0;
|
||||
if(value.find_first_not_of(L" \t\r\n")!=std::wstring::npos) rememberCommand(value);
|
||||
terminalHistoryIndex=terminalHistory.size();
|
||||
SetWindowTextW(input,L"");
|
||||
return 0;
|
||||
}
|
||||
if(message==WM_CHAR && wp==3 && terminal.alive())
|
||||
if(message==WM_KEYDOWN && !terminalVisible && wp==VK_TAB)
|
||||
{
|
||||
DWORD first{},last{};
|
||||
SendMessageW(input,EM_GETSEL,reinterpret_cast<WPARAM>(&first),reinterpret_cast<LPARAM>(&last));
|
||||
if(first==last)
|
||||
{
|
||||
terminal.write(std::wstring(1,L'\x03'));
|
||||
return 0;
|
||||
}
|
||||
activatePanel(1-active);
|
||||
return 0;
|
||||
}
|
||||
if(message==WM_KEYDOWN && !terminalVisible &&
|
||||
(wp==VK_TAB || (wp>=VK_F1 && wp<=VK_F12) ||
|
||||
((wp>=VK_F1 && wp<=VK_F12) || wp==VK_UP || wp==VK_DOWN || wp==VK_PRIOR || wp==VK_NEXT ||
|
||||
(!GetWindowTextLengthW(input) &&
|
||||
((wp>=VK_PRIOR && wp<=VK_DOWN) || wp==VK_INSERT || wp==VK_DELETE))))
|
||||
(wp==VK_HOME || wp==VK_END || wp==VK_LEFT || wp==VK_RIGHT || wp==VK_INSERT || wp==VK_DELETE))))
|
||||
{
|
||||
SendMessageW(panels[active].list,WM_KEYDOWN,wp,lp);
|
||||
if(IsWindow(input)) SetFocus(input);
|
||||
return 0;
|
||||
}
|
||||
if(message==WM_KEYDOWN && (wp==VK_UP || wp==VK_DOWN))
|
||||
@@ -1586,14 +1678,7 @@ void openPanelFile(const Panel &panel, const fs::path &file, const wchar_t *verb
|
||||
};
|
||||
if(!verb && (isExtension(L".bat") || isExtension(L".cmd")))
|
||||
{
|
||||
std::wstring command=L"& '";
|
||||
for(const auto character:file.native())
|
||||
{
|
||||
// PowerShell recognizes typographic apostrophes as quote delimiters too.
|
||||
if(character==L'\'' || character==L'\u2018' || character==L'\u2019') command+=character;
|
||||
command+=character;
|
||||
}
|
||||
command+=L"'";
|
||||
const auto command=L"& "+powerShellPath(file);
|
||||
if(submitTerminalCommand(panel,command) && terminalRows<5)
|
||||
{
|
||||
terminalRows=5;
|
||||
@@ -1609,8 +1694,8 @@ void openPanelFile(const Panel &panel, const fs::path &file, const wchar_t *verb
|
||||
|
||||
void enter(Panel &panel)
|
||||
{
|
||||
auto row = SendMessageW(panel.list, LB_GETCURSEL, 0, 0);
|
||||
if (row >= 0 && static_cast<size_t>(row) < panel.rows.size())
|
||||
const auto row=currentPanelRow(panel);
|
||||
if(row!=LB_ERR)
|
||||
{
|
||||
auto target = panel.rows[row];
|
||||
if(panel.sizes[row]==L"Folder" || panel.sizes[row]==L"Up") open(panel,target,true);
|
||||
@@ -3207,7 +3292,7 @@ void deleteSelection(HWND owner,Panel &panel,bool permanent)
|
||||
|
||||
void selectPanelEdge(Panel &panel,bool first)
|
||||
{
|
||||
SetFocus(panel.list);
|
||||
activatePanel(static_cast<int>(&panel-panels));
|
||||
const auto count=SendMessageW(panel.list,LB_GETCOUNT,0,0);
|
||||
if(count<=0) return;
|
||||
SendMessageW(panel.list,LB_SETCURSEL,first?0:count-1,0);
|
||||
@@ -3256,19 +3341,7 @@ LRESULT CALLBACK panelKeys(HWND window, UINT message, WPARAM wp, LPARAM lp, UINT
|
||||
}
|
||||
if (message == WM_KEYDOWN && (wp == VK_LEFT || wp == VK_RIGHT))
|
||||
return scrollList(window, message, wp == VK_LEFT ? VK_HOME : VK_END, lp);
|
||||
if (message == WM_SETFOCUS)
|
||||
{
|
||||
const auto previous=active;
|
||||
active = static_cast<int>(index);
|
||||
if(previous!=active)
|
||||
for(auto &panel:panels)
|
||||
{
|
||||
InvalidateRect(panel.path,nullptr,FALSE);
|
||||
InvalidateRect(panel.list,nullptr,FALSE);
|
||||
}
|
||||
showFileDetails(panels[index]);
|
||||
if(previous!=active) layout(GetParent(window));
|
||||
}
|
||||
if(message==WM_SETFOCUS) activatePanel(static_cast<int>(index));
|
||||
if(message==WM_CHAR && wp>=32 && wp!=127)
|
||||
{
|
||||
SetFocus(terminalInput);
|
||||
@@ -3276,15 +3349,15 @@ LRESULT CALLBACK panelKeys(HWND window, UINT message, WPARAM wp, LPARAM lp, UINT
|
||||
}
|
||||
if (message == WM_KEYDOWN)
|
||||
{
|
||||
if (wp == VK_TAB) { SetFocus(panels[1 - index].list); return 0; }
|
||||
if(wp==VK_TAB) { activatePanel(static_cast<int>(1-index)); SetFocus(terminalInput); return 0; }
|
||||
if (wp == VK_RETURN) { enter(panels[index]); return 0; }
|
||||
if (wp == VK_F2) { open(panels[index], panels[index].directory); return 0; }
|
||||
if (wp == VK_F10) { SendMessageW(GetParent(window), WM_CLOSE, 0, 0); return 0; }
|
||||
if (wp == VK_F3 || wp == VK_F4)
|
||||
{
|
||||
const auto &panel = panels[index];
|
||||
auto row = SendMessageW(window, LB_GETCURSEL, 0, 0);
|
||||
if (row < 0 || static_cast<size_t>(row) >= panel.rows.size()) return 0;
|
||||
const auto row=currentPanelRow(panel);
|
||||
if(row==LB_ERR) return 0;
|
||||
const bool edit = wp == VK_F4;
|
||||
openPanelFile(panel, panel.rows[row], edit ? L"edit" : L"open",
|
||||
edit ? L"No editor is registered for this file." : L"Cannot open the selected file.");
|
||||
@@ -3433,27 +3506,19 @@ bool handleFilesMenuKey(HWND window,UINT message,WPARAM key,LPARAM flags,bool mo
|
||||
const bool repeated=(flags & (1LL << 30))!=0;
|
||||
if(message==WM_SYSKEYDOWN && key==VK_MENU)
|
||||
{
|
||||
if(!repeated) altAlone=!modified;
|
||||
return !modified;
|
||||
}
|
||||
if((message==WM_SYSKEYUP || message==WM_KEYUP) && key==VK_MENU)
|
||||
{
|
||||
if(std::exchange(altAlone,false))
|
||||
{
|
||||
toggleFilesMenu();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return !modified;
|
||||
if(message!=WM_KEYDOWN && message!=WM_SYSKEYDOWN) return false;
|
||||
altAlone=false;
|
||||
if(modified) return false;
|
||||
if(message==WM_KEYDOWN && key==VK_F9)
|
||||
{
|
||||
if(!repeated) toggleFilesMenu();
|
||||
return true;
|
||||
}
|
||||
if(message==WM_SYSKEYDOWN && (flags & (1LL << 29)) && key>=L'A' && key<=L'Z')
|
||||
if(IsWindowVisible(menuBar) && message==WM_SYSKEYDOWN &&
|
||||
(flags & (1LL << 29)) && key>=L'A' && key<=L'Z')
|
||||
{
|
||||
const auto category=menuAccessKeys.find(static_cast<wchar_t>(key));
|
||||
if(category!=menuAccessKeys.npos)
|
||||
@@ -3465,6 +3530,93 @@ bool handleFilesMenuKey(HWND window,UINT message,WPARAM key,LPARAM flags,bool mo
|
||||
return false;
|
||||
}
|
||||
|
||||
void searchPanelByPrefix(HWND window,wchar_t character)
|
||||
{
|
||||
if(character==L'\b')
|
||||
{
|
||||
if(!panelSearchPrefix.empty()) panelSearchPrefix.pop_back();
|
||||
}
|
||||
else panelSearchPrefix+=character;
|
||||
auto &panel=panels[active];
|
||||
const auto length=static_cast<int>(panelSearchPrefix.size());
|
||||
for(size_t row=0;length && row<panel.rows.size();++row)
|
||||
{
|
||||
if(panel.sizes[row]==L"Up") continue;
|
||||
const auto name=panel.rows[row].filename().native();
|
||||
if(name.size()<panelSearchPrefix.size() ||
|
||||
CompareStringOrdinal(name.data(),length,panelSearchPrefix.data(),length,TRUE)!=CSTR_EQUAL)
|
||||
continue;
|
||||
SendMessageW(panel.list,LB_SETCURSEL,row,0);
|
||||
InvalidateRect(panel.list,nullptr,FALSE);
|
||||
showFileDetails(panel);
|
||||
if(!IsWindowVisible(panelSearchPopup))
|
||||
{
|
||||
placePanelSearch(window);
|
||||
ShowWindow(panelSearchPopup,SW_SHOWNA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(IsWindowVisible(panelSearchPopup)) InvalidateRect(panelSearchPopup,nullptr,FALSE);
|
||||
else panelSearchPrefix.clear();
|
||||
}
|
||||
|
||||
bool handlePanelSearchKey(HWND window,MSG &message)
|
||||
{
|
||||
const bool searching=IsWindowVisible(panelSearchPopup);
|
||||
if(message.message==WM_LBUTTONDOWN || message.message==WM_RBUTTONDOWN ||
|
||||
message.message==WM_NCLBUTTONDOWN || message.message==WM_MOUSEWHEEL)
|
||||
{
|
||||
if(searching && message.hwnd!=panelSearchPopup) closePanelSearch();
|
||||
return false;
|
||||
}
|
||||
const bool input=message.hwnd==terminalInput || message.hwnd==panels[0].list ||
|
||||
message.hwnd==panels[1].list;
|
||||
if(!input || terminalVisible || IsWindowVisible(menuBar) || IsWindowVisible(picker)) return false;
|
||||
|
||||
const bool modified=(GetKeyState(VK_CONTROL)&0x8000) || (GetKeyState(VK_LWIN)&0x8000) ||
|
||||
(GetKeyState(VK_RWIN)&0x8000);
|
||||
const bool alt=(message.lParam & (1LL<<29))!=0;
|
||||
if((message.message==WM_SYSCHAR && alt) || (searching && message.message==WM_CHAR))
|
||||
{
|
||||
if(!modified && (message.wParam==L'\b' ||
|
||||
(message.wParam>=32 && message.wParam!=127 && (!alt || message.wParam!=L' '))))
|
||||
{
|
||||
searchPanelByPrefix(window,static_cast<wchar_t>(message.wParam));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(message.message!=WM_KEYDOWN && message.message!=WM_SYSKEYDOWN) return false;
|
||||
if(!modified && message.wParam!=VK_SPACE && message.message==WM_SYSKEYDOWN && alt &&
|
||||
(message.wParam==VK_BACK || MapVirtualKeyW(static_cast<UINT>(message.wParam),MAPVK_VK_TO_CHAR)))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
return true;
|
||||
}
|
||||
if(!searching || message.wParam==VK_MENU || message.wParam==VK_SHIFT) return false;
|
||||
if(!modified && !alt && (message.wParam==VK_BACK ||
|
||||
MapVirtualKeyW(static_cast<UINT>(message.wParam),MAPVK_VK_TO_CHAR)) &&
|
||||
message.wParam!=VK_RETURN && message.wParam!=VK_ESCAPE && message.wParam!=VK_TAB)
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
return true;
|
||||
}
|
||||
closePanelSearch();
|
||||
if(message.wParam==VK_RETURN && !modified && !alt)
|
||||
{
|
||||
SendMessageW(panels[active].list,message.message,message.wParam,message.lParam);
|
||||
return true;
|
||||
}
|
||||
return message.wParam==VK_ESCAPE && !modified && !alt;
|
||||
}
|
||||
|
||||
void restoreCommandFocus()
|
||||
{
|
||||
if(GetFocus()!=terminalInput && !GetCapture() && !copyInProgress && !activeFilesDialog &&
|
||||
!commandHistoryWindow && !IsWindowVisible(menuBar) && !IsWindowVisible(picker))
|
||||
SetFocus(terminalInput);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
if(message==filesPreferencesChanged)
|
||||
@@ -3481,8 +3633,11 @@ LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
}
|
||||
switch (message)
|
||||
{
|
||||
case WM_SETFOCUS:
|
||||
restoreCommandFocus();
|
||||
return 0;
|
||||
case WM_ACTIVATEAPP:
|
||||
if(!wp) altAlone=false;
|
||||
if(!wp) closePanelSearch();
|
||||
break;
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
@@ -3538,6 +3693,8 @@ LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
SendMessageW(picker,LB_SETITEMHEIGHT,0,textHeight);
|
||||
status = CreateWindowW(L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_PATHELLIPSIS,
|
||||
0, 0, 0, 0, window, reinterpret_cast<HMENU>(144), instance, nullptr);
|
||||
panelSearchPopup=CreateWindowW(L"STATIC",L"Search",WS_CHILD|WS_CLIPSIBLINGS|SS_OWNERDRAW|SS_NOTIFY,
|
||||
0,0,0,0,window,reinterpret_cast<HMENU>(148),instance,nullptr);
|
||||
terminalInput=CreateWindowW(L"EDIT",L"",WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,
|
||||
0,0,0,0,window,nullptr,instance,nullptr);
|
||||
terminalPrompt=CreateWindowW(L"STATIC",L"",WS_CHILD|WS_VISIBLE|SS_PATHELLIPSIS,
|
||||
@@ -3553,7 +3710,7 @@ LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
SetWindowSubclass(terminalInput,terminalInputKeys,1,0);
|
||||
SetTimer(window,terminalTimer,50,nullptr);
|
||||
SetTimer(window,directoryWatchTimer,200,nullptr);
|
||||
if (!mono || !blue || !teal || !menuBar || !picker || !pickerFrame || !status) return -1;
|
||||
if (!mono || !blue || !teal || !menuBar || !picker || !pickerFrame || !status || !panelSearchPopup) return -1;
|
||||
SendMessageW(status, WM_SETFONT, reinterpret_cast<WPARAM>(mono), FALSE);
|
||||
const wchar_t *labels[]{L"F2 Refresh", L"F3 View", L"F4 Edit", L"F5 Copy", L"F6 Move", L"F10 Exit"};
|
||||
for (int i = 0; i < static_cast<int>(std::size(commands)); ++i)
|
||||
@@ -3727,6 +3884,21 @@ LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
case WM_DRAWITEM:
|
||||
{
|
||||
const auto &item=*reinterpret_cast<const DRAWITEMSTRUCT *>(lp);
|
||||
if(item.hwndItem==panelSearchPopup)
|
||||
{
|
||||
const auto frame=dialogFrameMetrics(GetDpiForWindow(window));
|
||||
const auto surface=GetSysColorBrush(COLOR_BTNFACE);
|
||||
const auto border=GetSysColorBrush(COLOR_BTNTEXT);
|
||||
const auto ink=GetSysColor(COLOR_BTNTEXT);
|
||||
const auto box=paintDialogFrame(item.hDC,item.rcItem,frame,surface,border);
|
||||
paintDialogFrameCaptions(item.hDC,item.rcItem,box,L"Search",surface,ink,mono);
|
||||
auto field=item.rcItem;
|
||||
InflateRect(&field,-frame.content(),-frame.content());
|
||||
const auto cells=static_cast<size_t>(std::max(0L,field.right-field.left-10)/std::max(1,cellWidth));
|
||||
const auto start=panelSearchPrefix.size()>cells?panelSearchPrefix.size()-cells:0;
|
||||
paintText(item.hDC,field,panelSearchPrefix.c_str()+start,RGB(0,0,0),RGB(0,128,128));
|
||||
return TRUE;
|
||||
}
|
||||
if(item.CtlID==142 || item.CtlID==143)
|
||||
{
|
||||
auto bounds=item.rcItem;
|
||||
@@ -4001,7 +4173,6 @@ LRESULT CALLBACK filesWindow(HWND window, UINT message, WPARAM wp, LPARAM lp)
|
||||
if (LOWORD(wp) >= 110 && LOWORD(wp) <= 115 && HIWORD(wp) == BN_CLICKED)
|
||||
{
|
||||
const WPARAM keys[]{VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F10};
|
||||
SetFocus(panels[active].list);
|
||||
SendMessageW(panels[active].list, WM_KEYDOWN, keys[LOWORD(wp) - 110], 0);
|
||||
}
|
||||
if (LOWORD(wp) >= 102 && LOWORD(wp) <= 103 && HIWORD(wp) == LBN_DBLCLK)
|
||||
@@ -4111,8 +4282,13 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
|
||||
SetFocus(terminalInput);
|
||||
const auto com=CoInitializeEx(nullptr,COINIT_APARTMENTTHREADED);
|
||||
MSG message{};
|
||||
while (GetMessageW(&message, nullptr, 0, 0) > 0)
|
||||
for(;;)
|
||||
{
|
||||
if(GetForegroundWindow()==window) restoreCommandFocus();
|
||||
if(GetMessageW(&message,nullptr,0,0)<=0) break;
|
||||
if(message.hwnd==window && message.message>=WM_KEYFIRST && message.message<=WM_KEYLAST &&
|
||||
GetFocus()==terminalInput)
|
||||
message.hwnd=terminalInput;
|
||||
if(commandHistoryWindow)
|
||||
{
|
||||
if(message.message==WM_KEYDOWN && (message.wParam==VK_RETURN || message.wParam==VK_ESCAPE) &&
|
||||
@@ -4128,6 +4304,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
|
||||
message.message==WM_CONTEXTMENU;
|
||||
if(ownerClient && clientInput) continue;
|
||||
}
|
||||
if(!copyInProgress && handlePanelSearchKey(window,message)) continue;
|
||||
if(message.message==WM_KEYDOWN && (message.wParam==VK_UP || message.wParam==VK_DOWN) &&
|
||||
(GetKeyState(VK_CONTROL)&0x8000) && !(GetKeyState(VK_MENU)&0x8000) &&
|
||||
(message.hwnd==window || IsChild(window,message.hwnd)) && !terminalVisible && !copyInProgress)
|
||||
@@ -4150,8 +4327,9 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
|
||||
if(terminalVisible || startTerminal(window)) showTerminal(window,!terminalVisible);
|
||||
continue;
|
||||
}
|
||||
if(message.message==WM_KEYDOWN &&
|
||||
(message.hwnd==panels[0].list || message.hwnd==panels[1].list) &&
|
||||
const bool panelFocused=message.hwnd==panels[0].list || message.hwnd==panels[1].list;
|
||||
const bool mainInput=panelFocused || message.hwnd==terminalInput;
|
||||
if(message.message==WM_KEYDOWN && mainInput && !terminalVisible &&
|
||||
(GetKeyState(VK_CONTROL)&0x8000) && !(GetKeyState(VK_MENU)&0x8000) &&
|
||||
!(GetKeyState(VK_LWIN)&0x8000) && !(GetKeyState(VK_RWIN)&0x8000) &&
|
||||
message.wParam>='0' && message.wParam<='9' && !copyInProgress &&
|
||||
@@ -4161,7 +4339,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
|
||||
{
|
||||
hidePicker();
|
||||
showMenu(false);
|
||||
auto &panel=panels[message.hwnd==panels[1].list];
|
||||
auto &panel=panels[active];
|
||||
const auto digit=static_cast<int>(message.wParam-'0');
|
||||
if(GetKeyState(VK_SHIFT)&0x8000) addFolderShortcut(panel,digit);
|
||||
else showFolderShortcuts(panel,digit);
|
||||
@@ -4183,15 +4361,24 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const bool panelFocused=message.hwnd==panels[0].list || message.hwnd==panels[1].list;
|
||||
if(panelFocused && !copyInProgress && message.message==WM_KEYDOWN &&
|
||||
if(mainInput &&
|
||||
!copyInProgress && message.message==WM_KEYDOWN &&
|
||||
!(GetKeyState(VK_MENU)&0x8000) &&
|
||||
!(GetKeyState(VK_LWIN)&0x8000) && !(GetKeyState(VK_RWIN)&0x8000))
|
||||
{
|
||||
const bool ctrl=(GetKeyState(VK_CONTROL)&0x8000)!=0;
|
||||
const bool shift=(GetKeyState(VK_SHIFT)&0x8000)!=0;
|
||||
if((message.wParam=='V' && ctrl && !shift) ||
|
||||
(message.wParam==VK_INSERT && shift && !ctrl))
|
||||
if(ctrl && !shift && (message.wParam=='F' || message.wParam=='C'))
|
||||
{
|
||||
if(!(message.lParam & (1LL<<30)))
|
||||
{
|
||||
if(message.wParam=='F') insertCurrentPanelPath();
|
||||
else SendMessageW(terminalInput,WM_COPY,0,0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(panelFocused && ((message.wParam=='V' && ctrl && !shift) ||
|
||||
(message.wParam==VK_INSERT && shift && !ctrl)))
|
||||
{
|
||||
SetFocus(terminalInput);
|
||||
SendMessageW(terminalInput,WM_PASTE,0,0);
|
||||
|
||||
Reference in new issue
Block a user