diff --git a/extra/Addons/Colors/Interface/Colors_from_Gernichenko.farconfig b/extra/Addons/Colors/Interface/Colors_from_Gernichenko.farconfig index d114c8c272..525d64d354 100644 --- a/extra/Addons/Colors/Interface/Colors_from_Gernichenko.farconfig +++ b/extra/Addons/Colors/Interface/Colors_from_Gernichenko.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/Colors_from_Sadovoj.farconfig b/extra/Addons/Colors/Interface/Colors_from_Sadovoj.farconfig index 0e8537ac39..bb640feb25 100644 --- a/extra/Addons/Colors/Interface/Colors_from_Sadovoj.farconfig +++ b/extra/Addons/Colors/Interface/Colors_from_Sadovoj.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/Colors_from_admin_essp_ru.farconfig b/extra/Addons/Colors/Interface/Colors_from_admin_essp_ru.farconfig index b6101ca70b..3ac1e6eb0d 100644 --- a/extra/Addons/Colors/Interface/Colors_from_admin_essp_ru.farconfig +++ b/extra/Addons/Colors/Interface/Colors_from_admin_essp_ru.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/FARColors242.farconfig b/extra/Addons/Colors/Interface/FARColors242.farconfig index f24ef5b69c..a4b55dc25c 100644 --- a/extra/Addons/Colors/Interface/FARColors242.farconfig +++ b/extra/Addons/Colors/Interface/FARColors242.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/GreenMile.farconfig b/extra/Addons/Colors/Interface/GreenMile.farconfig index 9100474064..1c125c2b41 100644 --- a/extra/Addons/Colors/Interface/GreenMile.farconfig +++ b/extra/Addons/Colors/Interface/GreenMile.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/Rodion_Doroshkevich.farconfig b/extra/Addons/Colors/Interface/Rodion_Doroshkevich.farconfig index dfbd290719..d32406d958 100644 --- a/extra/Addons/Colors/Interface/Rodion_Doroshkevich.farconfig +++ b/extra/Addons/Colors/Interface/Rodion_Doroshkevich.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/VaxColors.farconfig b/extra/Addons/Colors/Interface/VaxColors.farconfig index 1bb0c3fe9c..c2854a4a94 100644 --- a/extra/Addons/Colors/Interface/VaxColors.farconfig +++ b/extra/Addons/Colors/Interface/VaxColors.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/black_and_white.farconfig b/extra/Addons/Colors/Interface/black_and_white.farconfig index 67de8c99d1..a322546675 100644 --- a/extra/Addons/Colors/Interface/black_and_white.farconfig +++ b/extra/Addons/Colors/Interface/black_and_white.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/black_from_Fonarev.farconfig b/extra/Addons/Colors/Interface/black_from_Fonarev.farconfig index 5158656af8..e5c3e4b25b 100644 --- a/extra/Addons/Colors/Interface/black_from_Fonarev.farconfig +++ b/extra/Addons/Colors/Interface/black_from_Fonarev.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/black_from_Myodov.farconfig b/extra/Addons/Colors/Interface/black_from_Myodov.farconfig index a8cc59c7e4..94d5ba48fc 100644 --- a/extra/Addons/Colors/Interface/black_from_Myodov.farconfig +++ b/extra/Addons/Colors/Interface/black_from_Myodov.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/black_from_july.farconfig b/extra/Addons/Colors/Interface/black_from_july.farconfig index a014e37b9e..9f551995ff 100644 --- a/extra/Addons/Colors/Interface/black_from_july.farconfig +++ b/extra/Addons/Colors/Interface/black_from_july.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/dn_like.farconfig b/extra/Addons/Colors/Interface/dn_like.farconfig index 6bc7d5249b..07bd606f79 100644 --- a/extra/Addons/Colors/Interface/dn_like.farconfig +++ b/extra/Addons/Colors/Interface/dn_like.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/hell.farconfig b/extra/Addons/Colors/Interface/hell.farconfig index b0ed094ce4..ca9d6fa3cc 100644 --- a/extra/Addons/Colors/Interface/hell.farconfig +++ b/extra/Addons/Colors/Interface/hell.farconfig @@ -85,6 +85,7 @@ + diff --git a/extra/Addons/Colors/Interface/nc5pal2.farconfig b/extra/Addons/Colors/Interface/nc5pal2.farconfig index b299458f7d..d824405932 100644 --- a/extra/Addons/Colors/Interface/nc5pal2.farconfig +++ b/extra/Addons/Colors/Interface/nc5pal2.farconfig @@ -85,6 +85,7 @@ + diff --git a/far/FarColorW.pas b/far/FarColorW.pas index e074dc33bf..365ab80772 100644 --- a/far/FarColorW.pas +++ b/far/FarColorW.pas @@ -215,7 +215,8 @@ interface COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON = 145; COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON = 146; - COL_LASTPALETTECOLOR = 147; + COL_PANELDRAGBORDER = 147; + COL_LASTPALETTECOLOR = 148; implementation end. diff --git a/far/FarCze.hlf.m4 b/far/FarCze.hlf.m4 index 75f38adbea..c2abe7702a 100644 --- a/far/FarCze.hlf.m4 +++ b/far/FarCze.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Czech,Čeština .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -365,11 +365,15 @@ $ #Ovládání panelů# Skrytí/ukázání levého panelu #Ctrl+F1# Skrytí/ukázání pravého panelu #Ctrl+F2# Změna výšky panelu #Ctrl+Nahoru,Ctrl+Dolů# - Změna šířky panelu #Ctrl+Vlevo,Ctrl+Vpravo# - Change panels width #Ctrl+Left,Ctrl+Right# + Změna výšky aktuálního panelu #Ctrl+Shift+Nahoru,Ctrl+Shift+Dolů# + Změna výšky panelů myší #Přetažení dolní hranice panelů# + Změna šířky panelů klávesnicí #Ctrl+Vlevo,Ctrl+Vpravo# (pokud je příkazová řádka prázdná) + Změna šířky panelů myší #Přetažení hranice mezi panely# Obnovení nastavení implicitní šířky panelů #Ctrl+Numpad5# - Restore default panels height #Ctrl+Alt+Numpad5# + nebo myší #Dvojklik# na hranici mezi panely + Obnovení nastavení implicitní výšky panelů #Ctrl+Alt+Numpad5# + nebo myší #Dvojklik# na dolní hranici panelu Zobrazení/Skrytí panelu funkčních kláves na spodní části. #Ctrl+B# Toggle total and free size show mode #Ctrl+Shift+S# in bytes (if possible) or with size suffixes K/M/G/T @@ -1181,6 +1185,26 @@ přepnut na souborový. ~Rychlé hledání~@FastFind@ může být použito pro dosažení požadovaného souboru pomocí prvního znaku jeho názvu. + #Změna velikosti panelů myší# + + Můžete změnit šířku souborových panelů pomocí myši: + + - ^Najeďte kurzorem myši na hranici mezi levým a pravým panelem, abyste viděli vizuální zpětnou vazbu označující oblast, kterou lze změnit. + - ^Klikněte a táhněte hranici doleva nebo doprava pro úpravu šířky panelů. + - ^Dvojklikněte na hranici pro obnovení výchozí stejné šířky panelů (rozdělení 50/50). + - ^Stiskněte #Esc# během změny velikosti pro zrušení a návrat k původní šířce panelů. + + #Změna výšky:# + - ^Najeďte kurzorem myši na spodní hranici panelu, abyste viděli vizuální zpětnou vazbu označující oblast, kterou lze změnit. + - ^Klikněte a táhněte spodní hranici nahoru nebo dolů pro úpravu výšky panelu. + - ^Chování změny velikosti závisí na horizontální pozici myši: + - ^Nad spodní hranicí LEVÉHO panelu v levé polovině panelu → Změna velikosti pouze LEVÉHO panelu + - ^Nad spodní hranicí LEVÉHO panelu v pravé polovině panelu → Změna velikosti OBOU panelů + - ^Nad spodní hranicí PRAVÉHO panelu v levé polovině panelu → Změna velikosti OBOU panelů + - ^Nad spodní hranicí PRAVÉHO panelu v pravé polovině panelu → Změna velikosti pouze PRAVÉHO panelu + - ^Dvojklikněte na spodní hranici pro obnovení plné výšky panelu. + - ^Stiskněte #Esc# během změny velikosti pro zrušení a návrat k původní výšce panelů. + See also the list of ~macro keys~@KeyMacroShellList@, available in the panels. diff --git a/far/FarEng.hlf.m4 b/far/FarEng.hlf.m4 index 12948be44e..7c591e4b61 100644 --- a/far/FarEng.hlf.m4 +++ b/far/FarEng.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=English,English .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -365,10 +365,14 @@ $ #Panel control commands# Hide/show right panel #Ctrl+F2# Change panels height #Ctrl+Up,Ctrl+Down# Change current panel height #Ctrl+Shift+Up,Ctrl+Shift+Down# - Change panels width #Ctrl+Left,Ctrl+Right# + Change panels height with mouse #Drag bottom border# of panels + Change panels width with keyboard #Ctrl+Left,Ctrl+Right# (when the command line is empty) - Restore default panels width #Ctrl+Numpad5# - Restore default panels height #Ctrl+Alt+Numpad5# + Change panels width with mouse #Drag border between panels# + Restore default panels width keyboard #Ctrl+Numpad5# + or with mouse #Double click# on border between panels + Restore default panels height with keyboard #Ctrl+Alt+Numpad5# + or with mouse #Double click# on bottom border of panel Show/Hide functional key bar at the bottom line. #Ctrl+B# Toggle total and free size show mode #Ctrl+Shift+S# in bytes (if possible) or with size suffixes K/M/G/T @@ -1160,6 +1164,27 @@ if the initial panel type differs it will be automatically set to the file panel ~Fast find~@FastFind@ action can be used to point to the required file by the first letters of its name. + #Mouse panel resizing# + + You can resize the width and height of file panels using the mouse: + + #Width resizing:# + - ^Hover the mouse cursor over the vertical border between the left and right panels to see visual feedback indicating the resizable area. + - ^Click and drag the border left or right to adjust the panel widths. + - ^Double-click on the vertical border to restore default equal panel widths (50/50 split). + - ^Press #Esc# during resizing to cancel and revert to the original panel widths. + + #Height resizing:# + - ^Hover the mouse cursor over the bottom border of a panel to see visual feedback indicating the resizable area. + - ^Click and drag the bottom border up or down to adjust the panel height. + - ^The resizing behavior depends on the horizontal mouse position: + - ^Over LEFT panel bottom border in Left half of panel → Resize LEFT panel only + - ^Over LEFT panel bottom border in Right half of panel → Resize BOTH panels + - ^Over RIGHT panel bottom border in Left half of panel → Resize BOTH panels + - ^Over RIGHT panel bottom border in Right half of panel → Resize RIGHT panel only + - ^Double-click on the bottom border to restore full panel height. + - ^Press #Esc# during resizing to cancel and revert to the original panel heights. + See also the list of ~macro keys~@KeyMacroShellList@, available in the panels. diff --git a/far/FarGer.hlf.m4 b/far/FarGer.hlf.m4 index 5b7730d704..1d73ef940f 100644 --- a/far/FarGer.hlf.m4 +++ b/far/FarGer.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=German,Deutsch .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -368,11 +368,15 @@ $ #Befehl zur Fenstersteuerung# Linkes Fenster anzeigen/verbergen #Strg+F1# Rechtes Fenster anzeigen/verbergen #Strg+F2# Fensterhöhe ändern #Strg+↑,Strg+↓# - Change current panel height #Ctrl+Shift+Up,Ctrl+Shift+Down# - Fensterbreite ändern #Strg+Links,Strg+Rechts# + Aktuelle Fensterhöhe ändern #Strg+Shift+↑,Strg+Shift+↓# + Fensterhöhe mit Maus ändern #Untere Grenze der Fenster ziehen# + Fensterbreite mit Tastatur ändern #Strg+Links,Strg+Rechts# (b.leerer Kommandozeile) + Fensterbreite mit Maus ändern #Grenze zwischen Fenstern ziehen# Standardfensterbreite wiederherstellen #Strg+Num5# - Restore default panels height #Ctrl+Alt+Numpad5# + oder mit Maus #Doppelklick# auf Grenze zwischen Fenstern + Standardfensterhöhe wiederherstellen #Strg+Alt+Num5# + oder mit Maus #Doppelklick# auf untere Grenze der Fenster Show/Hide functional key bar at the bottom line. #Ctrl+B# Toggle total and free size show mode #Ctrl+Shift+S# in bytes (if possible) or with size suffixes K/M/G/T @@ -1183,6 +1187,27 @@ automatisch die Starteinstellung des Fenstertyps benutzt. Die ~Schnellsuche~@FastFind@ kann benutzt werden, um durch die Anfangsbuch- staben eines Namens auf die Datei zu springen. + #Fenstergröße mit der Maus ändern# + + Sie können die Breite und Höhe der Dateifenster mit der Maus ändern: + + #Breite ändern:# + - ^Bewegen Sie den Mauszeiger über die vertikale Grenze zwischen dem linken und rechten Fenster, um eine visuelle Rückmeldung für den veränderbaren Bereich zu sehen. + - ^Klicken und ziehen Sie die Grenze nach links oder rechts, um die Fensterbreiten anzupassen. + - ^Doppelklicken Sie auf die vertikale Grenze, um die standardmäßigen gleichen Fensterbreiten wiederherzustellen (50/50-Aufteilung). + - ^Drücken Sie #Esc# während der Größenänderung, um abzubrechen und zur ursprünglichen Fensterbreite zurückzukehren. + + #Höhe ändern:# + - ^Bewegen Sie den Mauszeiger über die untere Grenze eines Fensters, um eine visuelle Rückmeldung für den veränderbaren Bereich zu sehen. + - ^Klicken und ziehen Sie die untere Grenze nach oben oder unten, um die Fensterhöhe anzupassen. + - ^Das Verhalten der Größenänderung hängt von der horizontalen Mausposition ab: + - ^Über LINKEM Fenster in linker Hälfte → Nur LINKES Fenster ändern + - ^Über LINKEM Fenster in rechter Hälfte → BEIDE Fenster ändern + - ^Über RECHTEM Fenster in linker Hälfte → BEIDE Fenster ändern + - ^Über RECHTEM Fenster in rechter Hälfte → Nur RECHTES Fenster ändern + - ^Doppelklicken Sie auf die untere Grenze, um die volle Fensterhöhe wiederherzustellen. + - ^Drücken Sie #Esc# während der Größenänderung, um abzubrechen und zur ursprünglichen Fensterhöhe zurückzukehren. + See also the list of ~macro keys~@KeyMacroShellList@, available in the panels. diff --git a/far/FarHun.hlf.m4 b/far/FarHun.hlf.m4 index a3e8ebab9d..822c2b74e8 100644 --- a/far/FarHun.hlf.m4 +++ b/far/FarHun.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Hungarian,Magyar .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -373,10 +373,16 @@ $ #Panelvezérlő parancsok# Elrejti/megmutatja a bal panelt #Ctrl+F1# Elrejti/megmutatja a jobb panelt #Ctrl+F2# A panelek magasságán változtat #Ctrl+Fel,Ctrl+Le# - A panelek szélességén változtat #Ctrl+Jobb,Ctrl+Bal# + Az aktuális panel magasságán változtat #Ctrl+Shift+Fel,Ctrl+Shift+Le# + A panelek magasságán változtat egérrel #Alsó határ húzása a paneleken# + A panelek szélességén változtat billentyűzettel #Ctrl+Jobb,Ctrl+Bal# (ha a parancssor üres) + A panelek szélességén változtat egérrel + #Határ húzása a panelek között# Visszaállítja a panelszélességek alapértékét #Ctrl+Numpad5# + vagy egérrel #Dupla kattintás# a panelek határán Visszaállítja a panelmagasságok alapértékét #Ctrl+Alt+Numpad5# + vagy egérrel #Dupla kattintás# a panel alsó határán Megmutatja/elrejti a funkcióbillentyűk sorát #Ctrl+B# a képernyő alján Toggle total and free size show mode #Ctrl+Shift+S# @@ -1185,6 +1191,26 @@ volt, a módváltás vagy a meghajtóváltás után automatikusan fájlpanel mó A ~gyorskeresés~@FastFind@ művelet a keresett fájlnév karaktereinek begépelésével a megfelelő fájlra állítja a kurzort. + #Panel átméretezése egérrel# + + A fájlpanelek szélességét egérrel is módosíthatja: + + - ^Vigye az egérmutatót a bal és jobb panel közötti határvonalra, hogy lássa az átméretezési terület vizuális jelzését. + - ^Kattintson és húzza a határvonalat balra vagy jobbra a panelek szélességének beállításához. + - ^Kattintson duplán a határvonalra az alapértelmezett egyenlő panelszélesség visszaállításához (50/50 felosztás). + - ^Nyomja meg az #Esc# billentyűt az átméretezés során a megszakításhoz és az eredeti panelszélességek visszaállításához. + + #Magasság átméretezése:# + - ^Vigye az egérmutatót a panel alsó határvonalára, hogy lássa az átméretezési terület vizuális jelzését. + - ^Kattintson és húzza az alsó határvonalat fel vagy le a panel magasságának beállításához. + - ^Az átméretezés viselkedése az egér vízszintes pozíciójától függ: + - ^A BAL panel alsó határvonala felett a panel bal felében → Csak a BAL panel átméretezése + - ^A BAL panel alsó határvonala felett a panel jobb felében → MINDKÉT panel átméretezése + - ^A JOBB panel alsó határvonala felett a panel bal felében → MINDKÉT panel átméretezése + - ^A JOBB panel alsó határvonala felett a panel jobb felében → Csak a JOBB panel átméretezése + - ^Kattintson duplán az alsó határvonalra a teljes panelmagasság visszaállításához. + - ^Nyomja meg az #Esc# billentyűt az átméretezés során a megszakításhoz és az eredeti panelmagasságok visszaállításához. + See also the list of ~macro keys~@KeyMacroShellList@, available in the panels. diff --git a/far/FarPol.hlf.m4 b/far/FarPol.hlf.m4 index d46ee9ea9e..84fc9f9c40 100644 --- a/far/FarPol.hlf.m4 +++ b/far/FarPol.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Polish,Polski .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -369,10 +369,14 @@ $ #Polecenia kontroli panelu# Ukryj/pokaż prawy panel #Ctrl+F2# Zmień wysokość panelu #Ctrl+Góra,Ctrl+Dół# Zmień wysokość bieżącego panelu #Ctrl+Shift+Góra,Ctrl+Shift+Dół# - Zmień szerokość panelu #Ctrl+Lewo,Ctrl+Prawo# + Zmień wysokość paneli myszą #Przeciągnij dolną granicę paneli# + Zmień szerokość paneli klawiaturą #Ctrl+Lewo,Ctrl+Prawo# (tylko gdy wiersz poleceń jest pusty) + Zmień szerokość paneli myszą #Przeciągnij granicę między panelami# Przywróć domyślną szerokość paneli #Ctrl+Numpad5# + lub myszą #Podwójne kliknięcie# na granicy między panelami Przywróć domyślną wysokość paneli #Ctrl+Alt+Numpad5# + lub myszą #Podwójne kliknięcie# na dolnej granicy panelu Pokaż/Ukryj pasek skrótów w dolnej linii #Ctrl+B# Przełącz tryb całkowitej i wolnej wielkości #Ctrl+Shift+S# w bajtach (jeżeli możliwe) lub w wielokrotnościach K/M/G/T @@ -1152,6 +1156,26 @@ automatycznie ustawiony na panel plików. Operacja ~szybkiego szukania~@FastFind@ może być użyta jako odnośnik do żądanego plików po pierwszej literze jego nazwy. + #Zmiana rozmiaru paneli myszą# + + Można zmieniać szerokość paneli plików za pomocą myszy: + + - ^Najedź kursorem myszy na granicę między lewym i prawym panelem, aby zobaczyć wizualną informację o możliwości zmiany rozmiaru. + - ^Kliknij i przeciągnij granicę w lewo lub w prawo, aby dostosować szerokość paneli. + - ^Kliknij dwukrotnie na granicy, aby przywrócić domyślną równą szerokość paneli (podział 50/50). + - ^Naciśnij #Esc# podczas zmiany rozmiaru, aby anulować i powrócić do oryginalnej szerokości paneli. + + #Zmiana wysokości:# + - ^Najedź kursorem myszy na dolną granicę panelu, aby zobaczyć wizualną informację zwrotną wskazującą obszar, który można zmieniać. + - ^Kliknij i przeciągnij dolną granicę w górę lub w dół, aby dostosować wysokość panelu. + - ^Zachowanie zmiany rozmiaru zależy od poziomej pozycji myszy: + - ^Nad dolną granicą LEWEGO panelu w lewej połowie panelu → Zmiana rozmiaru tylko LEWEGO panelu + - ^Nad dolną granicą LEWEGO panelu w prawej połowie panelu → Zmiana rozmiaru OBU paneli + - ^Nad dolną granicą PRAWEGO panelu w lewej połowie panelu → Zmiana rozmiaru OBU paneli + - ^Nad dolną granicą PRAWEGO panelu w prawej połowie panelu → Zmiana rozmiaru tylko PRAWEGO panelu + - ^Kliknij dwukrotnie na dolną granicę, aby przywrócić pełną wysokość panelu. + - ^Naciśnij #Esc# podczas zmiany rozmiaru, aby anulować i powrócić do oryginalnej wysokości paneli. + Zobacz także listę ~klawiszy makropoleceń~@KeyMacroShellList@, dostępnych w panelach. @@ -6607,21 +6631,21 @@ w Edytorze. @Editor.SearchAllUseAltFileNameFormat $ #far:config Editor.SearchAllUseAltFileNameFormat# - This string parameter controls composing of the file name used by the -new Editor containing ~all matching entries~@FindAllMenu@. The value -is one or more ~file masks~@FileMasks@. + Ten parametr łańcuchowy kontroluje tworzenie nazwy pliku używanej przez +nowy Edytor zawierający ~wszystkie pasujące wpisy~@FindAllMenu@. +Wartością jest jedna lub więcej ~masek plików~@FileMasks@. - The new filename is created from the stem filename and the extension -of the file currently opened in the Editor. Depending on the original -file name, the new file name is formatted using one of the two -alternative UI format strings defined in ~.lng files~@CustomizingUI@. -The string with the ID #MEditSearchAllFileNameFormatAlt# is used if the -original file name matches one of the file masks; otherwise, -#MEditSearchAllFileNameFormat# is used. + Nowa nazwa pliku jest tworzona wg nazwy podstawowego pliku i rozszerzenia +pliku aktualnie otwartego w edytorze. W zależoności od oryginalnej nazwy +pliku, nowa nazwa jest formatowana przy użyciu jednego z dwóch alternatywnych +ciągów zdefiniowanych w ~plikach .lng~@CustomizingUI@. +Łańcuch o identyfikatorze #MEditSearchAllFileNameFormatAlt# jest używany, +jeżeli oryginalna nazwa pliku pasuje do jednej z masek plików; +w przeciwnym razie używany jest identyfikator #MEditSearchAllFileNameFormat#. - Default value: #*.txt,*.log,*.md,*.csv,*.ini,*.cmd,*.map# + Wartość domyślna: #*.txt,*.log,*.md,*.csv,*.ini,*.cmd,*.map# - This parameter can be changed via ~far:config~@FarConfig@ only. + Parametr też można zmienić tylko w ~far:config~@FarConfig@. @Panel.ShortcutAlwaysChdir @@ -6890,17 +6914,17 @@ tworzenia, usuwania lub zmiany nazw folderów. @Panel.TreatDotFilesAsHidden $ #far:config Panel.TreatDotFilesAsHidden# - This Boolean parameter controls the filtering of files or folders -starting with a dot (“dotfiles”). It works in combination with the -#Show hidden and system files# option in the -~panel settings~@PanelSettings@ dialog. + Ten parametr logiczny kontroluje filtrowanie plików lub folderów rozpoczynających się +od kropki (“dotfiles”). Działa w połączeniu z opcją #Pokazuj pliki ukryte i systemowe# +w oknie ~ustawień panelu~@PanelSettings@. - False - ^Dotfiles will always be shown. - True - Dotfiles will be hidden/shown together with the Hidden and System files. + Fałsz - ^Pliki zaczynające się kropkami zawsze będę widoczne. + Prawda - Pliki zaczynające się kropkami będą ukrywane/wyświetlane razem z plikami +ukrytymi i systemowymi. - Default value: False (Dotfiles will always be shown.) + Domyślna wartość: Fałsz (pliki zawsze będą wyświetlane.) - This parameter can be changed via ~far:config~@FarConfig@ only. + Ten parametr można zmienić tylko w ~far:config~@FarConfig@. @Index diff --git a/far/FarRus.hlf.m4 b/far/FarRus.hlf.m4 index acb67d942a..28718e085d 100644 --- a/far/FarRus.hlf.m4 +++ b/far/FarRus.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Russian,Русский .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -380,10 +380,14 @@ $ #Команды управления панелями# Убрать/показать правую панель #Ctrl+F2# Изменить высоту панелей #Ctrl+Up,Ctrl+Down# Изменить высоту текущей панели #Ctrl+Shift+Up,Ctrl+Shift+Down# - Изменить ширину панелей #Ctrl+Left,Ctrl+Right# + Изменить высоту панелей мышью#Перетаскивание нижней границы панелей# + Изменить ширину панелей клавиатурой #Ctrl+Left,Ctrl+Right# (при пустой командной строке) + Изменить ширину панелей мышью#Перетаскивание границы между панелями# Восстановить ширину панелей по умолчанию #Ctrl+Numpad5# + или мышью #Двойной щелчок# по границе между панелями Восстановить высоту панелей по умолчанию #Ctrl+Alt+Numpad5# + или мышью #Двойной щелчок# по нижней границе панели Спрятать/Показать линейку функциональных клавиш #Ctrl+B# Переключение режима показа общего размера файлов и #Ctrl+Shift+S# свободного места в байтах (если можно) или с суффиксами К/М/Г/Т @@ -1187,6 +1191,27 @@ $ #Панель файлов# Для позиционирования на файл можно воспользоваться операцией ~быстрого поиска~@FastFind@ по первым буквам имени. + #Изменение размера панелей мышью# + + Вы можете изменять ширину и высоту панелей файлов с помощью мыши: + + #Изменение ширины:# + - ^Наведите курсор мыши на вертикальную границу между левой и правой панелями, чтобы увидеть визуальную подсказку о возможности изменения размера. + - ^Нажмите и перетащите границу влево или вправо для регулировки ширины панелей. + - ^Дважды щёлкните на вертикальной границе, чтобы восстановить равную ширину панелей по умолчанию (разделение 50/50). + - ^Нажмите #Esc# во время изменения размера, чтобы отменить и вернуться к исходной ширине панелей. + + #Изменение высоты:# + - ^Наведите курсор мыши на нижнюю границу панели, чтобы увидеть визуальную подсказку о возможности изменения размера. + - ^Нажмите и перетащите нижнюю границу вверх или вниз для регулировки высоты панели. + - ^Поведение изменения размера зависит от горизонтального положения мыши: + - ^Над ЛЕВОЙ панелью + Левая половина → Изменяется только ЛЕВАЯ панель + - ^Над ЛЕВОЙ панелью + Правая половина → Изменяются ОБЕ панели + - ^Над ПРАВОЙ панелью + Левая половина → Изменяются ОБЕ панели + - ^Над ПРАВОЙ панелью + Правая половина → Изменяется только ПРАВАЯ панель + - ^Дважды щёлкните на нижней границе, чтобы восстановить полную высоту панели. + - ^Нажмите #Esc# во время изменения размера, чтобы отменить и вернуться к исходной высоте панелей. + См. также список ~макроклавиш~@KeyMacroShellList@, доступных в панелях. diff --git a/far/FarSky.hlf.m4 b/far/FarSky.hlf.m4 index f7ec696ae0..539d0b36af 100644 --- a/far/FarSky.hlf.m4 +++ b/far/FarSky.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Slovak,Slovenčina .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -363,11 +363,15 @@ $ #Príkazy na ovládanie panelov# Schovaj/zobraz ľavý panel #Ctrl+F1# Schovaj/zobraz pravý panel #Ctrl+F2# Zmeň výšku panelov #Ctrl+Nahor,Ctrl+Nadol# - Change current panel height #Ctrl+Shift+Up,Ctrl+Shift+Down# - Zmeň šírku panelov #Ctrl+Doľ,Ctrl+Dopr# + Zmeň výšku aktuálneho panelu #Ctrl+Shift+Nahor,Ctrl+Shift+Nadol# + Zmeň výšku panelov myšou #Ťahanie dolnej hranice panelov# + Zmeň šírku panelov klávesnicou #Ctrl+Doľ,Ctrl+Dopr# (ak je prík. riadok prázdny) + Zmeň šírku panelov myšou #Ťahanie hranice medzi panelmi# Vráť štandartnú šírku panelov #Ctrl+NumKlav5# - Restore default panels height #Ctrl+Alt+Numpad5# + alebo myšou #Dvojklik# na hranicu medzi panelmi + Vráť štandartnú výšku panelov #Ctrl+Alt+NumKlav5# + alebo myšou #Dvojklik# na dolnú hranicu panelu Show/Hide functional key bar at the bottom line. #Ctrl+B# Toggle total and free size show mode #Ctrl+Shift+S# in bytes (if possible) or with size suffixes K/M/G/T @@ -1158,6 +1162,26 @@ ak bol predtým nastavený iný typ panelu. ~Rýchle vyhľadávanie~@FastFind@ možno použiť na nastavenie sa na požadovaný súbor použitím prvých písmen jeho mena. + #Zmena veľkosti panelov myšou# + + Môžete zmeniť šírku súborových panelov pomocou myši: + + - ^Navedite kurzor myši na hranicu medzi ľavým a pravým panelom, aby ste videli vizuálnu spätnú väzbu označujúcu oblasť, ktorú možno zmeniť. + - ^Kliknite a ťahajte hranicu doľava alebo doprava na úpravu šírky panelov. + - ^Dvakrát kliknite na hranicu na obnovenie predvolenej rovnakej šírky panelov (rozdelenie 50/50). + - ^Stlačte #Esc# počas zmeny veľkosti na zrušenie a návrat k pôvodnej šírke panelov. + + #Zmena výšky:# + - ^Navedite kurzor myši na spodnú hranicu panelu, aby ste videli vizuálnu spätnú väzbu označujúcu oblasť, ktorú možno zmeniť. + - ^Kliknite a ťahajte spodnú hranicu hore alebo dole na úpravu výšky panelu. + - ^Správanie zmeny veľkosti závisí od horizontálnej pozície myši: + - ^Nad spodnou hranicou ĽAVÉHO panelu v ľavej polovici panelu → Zmena veľkosti iba ĽAVÉHO panelu + - ^Nad spodnou hranicou ĽAVÉHO panelu v pravej polovici panelu → Zmena veľkosti OBOCH panelov + - ^Nad spodnou hranicou PRAVÉHO panelu v ľavej polovici panelu → Zmena veľkosti OBOCH panelov + - ^Nad spodnou hranicou PRAVÉHO panelu v pravej polovici panelu → Zmena veľkosti iba PRAVÉHO panelu + - ^Dvakrát kliknite na spodnú hranicu na obnovenie plnej výšky panelu. + - ^Stlačte #Esc# počas zmeny veľkosti na zrušenie a návrat k pôvodnej výške panelov. + See also the list of ~macro keys~@KeyMacroShellList@, available in the panels. diff --git a/far/FarUkr.hlf.m4 b/far/FarUkr.hlf.m4 index 692f931293..354596ec59 100644 --- a/far/FarUkr.hlf.m4 +++ b/far/FarUkr.hlf.m4 @@ -1,4 +1,4 @@ -m4_include(`farversion.m4')m4_dnl +m4_include(`farversion.m4')m4_dnl .Language=Ukrainian,Українська .Options CtrlColorChar=\ .Options CtrlStartPosChar=^ @@ -362,10 +362,14 @@ $ #Команди керування панелями# Прибрати/показати праву панель #Ctrl+F2# Змінити висоту панелей #Ctrl+Up, Ctrl+Down# Змінити висоту поточної панелі #Ctrl+Shift+Up,Ctrl+Shift+Down# - Змінити ширину #Ctrl+Left, Ctrl+Right# + Змінити висоту панелей мишею #Перетягування нижньої межі панелей# + Змінити ширину панелей клавіатурою #Ctrl+Left, Ctrl+Right# (при пустому командному рядку) + Змінити ширину панелей мишею #Перетягування межі між панелями# Відновити ширину панелей за замовчуванням #Ctrl+Numpad5# + або мишею #Подвійний клік# по межі між панелями Відновити висоту панелей за замовчуванням #Ctrl+Alt+Numpad5# + або мишею #Подвійний клік# по нижній межі панелі Сховати/Показати лінійку функціональних клавіш #Ctrl+B# Перемкнути показ загального та вільного розміру #Ctrl+Shift+S# у байтах (якщо можливо) або з суфіксами розміру K/M/G/T @@ -1180,6 +1184,27 @@ NTFS. Деякі файлові системи можуть не підтрим Для позиціонування на файл можна скористатися операцією ~швидкого пошуку~@FastFind@ по перших літерах імені. + #Зміна розміру панелей мишею# + + Ви можете змінювати ширину та висоту панелей файлів за допомогою миші: + + #Зміна ширини:# + - ^Наведіть курсор миші на вертикальну межу між лівою та правою панелями, щоб побачити візуальний зворотний зв'язок, що вказує на область зміни розміру. + - ^Клацніть та перетягніть межу ліворуч або праворуч для налаштування ширини панелей. + - ^Двічі клацніть на вертикальній межі, щоб відновити однакову ширину панелей за замовчуванням (розділення 50/50). + - ^Натисніть #Esc# під час зміни розміру, щоб скасувати та повернутися до початкової ширини панелей. + + #Зміна висоти:# + - ^Наведіть курсор миші на нижню межу панелі, щоб побачити візуальний зворотний зв'язок, що вказує на область зміни розміру. + - ^Клацніть та перетягніть нижню межу вгору або вниз для налаштування висоти панелі. + - ^Поведінка зміни розміру залежить від горизонтального положення миші: + - ^Над ЛІВОЮ панеллю в лівій половині панелі → Змінюється тільки ЛІВА панель + - ^Над ЛІВОЮ панеллю в правій половині панелі → Змінюються ОБІ панелі + - ^Над ПРАВОЮ панеллю в лівій половині панелі → Змінюються ОБІ панелі + - ^Над ПРАВОЮ панеллю в правій половині панелі → Змінюється тільки ПРАВА панель + - ^Двічі клацніть на нижній межі, щоб відновити повну висоту панелі. + - ^Натисніть #Esc# під час зміни розміру, щоб скасувати та повернутися до початкової висоти панелей. + Дивіться також список ~макроклавіш~@KeyMacroShellList@, доступних у панелях. diff --git a/far/changelog b/far/changelog index 95142287f4..6d7fbacdbf 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,82 @@ +-------------------------------------------------------------------------------- +yulian5 2025-10-26 21:00:00-06:00 - build 6579 + +1. New feature: panel resizing with mouse + +-------------------------------------------------------------------------------- +shmuel 2025-10-25 17:09:40+03:00 - build 6578 + +1. Add more stack operations to Macro-API engine. + +-------------------------------------------------------------------------------- +ssvine 2025-10-25 10:12:06+03:00 - build 6577 + +1. gh-1034: Refresh plugin panel after uploading a changed file in ProcessEnter. + +-------------------------------------------------------------------------------- +shmuel 2025-10-24 20:22:16+03:00 - build 6576 + +1. Add a few stack operations to Macro-API engine. + +-------------------------------------------------------------------------------- +drkns 2025-10-20 23:56:08+01:00 - build 6575 + +1. Clarify DI_COMBOBOX and DIF_DROPDOWNLIST behavior in corner cases. + +2. Refactoring. + +3. Warnings. + +-------------------------------------------------------------------------------- +rohitab 2025-10-20 08:50:41+11:00 - build 6574 + +1. gh-1032: Crash if size of name column is less than size of mark character. + +-------------------------------------------------------------------------------- +drkns 2025-10-16 23:42:46+01:00 - build 6573 + +1. Continue gh-1031. + Save the history if the user touched the control or if the control is visible. + +-------------------------------------------------------------------------------- +drkns 2025-10-16 20:22:16+01:00 - build 6572 + +1. gh-1031: History saved for hidden edit controls. + Only save the history if the user touched the control. + +2. Minor fix in color processing. + +-------------------------------------------------------------------------------- +zg 2025-10-05 23:11:22+03:00 - build 6571 + +1. selection drawn incorrectly in viewer in dump mode. + +-------------------------------------------------------------------------------- +drkns 2025-10-04 21:05:17+01:00 - build 6570 + +1. gh-939: ECSTATE_SAVED / ECSTATE_MODIFIED changed their meaning. + The original meaning restored (more or less). + +-------------------------------------------------------------------------------- +drkns 2025-10-04 00:00:33+01:00 - build 6569 + +1. Refactoring. + +2. More ASAN tests. + +3. Reorganize headers. + +-------------------------------------------------------------------------------- +drkns 2025-10-03 20:47:49+01:00 - build 6568 + +1. gh-1022: crash on smb share. + This was already fixed in 1805 and broken again in 5838. + +-------------------------------------------------------------------------------- +drkns 2025-10-03 11:10:57+01:00 - build 6567 + +1. Correction of 6549 for old OSes. + -------------------------------------------------------------------------------- rohitab 2025-10-01 13:36:49+10:00 - build 6566 diff --git a/far/farcolor.hpp b/far/farcolor.hpp index e5fa649ab6..2a3eaa78b8 100644 --- a/far/farcolor.hpp +++ b/far/farcolor.hpp @@ -212,6 +212,7 @@ enum PaletteColors COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON, COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON, + COL_PANELDRAGBORDER, COL_LASTPALETTECOLOR }; diff --git a/far/farlang.templ.m4 b/far/farlang.templ.m4 index 2b96124427..5c8811a5d9 100644 --- a/far/farlang.templ.m4 +++ b/far/farlang.templ.m4 @@ -18791,6 +18791,21 @@ MSetColorPanelDragging "Tempiamas tekstas" upd:"Dragging text" +MSetColorPanelDraggingBorder +"Граница перетаскивания" +"Dragging border" +"Tažená hranice" +"Drag && Drop Border" +"Vonszolt szegély" +"Przeciągana krawędź" +"Texto arrastrado" +"Potiahnutý okraj" +"Spostamento Bordo" +"Межа перетягуванні" +"Мяжа пераносу" +"Tempiama riba" +upd:"Dragging border" + MSetColorPanelBox "Рамка" "Border" diff --git a/far/filelist.cpp b/far/filelist.cpp index 7e0870e726..24e59d789a 100644 --- a/far/filelist.cpp +++ b/far/filelist.cpp @@ -2842,7 +2842,19 @@ void FileList::ProcessEnter(bool EnableExec,bool SeparateWindow,bool EnableAssoc { int PutCode = Global->CtrlObject->Plugins->PutFiles(GetPluginHandle(), { &PanelItem.Item, 1 }, false, OPM_EDIT); if (PutCode == 1 || PutCode == 2) + { SetPluginModified(); + + Update(UPDATE_KEEP_SELECTION); + Redraw(); + const auto AnotherPanel = Parent()->GetAnotherPanel(this); + + if (AnotherPanel->GetMode() == panel_mode::NORMAL_PANEL) + { + AnotherPanel->Update(UPDATE_KEEP_SELECTION); + AnotherPanel->Redraw(); + } + } } } } @@ -8203,6 +8215,9 @@ void FileList::ShowSelectedSize() if (strSelStr.size() > AvailableWidth) inplace::truncate_right(strSelStr, AvailableWidth); } + // Cache the status text length for GetBottomStatusTextBounds + m_CachedStatusTextLength = static_cast(strSelStr.size()); + SetColor(COL_PANELSELECTEDINFO); GotoXY(static_cast(m_Where.left + BorderSize + (AvailableWidth - strSelStr.size()) / 2), m_Where.bottom - 2 * Global->Opt->ShowPanelStatus); Text(L' '); @@ -8214,7 +8229,10 @@ void FileList::ShowSelectedSize() void FileList::ShowTotalSize(const OpenPanelInfo &Info) { if (!Global->Opt->ShowPanelTotals && m_PanelMode == panel_mode::PLUGIN_PANEL && !(Info.Flags & OPIF_REALNAMES)) + { + InvalidateStatusTextCache(); return; + } const auto calc_total_string = [this, Info](bool ShowBytes) { @@ -8256,6 +8274,9 @@ void FileList::ShowTotalSize(const OpenPanelInfo &Info) const string_view TotalStrView = TotalStr; + // Cache the status text length for GetBottomStatusTextBounds + m_CachedStatusTextLength = static_cast(TotalStrView.size()); + SetColor(COL_PANELTOTALINFO); GotoXY(static_cast(m_Where.left + BorderSize + (AvailableWidth - TotalStrView.size()) / 2), m_Where.bottom); const auto BoxPos = TotalStrView.find(BoxSymbols[BS_H2]); @@ -9140,6 +9161,37 @@ void FileList::background_update() } +bool FileList::GetBottomStatusTextBounds(int& OutStartX, int& OutEndX) const +{ + OutStartX = -1; + OutEndX = -1; + + if (m_CachedStatusTextLength == -1) + { + return false; + } + + // Check if status text should be displayed + const bool hasSelectedFiles = m_SelFileCount > 0; + const bool shouldShowTotals = Global->Opt->ShowPanelTotals || Global->Opt->ShowPanelFree; + + if (!hasSelectedFiles && !shouldShowTotals) + { + return false; // No status text to display + } + + const int BorderSize = 1; + const int MarginSize = 1; + const auto AvailableWidth = static_cast(std::max(0, ObjWidth() - BorderSize * 2 - MarginSize * 2)); + + const auto statusTextLength = static_cast(m_CachedStatusTextLength); + + // Calculate the start and end positions for text status + OutStartX = m_Where.left + BorderSize + static_cast((AvailableWidth - statusTextLength) / 2); + OutEndX = OutStartX + static_cast(statusTextLength) - 1; + + return true; +} bool FileList::IsDizDisplayed() const { diff --git a/far/filelist.hpp b/far/filelist.hpp index b74083c033..b108f22cdf 100644 --- a/far/filelist.hpp +++ b/far/filelist.hpp @@ -198,6 +198,7 @@ class FileList final: public Panel int GetColumnsCount() const override; void SetReturnCurrentFile(bool Mode) override; void GetOpenPanelInfo(OpenPanelInfo *Info) const override; + bool GetBottomStatusTextBounds(int& OutStartX, int& OutEndX) const override; void SetPluginMode(std::unique_ptr&& PluginPanel, string_view PluginFile, bool SendOnFocus = false) override; size_t GetSelCount() const override; bool GetSelName(string *strName, string *strShortName = nullptr, os::fs::find_data *fd = nullptr) override; @@ -487,6 +488,10 @@ class FileList final: public Panel class background_updater; std::unique_ptr m_BackgroundUpdater; + + // Cached status text length for performance optimization + mutable int m_CachedStatusTextLength = -1; + void InvalidateStatusTextCache() const { m_CachedStatusTextLength = -1; } }; #endif // FILELIST_HPP_825FE8AE_1E34_4DFD_B167_2D6A121B1777 diff --git a/far/filepanels.cpp b/far/filepanels.cpp index 170544fde6..cae9bd9297 100644 --- a/far/filepanels.cpp +++ b/far/filepanels.cpp @@ -61,6 +61,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "diskmenu.hpp" #include "global.hpp" #include "keyboard.hpp" +#include "colormix.hpp" // Platform: #include "platform.env.hpp" @@ -387,6 +388,36 @@ bool FilePanels::ProcessKey(const Manager::Key& Key) { const auto LocalKey = Key(); + // Handle ESC key during resizing to cancel and revert + if (LocalKey == KEY_ESC) + { + if (m_MouseState == MouseState::Resizing) + { + // Cancel width resizing and revert to original state + Global->Opt->WidthDecrement = m_OriginalWidthDecrement; + m_MouseState = MouseState::None; + ClearWidthBorderFeedback(); + m_HoverStartTime = 0; + ResetAllMouseStates(); + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + return true; + } + else if (m_MouseState == MouseState::HeightResizing) + { + // Cancel height resizing and revert to original state + Global->Opt->LeftHeightDecrement = m_OriginalLeftHeightDecrement; + Global->Opt->RightHeightDecrement = m_OriginalRightHeightDecrement; + m_MouseState = MouseState::None; + ClearHeightBorderFeedback(); + m_HeightHoverStartTime = 0; + ResetAllMouseStates(); + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + return true; + } + } + if ( any_of(LocalKey, KEY_CTRLLEFT, KEY_CTRLRIGHT, KEY_CTRLNUMPAD4, KEY_CTRLNUMPAD6, @@ -1080,6 +1111,18 @@ void FilePanels::DisplayObject() if (RightPanel()->IsVisible()) RightPanel()->Show(); + // Draw the border feedback if currently resizing + if (m_MouseState == MouseState::Resizing) + { + DrawWidthBorderFeedback(false, true); + } + + // Draw the height border feedback if currently height resizing + if (m_MouseState == MouseState::HeightResizing) + { + DrawHeightBorderFeedback(false, true); + } + #else Panel *PassivePanel=nullptr; int PassiveIsLeftFlag=TRUE; @@ -1126,11 +1169,19 @@ void FilePanels::DisplayObject() #endif } -bool FilePanels::ProcessMouse(const MOUSE_EVENT_RECORD *MouseEvent) +bool FilePanels::ProcessMouse(const MOUSE_EVENT_RECORD* MouseEvent) { - if (!MouseEvent->dwMousePosition.Y) + // Cache essential inputs for better performance + // Defer expensive calculations until needed + const auto& pos = MouseEvent->dwMousePosition; + const DWORD btn = MouseEvent->dwButtonState; + const DWORD flags = MouseEvent->dwEventFlags; + auto& opts = Global->Opt; + + // 1) Far-style title‐bar click + if (pos.Y == 0) { - if (!Global->Opt->ShowColumnTitles) // Sort Mark letter in the menu area + if (!opts->ShowColumnTitles) // Sort Mark letter in the menu area { if (ActivePanel()->ProcessMouse(MouseEvent)) return true; @@ -1138,28 +1189,28 @@ bool FilePanels::ProcessMouse(const MOUSE_EVENT_RECORD *MouseEvent) return true; } - if ((MouseEvent->dwButtonState & 3) && !MouseEvent->dwEventFlags) + if ((btn & 3) && !flags) { - if (!MouseEvent->dwMousePosition.X) + if (pos.X == 0) ProcessKey(Manager::Key(KEY_CTRLO)); else - Global->Opt->ShellOptions(false, MouseEvent); - + opts->ShellOptions(false, MouseEvent); return true; } } - if (MouseEvent->dwButtonState&FROM_LEFT_2ND_BUTTON_PRESSED) + // 2) Middle‐click -> ENTER Key + if (btn & FROM_LEFT_2ND_BUTTON_PRESSED) { - if (!IsMouseButtonEvent(MouseEvent->dwEventFlags)) + if (!IsMouseButtonEvent(flags)) return true; int Key = KEY_ENTER; - if (MouseEvent->dwControlKeyState&SHIFT_PRESSED) + if (MouseEvent->dwControlKeyState & SHIFT_PRESSED) { Key |= KEY_SHIFT; } - if (MouseEvent->dwControlKeyState&(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + if (MouseEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) { Key |= KEY_CTRL; } @@ -1171,11 +1222,311 @@ bool FilePanels::ProcessMouse(const MOUSE_EVENT_RECORD *MouseEvent) return true; } + // 3) Continue/finish a Resizing operation + if (m_MouseState == MouseState::Resizing) + { + const bool leftPressed = (btn & FROM_LEFT_1ST_BUTTON_PRESSED) != 0; + if (leftPressed) + { + const int dx = pos.X - m_ResizeStartX; + const int newDec = m_ResizeStartWidthDecrement - dx; + const int halfXminus10 = ScrX / 2 - 10; // Calculate only when needed + const int clamped = std::clamp(newDec, -halfXminus10, halfXminus10); + if (opts->WidthDecrement != clamped) + { + opts->WidthDecrement = clamped; + Global->WindowManager->ResizeAllWindows(); + } + } + else + { + // mouse released -> stop resizing + m_MouseState = MouseState::None; + ClearWidthBorderFeedback(); + m_HoverStartTime = 0; + ResetAllMouseStates(); + } + return true; + } + + // 3a) Continue/finish a Height Resizing operation + if (m_MouseState == MouseState::HeightResizing) + { + const bool leftPressed = (btn & FROM_LEFT_1ST_BUTTON_PRESSED) != 0; + if (leftPressed) + { + const int dy = m_ResizeStartY - pos.Y; // Inverted: positive dy means mouse moved up (decrease height) + const auto leftPanel = LeftPanel(); + const auto rightPanel = RightPanel(); + const auto leftPanelPos = leftPanel->GetPosition(); + const auto rightPanelPos = rightPanel->GetPosition(); + + // Determine which panel(s) to resize based on mouse X position at start of resize + const int startX = m_ResizeStartX; + + // Calculate boundaries for each panel + const int leftPanelMidX = leftPanelPos.left + (leftPanelPos.right - leftPanelPos.left) / 2; + const int rightPanelMidX = rightPanelPos.left + (rightPanelPos.right - rightPanelPos.left) / 2; + + // First determine which panel the mouse is over + const bool overLeftPanel = (startX >= leftPanelPos.left && startX <= leftPanelPos.right); + const bool overRightPanel = (startX >= rightPanelPos.left && startX <= rightPanelPos.right); + + if (overLeftPanel) + { + // Mouse is over left panel + if (startX <= leftPanelMidX) + { + // Left half of left panel - resize left panel only + const int newLeftDec = m_ResizeStartLeftHeightDecrement + dy; + const int maxDec = ScrY - 7; + const int clampedLeft = std::clamp(newLeftDec, 0, maxDec); + if (opts->LeftHeightDecrement == clampedLeft) + return true; + + opts->LeftHeightDecrement = clampedLeft; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + } + else + { + // Right half of left panel (inner half, closer to center) - resize both panels + const int newLeftDec = m_ResizeStartLeftHeightDecrement + dy; + const int newRightDec = m_ResizeStartRightHeightDecrement + dy; + const int maxDec = ScrY - 7; + const int clampedLeft = std::clamp(newLeftDec, 0, maxDec); + const int clampedRight = std::clamp(newRightDec, 0, maxDec); + if (opts->LeftHeightDecrement == clampedLeft && opts->RightHeightDecrement == clampedRight) + return true; + + opts->LeftHeightDecrement = clampedLeft; + opts->RightHeightDecrement = clampedRight; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + } + } + else if (overRightPanel) + { + // Mouse is over right panel + if (startX < rightPanelMidX) + { + // Left half of right panel (inner half, closer to center) - resize both panels + const int newLeftDec = m_ResizeStartLeftHeightDecrement + dy; + const int newRightDec = m_ResizeStartRightHeightDecrement + dy; + const int maxDec = ScrY - 7; + const int clampedLeft = std::clamp(newLeftDec, 0, maxDec); + const int clampedRight = std::clamp(newRightDec, 0, maxDec); + if (opts->LeftHeightDecrement == clampedLeft && opts->RightHeightDecrement == clampedRight) + return true; + + opts->LeftHeightDecrement = clampedLeft; + opts->RightHeightDecrement = clampedRight; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + } + else + { + // Right half of right panel - resize right panel only + const int newRightDec = m_ResizeStartRightHeightDecrement + dy; + const int maxDec = ScrY - 7; + const int clampedRight = std::clamp(newRightDec, 0, maxDec); + if (opts->RightHeightDecrement == clampedRight) + return true; + + opts->RightHeightDecrement = clampedRight; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + } + } + } + else + { + // mouse released -> stop height resizing + m_MouseState = MouseState::None; + ClearHeightBorderFeedback(); + m_HeightHoverStartTime = 0; + ResetAllMouseStates(); + } + return true; + } + + // 4) Border interaction: hover, double‐click, start resize + // Check width border first, but only if NOT already in height resizing mode + const bool overWidthBorder = IsMouseOverPanelInnerBorder(MouseEvent); + const bool overHeightBorder = IsMouseOverPanelBottomBorder(MouseEvent); + + // Priority: if in height resizing mode, ignore width border + // If over both borders, prefer height border (bottom border takes priority) + const bool processWidthBorder = overWidthBorder && !overHeightBorder && + m_MouseState != MouseState::HeightHovering && + m_MouseState != MouseState::HeightResizing; + const bool processHeightBorder = overHeightBorder && + m_MouseState != MouseState::Hovering && + m_MouseState != MouseState::Resizing; + + if (processWidthBorder) + { + // 4a) Double‐click resets to center + if (flags & DOUBLE_CLICK) + { + m_MouseState = MouseState::None; + m_HoverStartTime = 0; + opts->WidthDecrement = 0; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + + // Final flush and reset after the refresh to ensure clean state + ResetWidthMouseStates(); + + // Consume the event completely to prevent propagation to panels + return true; + } + + // 4b) Hover (no button pressed) + const bool leftPressed = (btn & FROM_LEFT_1ST_BUTTON_PRESSED) != 0; + if (!leftPressed) + { + const DWORD now = GetTickCount(); + if (m_MouseState == MouseState::None) + { + if (m_HoverStartTime == 0) + { + m_HoverStartTime = now; + return true; + } + + const int hoverThreshold = 300; + if (now - m_HoverStartTime < hoverThreshold) + return true; + + m_MouseState = MouseState::Hovering; + DrawWidthBorderFeedback(true, false); + } + else if (m_MouseState == MouseState::Hovering) + { + DrawWidthBorderFeedback(true, false); + } + return true; + } + + // 4c) Begin resize on first click (no movement yet) + if (m_MouseState == MouseState::Hovering) + { + const bool moved = (flags & MOUSE_MOVED) != 0; + if (!moved) + { + m_MouseState = MouseState::Resizing; + m_ResizeStartX = pos.X; + m_ResizeStartWidthDecrement = opts->WidthDecrement; + m_OriginalWidthDecrement = opts->WidthDecrement; // Save for ESC cancellation + m_HoverStartTime = 0; + + // No ResetWidthMouseStates() here, as we are starting the resize + return true; + } + } + } + else if (m_MouseState == MouseState::Hovering && !overWidthBorder) + { + // left border, but moved off -> clear hover + m_MouseState = MouseState::None; + ClearWidthBorderFeedback(); + m_HoverStartTime = 0; + ResetWidthMouseStates(); + } + + // 4d) Height border interaction: hover, double‐click, start resize + if (processHeightBorder) + { + // 4d1) Double‐click resets to full height + if (flags & DOUBLE_CLICK) + { + m_MouseState = MouseState::None; + m_HeightHoverStartTime = 0; + opts->LeftHeightDecrement = 0; + opts->RightHeightDecrement = 0; + SetScreenPosition(); + Global->WindowManager->RefreshWindow(); + + // Final flush and reset after the refresh to ensure clean state + ResetHeightMouseStates(); + + // Consume the event completely to prevent propagation to panels + return true; + } + + // 4d2) Hover (no button pressed) + const bool leftPressed = (btn & FROM_LEFT_1ST_BUTTON_PRESSED) != 0; + if (!leftPressed) + { + const DWORD now = GetTickCount(); + if (m_MouseState == MouseState::None) + { + if (m_HeightHoverStartTime == 0) + { + m_HeightHoverStartTime = now; + return true; + } + + const int hoverThreshold = 300; + if (now - m_HeightHoverStartTime < hoverThreshold) + return true; + + m_MouseState = MouseState::HeightHovering; + DrawHeightBorderFeedback(true, false); + } + else if (m_MouseState == MouseState::HeightHovering) + { + DrawHeightBorderFeedback(true, false); + } + return true; + } + + // 4d3) Begin height resize on first click (no movement yet) + if (m_MouseState == MouseState::HeightHovering) + { + const bool moved = (flags & MOUSE_MOVED) != 0; + if (!moved) + { + m_MouseState = MouseState::HeightResizing; + m_ResizeStartX = pos.X; // Store X position to determine which panel(s) to resize + m_ResizeStartY = pos.Y; + m_ResizeStartLeftHeightDecrement = opts->LeftHeightDecrement; + m_ResizeStartRightHeightDecrement = opts->RightHeightDecrement; + m_OriginalLeftHeightDecrement = opts->LeftHeightDecrement; // Save for ESC cancellation + m_OriginalRightHeightDecrement = opts->RightHeightDecrement; // Save for ESC cancellation + m_HeightHoverStartTime = 0; + + // No ResetHeightMouseStates() here, as we are starting the resize + return true; + } + } + } + else if (m_MouseState == MouseState::HeightHovering && !overHeightBorder) + { + // left height border, but moved off -> clear hover + m_MouseState = MouseState::None; + ClearHeightBorderFeedback(); + m_HeightHoverStartTime = 0; + ResetHeightMouseStates(); + } + + // 5) Additional safeguard: Don't process double-clicks that might have been + // intended for border but are now over panel area due to resize + if ((flags & DOUBLE_CLICK) && IsMouseOverPanelInnerBorder(MouseEvent)) + { + // This is a double-click that should have been handled by border logic above + // but somehow reached here. Consume it to prevent unwanted panel actions. + return true; + } + if (!ActivePanel()->ProcessMouse(MouseEvent)) { - if (!PassivePanel()->ProcessMouse(MouseEvent)) - if (!m_windowKeyBar->ProcessMouse(MouseEvent)) - CmdLine->ProcessMouse(MouseEvent); + if (!PassivePanel()->ProcessMouse(MouseEvent) && + !m_windowKeyBar->ProcessMouse(MouseEvent)) + { + CmdLine->ProcessMouse(MouseEvent); + } ActivePanel()->SetCurPath(); } @@ -1183,6 +1534,290 @@ bool FilePanels::ProcessMouse(const MOUSE_EVENT_RECORD *MouseEvent) return true; } +bool FilePanels::IsMouseOverPanelInnerBorder(const MOUSE_EVENT_RECORD *MouseEvent) const +{ + const auto MouseX = MouseEvent->dwMousePosition.X; + const auto MouseY = MouseEvent->dwMousePosition.Y; + + // Cache frequently accessed values + const auto& opt = Global->Opt; + const auto BorderX = ScrX / 2 - opt->WidthDecrement; + + // Check a 2-column wide area for the border between panels + if (!(MouseX >= BorderX && MouseX <= BorderX + 1)) + return false; + + // Exclude scroll bar areas from border detection to give scroll bars priority + // But allow 1 additional row below the scrollbar as grip area for width resizing + // Somehow it works only for hightlighting - need to fix + if (opt->ShowPanelScrollbar) + { + const auto leftPanel = LeftPanel(); + const auto leftPanelPos = leftPanel->GetPosition(); + + // Left panel - border (BorderX) is on the right side - we need to avoid the scrollbar area + if (!leftPanel->IsVisible() || MouseX != BorderX) + return true; + + if (MouseX != leftPanelPos.right || leftPanel->GetType() != panel_type::FILE_PANEL) + return true; + + const auto filePanel = std::dynamic_pointer_cast(leftPanel); + if (!filePanel) + return true; + + const int height = leftPanelPos.bottom - leftPanelPos.top - 1; + if (filePanel->GetFileCount() <= static_cast(height)) + return true; + + const auto scrollBarStartY = leftPanelPos.top + 1 + (opt->ShowColumnTitles ? 1 : 0); + // There is conflict with scrollbar area, let's grab one cell from it for the better grip + const auto scrollBarEndY = scrollBarStartY + (height - (opt->ShowColumnTitles ? 1 : 0)) - 1; + if (MouseY >= scrollBarStartY && MouseY < scrollBarEndY) + return false; // This is scroll bar area, not border for width resizing + + // Right panel - scrollbar area doesn't conflict with border (BorderX + 1) - do nothing + + return true; // not scrollbar area or grip area above/below scrollbar + } + + return true; +} + +bool FilePanels::IsMouseOverPanelBottomBorder(const MOUSE_EVENT_RECORD *MouseEvent) const +{ + const auto MouseX = MouseEvent->dwMousePosition.X; + const auto MouseY = MouseEvent->dwMousePosition.Y; + + // Cache frequently accessed values + const auto leftPanel = LeftPanel(); + const auto rightPanel = RightPanel(); + const auto leftPanelPos = leftPanel->GetPosition(); + const auto rightPanelPos = rightPanel->GetPosition(); + + // Check if mouse is over the bottom border of either panel + const auto leftBottomY = leftPanelPos.bottom; + const auto rightBottomY = rightPanelPos.bottom; + + // Left panel bottom border + if (leftPanel->IsVisible() && MouseY == leftBottomY && + MouseX >= leftPanelPos.left && MouseX <= leftPanelPos.right) + { + return true; + } + + // Right panel bottom border + if (rightPanel->IsVisible() && MouseY == rightBottomY && + MouseX >= rightPanelPos.left && MouseX <= rightPanelPos.right) + { + return true; + } + + return false; +} + +void FilePanels::DrawWidthBorderFeedback(bool IsHovering, bool IsDragging) +{ + // Show visual feedback on hover and during dragging + if (!IsHovering && !IsDragging) + return; + + // Cache frequently accessed pointers and values + const auto leftPanel = LeftPanel(); + const auto rightPanel = RightPanel(); + const auto leftPanelPos = leftPanel->GetPosition(); + const auto rightPanelPos = rightPanel->GetPosition(); + const auto& opt = Global->Opt; + + const auto BorderX = ScrX / 2 - opt->WidthDecrement; + const auto borderX = static_cast(BorderX); + + const auto BorderColor = colors::PaletteColorToFarColor(COL_PANELDRAGBORDER); + + static constexpr wchar_t BorderChar[] = L"║"; + + // Draw full height border feedback + const auto StartY = 1; + const auto EndY = ScrY - 2; + + const int borderXPlus = borderX + 1; + const bool drawLeft = leftPanel->IsVisible(); + const bool drawRight = rightPanel->IsVisible() && borderX < ScrX - 1; + + // Calculate actual drawing boundaries based on panel heights + const auto leftPanelStartY = std::max(StartY, static_cast(leftPanelPos.top + 1)); + const auto leftPanelEndY = std::min(EndY, static_cast(leftPanelPos.bottom)); + const auto rightPanelStartY = std::max(StartY, static_cast(rightPanelPos.top + 1)); + const auto rightPanelEndY = std::min(EndY, static_cast(rightPanelPos.bottom)); + + // Helper function to get scroll bar boundaries for a panel + auto getScrollBarBounds = [&](const panel_ptr& panel) -> std::tuple { + if (!opt->ShowPanelScrollbar || !panel->IsVisible() || panel->GetType() != panel_type::FILE_PANEL) + return {false, 0, 0}; + + const auto filePanel = std::dynamic_pointer_cast(panel); + if (!filePanel) return {false, 0, 0}; + + const auto panelPos = panel->GetPosition(); + const bool hasScrollBar = filePanel->GetFileCount() > static_cast(panelPos.bottom - panelPos.top - 1); + + if (!hasScrollBar) return {false, 0, 0}; + + const auto scrollBarStartY = panelPos.top + 1 + (opt->ShowColumnTitles ? 1 : 0); + // There is conflict with scrollbar area, let's grab one cell from it for the better grip + const auto scrollBarEndY = scrollBarStartY + (panelPos.bottom - panelPos.top - 2 - (opt->ShowColumnTitles ? 1 : 0)) - 1; + + return {true, scrollBarStartY, scrollBarEndY}; + }; + + const auto [leftHasScrollBar, leftScrollBarStart, leftScrollBarEnd] = getScrollBarBounds(LeftPanel()); + + // Draw borders for full height, respecting panel boundaries and scrollbars + for (int y = StartY; y < EndY; ++y) + { + if (drawLeft && y >= leftPanelStartY && y < leftPanelEndY) + { + bool skipForScrollBar = leftHasScrollBar && (borderX == leftPanelPos.right) && + (y >= leftScrollBarStart && y < leftScrollBarEnd); + + if (!skipForScrollBar) + { + GotoXY(borderX, y); + Text({ borderX, y }, BorderColor, BorderChar); + } + } + if (drawRight && y >= rightPanelStartY && y < rightPanelEndY) + { + GotoXY(borderXPlus, y); + Text({ borderXPlus, y }, BorderColor, BorderChar); + } + } + + m_LastWidthFeedbackY = StartY; // Mark that width feedback is drawn +} + +void FilePanels::ClearWidthBorderFeedback() +{ + if (m_LastWidthFeedbackY == -1) + return; + + // Clear feedback by refreshing the window + Global->WindowManager->RefreshWindow(); + m_LastWidthFeedbackY = -1; +} + +std::pair FilePanels::DetermineHeightHighlightPanels(bool IsDragging, const rectangle& leftPanelPos, const rectangle& rightPanelPos) +{ + const int mouseX = IsDragging ? m_ResizeStartX : IntKeyState.MousePos.x; + const int leftPanelMidX = leftPanelPos.left + (leftPanelPos.right - leftPanelPos.left) / 2; + const int rightPanelMidX = rightPanelPos.left + (rightPanelPos.right - rightPanelPos.left) / 2; + + bool highlightLeft = false; + bool highlightRight = false; + + const bool overLeftPanel = (mouseX >= leftPanelPos.left && mouseX <= leftPanelPos.right); + const bool overRightPanel = (mouseX >= rightPanelPos.left && mouseX <= rightPanelPos.right); + + if (overLeftPanel) + { + if (mouseX <= leftPanelMidX) + { + highlightLeft = true; + } + else + { + highlightLeft = true; + highlightRight = true; + } + } + else if (overRightPanel) + { + if (mouseX < rightPanelMidX) + { + highlightLeft = true; + highlightRight = true; + } + else + { + highlightRight = true; + } + } + + return { highlightLeft, highlightRight }; +} + +void FilePanels::DrawPanelBottomBorder(const std::shared_ptr& panel, const rectangle& panelPos, const FarColor& BorderColor, const wchar_t* BorderChar) +{ + if (!panel->IsVisible()) + return; + + const auto bottomY = panelPos.bottom; + int statusStartX = -1, statusEndX = -1; + + if (const auto fileListPanel = std::dynamic_pointer_cast(panel)) + { + fileListPanel->GetBottomStatusTextBounds(statusStartX, statusEndX); + } + + if (statusStartX != -1 && statusEndX != -1) + { + // Draw border segments around status text + for (int x = panelPos.left + 1; x < statusStartX; ++x) + { + GotoXY(x, bottomY); + Text({ x, bottomY }, BorderColor, BorderChar); + } + + for (int x = statusEndX + 3; x < panelPos.right; ++x) + { + GotoXY(x, bottomY); + Text({ x, bottomY }, BorderColor, BorderChar); + } + } + else + { + // Draw full bottom border (except corners) + for (int x = panelPos.left + 1; x < panelPos.right; ++x) + { + GotoXY(x, bottomY); + Text({ x, bottomY }, BorderColor, BorderChar); + } + } +} + +void FilePanels::DrawHeightBorderFeedback(bool IsHovering, bool IsDragging) +{ + if (!IsHovering && !IsDragging) + return; + + const auto leftPanel = LeftPanel(); + const auto rightPanel = RightPanel(); + const auto leftPanelPos = leftPanel->GetPosition(); + const auto rightPanelPos = rightPanel->GetPosition(); + + const auto BorderColor = colors::PaletteColorToFarColor(COL_PANELDRAGBORDER); + static constexpr wchar_t BorderChar[] = L"═"; + + const auto [highlightLeft, highlightRight] = DetermineHeightHighlightPanels(IsDragging, leftPanelPos, rightPanelPos); + + if (highlightLeft) + DrawPanelBottomBorder(leftPanel, leftPanelPos, BorderColor, BorderChar); + + if (highlightRight) + DrawPanelBottomBorder(rightPanel, rightPanelPos, BorderColor, BorderChar); + + m_LastHeightFeedbackX = leftPanelPos.left; // Mark that height feedback is drawn +} +void FilePanels::ClearHeightBorderFeedback() +{ + if (m_LastHeightFeedbackX == -1) + return; + + // Clear feedback by refreshing the window + Global->WindowManager->RefreshWindow(); + m_LastHeightFeedbackX = -1; +} + void FilePanels::ShowConsoleTitle() { ActivePanel()->RefreshTitle(); @@ -1302,3 +1937,36 @@ void FilePanels::Show() TopMenuBar->Show(); } } + +void FilePanels::ResetAllMouseStates() +{ + FlushInputBuffer(); + + // Reset Far's internal mouse state tracking + IntKeyState.MouseButtonState = 0; + IntKeyState.PrevMouseButtonState = 0; + IntKeyState.PrevLButtonPressed = false; + IntKeyState.PrevRButtonPressed = false; + IntKeyState.PrevMButtonPressed = false; + IntKeyState.MouseEventFlags = 0; + IntKeyState.PreMouseEventFlags = 0; + + // Reset drag-and-drop state + Panel::EndDrag(); +} + +void FilePanels::ResetWidthMouseStates() const +{ + // Reset width-specific states only + m_HoverStartTime = 0; +} + +void FilePanels::ResetHeightMouseStates() const +{ + // Reset height-specific states only + m_HeightHoverStartTime = 0; + m_LastHeightFeedbackX = -1; + m_ResizeStartY = 0; + m_ResizeStartLeftHeightDecrement = 0; + m_ResizeStartRightHeightDecrement = 0; +} diff --git a/far/filepanels.hpp b/far/filepanels.hpp index 4d9c058072..a190e999bc 100644 --- a/far/filepanels.hpp +++ b/far/filepanels.hpp @@ -92,6 +92,8 @@ class FilePanels final: public window, public ViewerContainer bool IsLeftActive() const { return m_ActivePanelIndex == panel_left; } bool IsRightActive() const { return m_ActivePanelIndex == panel_right; } + // Check if currently in resizing mode (for macro ESC key handling) + bool IsInResizingMode() const { return m_MouseState == MouseState::Resizing || m_MouseState == MouseState::HeightResizing; } panel_ptr GetAnotherPanel(panel_ptr Current) const { return GetAnotherPanel(Current.get()); } panel_ptr GetAnotherPanel(const Panel* Current) const; @@ -111,6 +113,24 @@ class FilePanels final: public window, public ViewerContainer static void SetPassivePanelInternal(panel_ptr ToBePassive); void SetActivePanelInternal(panel_ptr ToBeActive); + // Panel border mouse handling for resizing + bool IsMouseOverPanelInnerBorder(const MOUSE_EVENT_RECORD *MouseEvent) const; + void DrawWidthBorderFeedback(bool IsHovering, bool IsDragging); + void ClearWidthBorderFeedback(); + void ResetAllMouseStates(); + void ResetWidthMouseStates() const; + + // Panel height resizing functions + bool IsMouseOverPanelBottomBorder(const MOUSE_EVENT_RECORD *MouseEvent) const; + void DrawHeightBorderFeedback(bool IsHovering, bool IsDragging); + void ClearHeightBorderFeedback(); + void ResetHeightMouseStates() const; + + // Helper functions for height border feedback + std::pair DetermineHeightHighlightPanels(bool IsDragging, const rectangle& leftPanelPos, const rectangle& rightPanelPos); + void DrawPanelBottomBorder(const std::shared_ptr& panel, const rectangle& panelPos, const FarColor& BorderColor, const wchar_t* BorderChar); + + panel_ptr CreatePanel(panel_type Type); void SetPanelPositions(bool LeftFullScreen, bool RightFullScreen) const; int SetAnhoterPanelFocus(); @@ -139,6 +159,34 @@ class FilePanels final: public window, public ViewerContainer m_Panels[panels_count]; panel_index m_ActivePanelIndex; + + // Panel resizing state + mutable int m_ResizeStartX = 0; + mutable int m_ResizeStartWidthDecrement = 0; + mutable int m_LastWidthFeedbackY = -1; + mutable DWORD m_HoverStartTime = 0; // For hover delay + + // Panel height resizing state + mutable int m_ResizeStartY = 0; + mutable int m_ResizeStartLeftHeightDecrement = 0; + mutable int m_ResizeStartRightHeightDecrement = 0; + mutable int m_LastHeightFeedbackX = -1; + mutable DWORD m_HeightHoverStartTime = 0; + + // Original state for ESC cancellation + mutable int m_OriginalWidthDecrement = 0; + mutable int m_OriginalLeftHeightDecrement = 0; + mutable int m_OriginalRightHeightDecrement = 0; + + enum class MouseState + { + None, + Hovering, + Resizing, + HeightHovering, + HeightResizing + }; + mutable MouseState m_MouseState = MouseState::None; }; #endif // FILEPANELS_HPP_B2D6495E_DA8B_4E72_80F5_37282A14C316 diff --git a/far/keyboard.cpp b/far/keyboard.cpp index cf20ffce17..f3ef49684a 100644 --- a/far/keyboard.cpp +++ b/far/keyboard.cpp @@ -673,6 +673,13 @@ static bool ProcessMacros(INPUT_RECORD* rec, DWORD& Result) if (const auto MacroKey = Global->CtrlObject->Macro.GetKey()) { + // Block ESC key from being processed by macros during panel resizing + // ESC should only be handled by FilePanels::ProcessKey to cancel resizing + if (MacroKey == KEY_ESC && Global->CtrlObject->Cp()->IsInResizingMode()) + { + return false; // Prevent ESC macro from executing during resizing + } + static int LastMsClickMacroKey = 0; if (const auto MsClickKey = KeyMsClickToButtonState(MacroKey)) { @@ -913,6 +920,13 @@ static DWORD GetInputRecordImpl(INPUT_RECORD *rec,bool ExcludeMacro,bool Process if (NotMacros || ExcludeMacro) return CalcKey; + // Block ESC key from being processed by macros during panel resizing + // ESC should only be handled by FilePanels::ProcessKey to cancel resizing + if (CalcKey == KEY_ESC && Global->CtrlObject && Global->CtrlObject->Cp() && Global->CtrlObject->Cp()->IsInResizingMode()) + { + return CalcKey; // Don't process ESC through macros during resizing, consume the event + } + const FAR_INPUT_RECORD irec{ CalcKey, *rec }; if (!Global->CtrlObject || !Global->CtrlObject->Macro.ProcessEvent(&irec)) return CalcKey; @@ -1075,6 +1089,14 @@ static DWORD GetInputRecordImpl(INPUT_RECORD *rec,bool ExcludeMacro,bool Process console.ReadOneInput(*rec); + // Block ALL keyboard input during panel resizing (except ESC which is handled in FilePanels::ProcessKey) + // This check is AFTER ReadOneInput to ensure the event is consumed from the queue + if (rec->EventType == KEY_EVENT && CalcKey != KEY_NONE && Global->CtrlObject && Global->CtrlObject->Cp() && + Global->CtrlObject->Cp()->IsInResizingMode() && CalcKey != KEY_ESC) + { + return KEY_NONE; // Block all other keyboard keys during resizing + } + if (rec->EventType == FOCUS_EVENT) { return ProcessFocusEvent(rec->Event.FocusEvent.bSetFocus != FALSE); @@ -1280,6 +1302,8 @@ bool CheckForEscSilent() return true; } + SCOPED_ACTION(auto)(message_manager::instance().suppressor()); + INPUT_RECORD rec; bool Processed = true; /* TODO: Здесь, в общем то - ХЗ, т.к. diff --git a/far/palette.cpp b/far/palette.cpp index bf1235d9f6..5e2ab8e85b 100644 --- a/far/palette.cpp +++ b/far/palette.cpp @@ -209,6 +209,7 @@ Init[] {L"WarnDialog.DefaultButton.Selected"sv, F_BLACK|B_LIGHTGRAY, }, // COL_WARNDIALOGSELECTEDDEFAULTBUTTON, {L"WarnDialog.DefaultButton.Highlight"sv, F_YELLOW|B_RED, }, // COL_WARNDIALOGHIGHLIGHTDEFAULTBUTTON, {L"WarnDialog.DefaultButton.Highlight.Selected"sv, F_YELLOW|B_LIGHTGRAY, }, // COL_WARNDIALOGHIGHLIGHTSELECTEDDEFAULTBUTTON, + {L"Panel.DragBorder"sv, F_YELLOW|B_BLUE, }, // COL_PANELDRAGBORDER, }; static_assert(std::size(Init) == COL_LASTPALETTECOLOR); diff --git a/far/panel.hpp b/far/panel.hpp index 5d910ba817..82c26579dd 100644 --- a/far/panel.hpp +++ b/far/panel.hpp @@ -158,6 +158,7 @@ class Panel: public ScreenObject, public std::enable_shared_from_this virtual void SetReturnCurrentFile(bool Mode) {} virtual void QViewDelTempName() {} virtual void GetOpenPanelInfo(OpenPanelInfo* Info) const; + virtual bool GetBottomStatusTextBounds(int& OutStartX, int& OutEndX) const { OutStartX = -1; OutEndX = -1; return false; } virtual void SetPluginMode(std::unique_ptr&& hPlugin, string_view PluginFile, bool SendOnFocus = false) {} virtual void SetPluginModified() {} virtual bool ProcessPluginEvent(int Event,void *Param) {return false;} diff --git a/far/setcolor.cpp b/far/setcolor.cpp index 355abbdb70..9a9809328e 100644 --- a/far/setcolor.cpp +++ b/far/setcolor.cpp @@ -313,6 +313,7 @@ void SetColors() { lng::MSetColorPanelHighlightedInfo, COL_PANELINFOTEXT }, { lng::MSetColorPanelDragging, COL_PANELDRAGTEXT }, { lng::MSetColorPanelBox, COL_PANELBOX }, + { lng::MSetColorPanelDraggingBorder, COL_PANELDRAGBORDER, {}, { COL_PANELDRAGTEXT } }, { lng::MSetColorPanelNormalCursor, COL_PANELCURSOR, {}, { COL_PANELTEXT } }, { lng::MSetColorPanelSelectedCursor, COL_PANELSELECTEDCURSOR, {}, { COL_PANELCURSOR, COL_PANELSELECTEDTEXT, COL_PANELTEXT } }, { lng::MSetColorPanelNormalTitle, COL_PANELTITLE }, diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 24d302ea4b..f1f8de3e8b 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -6566 +6579