mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Preventing session tabs flicker with large number of sessions
Source commit: 03cfa5b1411b866567a4b71c69ff7c15ce61556e
This commit is contained in:
@@ -584,7 +584,7 @@ void __fastcall TCustomScpExplorerForm::TerminalChanged()
|
||||
InitStatusBar();
|
||||
}
|
||||
|
||||
DoTerminalListChanged(false);
|
||||
DoTerminalListChanged();
|
||||
|
||||
if (ManagedTerminal != NULL)
|
||||
{
|
||||
@@ -6235,68 +6235,64 @@ void __fastcall TCustomScpExplorerForm::NeedSession(bool ReloadSessions)
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::DoTerminalListChanged(bool Force)
|
||||
void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
|
||||
{
|
||||
TStrings * TerminalList = TTerminalManager::Instance()->TerminalList;
|
||||
int ActiveTerminalIndex = TTerminalManager::Instance()->ActiveTerminalIndex;
|
||||
|
||||
Configuration->Usage->SetMax(L"MaxOpenedSessions", TerminalList->Count);
|
||||
|
||||
bool ListChanged = Force || (TerminalList->Count + 1 != SessionsPageControl->PageCount);
|
||||
if (!ListChanged)
|
||||
SendMessage(SessionsPageControl->Handle, WM_SETREDRAW, 0, 0);
|
||||
try
|
||||
{
|
||||
int Index = 0;
|
||||
while (!ListChanged && (Index < TerminalList->Count))
|
||||
while ((SessionsPageControl->PageCount > TerminalList->Count + 1) ||
|
||||
// Clear the design time unthemed tab
|
||||
((SessionsPageControl->PageCount > 0) &&
|
||||
(dynamic_cast<TThemeTabSheet *>(SessionsPageControl->Pages[SessionsPageControl->PageCount - 1]) == NULL)))
|
||||
{
|
||||
ListChanged =
|
||||
(GetSessionTabTerminal(SessionsPageControl->Pages[Index]) != TerminalList->Objects[Index]) ||
|
||||
(SessionsPageControl->Pages[Index]->Caption != TerminalList->Strings[Index]);
|
||||
Index++;
|
||||
delete SessionsPageControl->Pages[SessionsPageControl->PageCount - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (ListChanged)
|
||||
{
|
||||
SendMessage(SessionsPageControl->Handle, WM_SETREDRAW, 0, 0);
|
||||
try
|
||||
for (int Index = 0; Index <= TerminalList->Count; Index++)
|
||||
{
|
||||
FSessionColors->Clear();
|
||||
|
||||
AddFixedSessionImages();
|
||||
|
||||
while (SessionsPageControl->PageCount > 0)
|
||||
TTabSheet * TabSheet;
|
||||
if (Index >= SessionsPageControl->PageCount)
|
||||
{
|
||||
delete SessionsPageControl->Pages[0];
|
||||
TabSheet = new TThemeTabSheet(SessionsPageControl);
|
||||
TabSheet->PageControl = SessionsPageControl;
|
||||
}
|
||||
else
|
||||
{
|
||||
TabSheet = SessionsPageControl->Pages[Index];
|
||||
}
|
||||
|
||||
for (int Index = 0; Index < TerminalList->Count; Index++)
|
||||
if (Index < TerminalList->Count)
|
||||
{
|
||||
TThemeTabSheet * TabSheet = new TThemeTabSheet(SessionsPageControl);
|
||||
TabSheet->Caption = TerminalList->Strings[Index];
|
||||
TTerminal * Terminal = dynamic_cast<TTerminal *>(TerminalList->Objects[Index]);
|
||||
TabSheet->Tag = reinterpret_cast<int>(Terminal);
|
||||
TabSheet->PageControl = SessionsPageControl;
|
||||
|
||||
UpdateSessionTab(TabSheet);
|
||||
}
|
||||
|
||||
TTabSheet * TabSheet = new TTabSheet(SessionsPageControl);
|
||||
TabSheet->PageControl = SessionsPageControl;
|
||||
TabSheet->ImageIndex = FNewSessionTabImageIndex;
|
||||
UpdateNewSessionTab();
|
||||
}
|
||||
__finally
|
||||
{
|
||||
SendMessage(SessionsPageControl->Handle, WM_SETREDRAW, 1, 0);
|
||||
else
|
||||
{
|
||||
TabSheet->ImageIndex = FNewSessionTabImageIndex;
|
||||
TabSheet->Tag = 0; // not really needed
|
||||
// We know that we are at the last page, sotherwise we could not call this (it assumes that new session tab is the last one)
|
||||
UpdateNewSessionTab();
|
||||
}
|
||||
}
|
||||
}
|
||||
__finally
|
||||
{
|
||||
SendMessage(SessionsPageControl->Handle, WM_SETREDRAW, 1, 0);
|
||||
}
|
||||
|
||||
SessionsPageControl->ActivePageIndex = ActiveTerminalIndex;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::TerminalListChanged(TObject * /*Sender*/)
|
||||
{
|
||||
DoTerminalListChanged(false);
|
||||
DoTerminalListChanged();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::UpdateNewSessionTab()
|
||||
@@ -6324,11 +6320,11 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet)
|
||||
dynamic_cast<TManagedTerminal *>(GetSessionTabTerminal(TabSheet));
|
||||
if (DebugAlwaysTrue(ManagedTerminal != NULL))
|
||||
{
|
||||
TColor Color =
|
||||
(ManagedTerminal == FTerminal) ? FSessionColor : ManagedTerminal->StateData->Color;
|
||||
|
||||
TColor Color = (ManagedTerminal == FTerminal) ? FSessionColor : ManagedTerminal->StateData->Color;
|
||||
TabSheet->ImageIndex = AddSessionColor(Color);
|
||||
TabSheet->Caption = TTerminalManager::Instance()->GetTerminalTitle(ManagedTerminal, true);
|
||||
|
||||
UnicodeString TabCaption = TTerminalManager::Instance()->GetTerminalTitle(ManagedTerminal, true);
|
||||
TabSheet->Caption = TabCaption;
|
||||
|
||||
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(TabSheet);
|
||||
if (DebugAlwaysTrue(ThemeTabSheet != NULL))
|
||||
@@ -6356,7 +6352,7 @@ bool __fastcall TCustomScpExplorerForm::SessionTabSwitched()
|
||||
}
|
||||
__finally
|
||||
{
|
||||
DoTerminalListChanged(false);
|
||||
DoTerminalListChanged();
|
||||
}
|
||||
|
||||
FSessionsPageControlNewSessionTime = Now();
|
||||
@@ -6599,7 +6595,7 @@ void __fastcall TCustomScpExplorerForm::UpdatePixelsPerInchMainWindowCounter()
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::StartingDisconnected()
|
||||
{
|
||||
DoTerminalListChanged(true);
|
||||
DoTerminalListChanged();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::PopupTrayBalloon(TTerminal * Terminal,
|
||||
@@ -8592,8 +8588,9 @@ void __fastcall TCustomScpExplorerForm::UpdateImages()
|
||||
void __fastcall TCustomScpExplorerForm::CMDpiChanged(TMessage & Message)
|
||||
{
|
||||
TForm::Dispatch(&Message);
|
||||
// regenerate session images
|
||||
DoTerminalListChanged(true);
|
||||
FSessionColors->Clear();
|
||||
AddFixedSessionImages();
|
||||
RegenerateSessionColorsImageList(FSessionColors, FSessionColorMaskImageIndex);
|
||||
UpdateImages();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -9414,8 +9411,7 @@ int __fastcall TCustomScpExplorerForm::AddSessionColor(TColor Color)
|
||||
{
|
||||
if (Color != 0)
|
||||
{
|
||||
AddSessionColorImage(FSessionColors, Color, FSessionColorMaskImageIndex);
|
||||
return FSessionColors->Count - 1;
|
||||
return GetSessionColorImage(FSessionColors, Color, FSessionColorMaskImageIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -596,7 +596,7 @@ protected:
|
||||
void * Arg);
|
||||
void __fastcall AnyInternalEditorModified(TObject * Sender, bool & Modified);
|
||||
virtual void __fastcall StartingDisconnected();
|
||||
void __fastcall DoTerminalListChanged(bool Force);
|
||||
void __fastcall DoTerminalListChanged();
|
||||
void __fastcall NeedSession(bool ReloadSessions);
|
||||
bool __fastcall DraggingAllFilesFromDirView(TOperationSide Side, TStrings * FileList);
|
||||
bool __fastcall SelectedAllFilesInDirView(TCustomDirView * DView);
|
||||
|
||||
@@ -358,8 +358,7 @@ int __fastcall TLoginDialog::GetSessionImageIndex(TSessionData * Data)
|
||||
int Result;
|
||||
if (Data->Color != 0)
|
||||
{
|
||||
AddSessionColorImage(SessionTree->Images, static_cast<TColor>(Data->Color), SiteColorMaskImageIndex);
|
||||
Result = SessionTree->Images->Count - 1;
|
||||
Result = GetSessionColorImage(SessionTree->Images, static_cast<TColor>(Data->Color), SiteColorMaskImageIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -107,7 +107,7 @@ void __fastcall TSiteAdvancedDialog::InitControls()
|
||||
UpdateNavigationTree();
|
||||
|
||||
SelectScaledImageList(ColorImageList);
|
||||
SetSessionColor((TColor)0);
|
||||
FColor = TColor();
|
||||
|
||||
MenuButton(PrivateKeyToolsButton);
|
||||
}
|
||||
@@ -404,7 +404,7 @@ void __fastcall TSiteAdvancedDialog::LoadSession()
|
||||
GetEncryptKeyEdit()->Text = FSessionData->EncryptKey;
|
||||
|
||||
// color
|
||||
SetSessionColor((TColor)FSessionData->Color);
|
||||
FColor = (TColor)FSessionData->Color;
|
||||
}
|
||||
|
||||
UpdateControls();
|
||||
@@ -1017,7 +1017,7 @@ void __fastcall TSiteAdvancedDialog::UpdateControls()
|
||||
else
|
||||
{
|
||||
ColorButton->Images = ColorImageList;
|
||||
ColorButton->ImageIndex = 1;
|
||||
ColorButton->ImageIndex = GetSessionColorImage(ColorImageList, FColor, 0);
|
||||
ColorButton->ImageAlignment = iaRight;
|
||||
}
|
||||
}
|
||||
@@ -1423,24 +1423,9 @@ void __fastcall TSiteAdvancedDialog::ColorButtonClick(TObject * /*Sender*/)
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::SessionColorChange(TColor Color)
|
||||
{
|
||||
SetSessionColor(Color);
|
||||
UpdateControls();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TSiteAdvancedDialog::SetSessionColor(TColor Color)
|
||||
{
|
||||
FColor = Color;
|
||||
|
||||
while (ColorImageList->Count > 1)
|
||||
{
|
||||
ColorImageList->Delete(1);
|
||||
}
|
||||
|
||||
if (Color != 0)
|
||||
{
|
||||
AddSessionColorImage(ColorImageList, Color, 0);
|
||||
}
|
||||
UpdateControls();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TTlsVersion __fastcall TSiteAdvancedDialog::IndexToTlsVersion(int Index)
|
||||
|
||||
@@ -347,7 +347,6 @@ private:
|
||||
int __fastcall GetFtpProxyLogonType();
|
||||
void __fastcall UpdateNavigationTree();
|
||||
TSshProt __fastcall GetSshProt();
|
||||
void __fastcall SetSessionColor(TColor Color);
|
||||
void __fastcall SessionColorChange(TColor Color);
|
||||
TTlsVersion __fastcall IndexToTlsVersion(int Index);
|
||||
int __fastcall TlsVersionToIndex(TTlsVersion TlsVersion);
|
||||
|
||||
@@ -496,56 +496,123 @@ bool __fastcall DeleteDirectory(const UnicodeString DirName)
|
||||
return retval;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall AddSessionColorImage(
|
||||
class TSessionColors : public TComponent
|
||||
{
|
||||
public:
|
||||
__fastcall TSessionColors(TComponent * Owner) : TComponent(Owner)
|
||||
{
|
||||
Name = QualifiedClassName();
|
||||
}
|
||||
|
||||
static TSessionColors * __fastcall Retrieve(TComponent * Component)
|
||||
{
|
||||
TSessionColors * SessionColors = dynamic_cast<TSessionColors *>(Component->FindComponent(QualifiedClassName()));
|
||||
if (SessionColors == NULL)
|
||||
{
|
||||
SessionColors = new TSessionColors(Component);
|
||||
}
|
||||
return SessionColors;
|
||||
}
|
||||
|
||||
typedef std::map<TColor, int> TColorMap;
|
||||
TColorMap ColorMap;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
int __fastcall GetSessionColorImage(
|
||||
TCustomImageList * ImageList, TColor Color, int MaskIndex)
|
||||
{
|
||||
|
||||
// This overly complex drawing is here to support color button on SiteAdvanced
|
||||
// dialog. There we use plain TImageList, instead of TPngImageList,
|
||||
// TButton does not work with transparent images
|
||||
// (not even TBitmap with Transparent = true)
|
||||
std::unique_ptr<TBitmap> MaskBitmap(new TBitmap());
|
||||
ImageList->GetBitmap(MaskIndex, MaskBitmap.get());
|
||||
TSessionColors * SessionColors = TSessionColors::Retrieve(ImageList);
|
||||
|
||||
std::unique_ptr<TPngImage> MaskImage(new TPngImage());
|
||||
MaskImage->Assign(MaskBitmap.get());
|
||||
|
||||
std::unique_ptr<TPngImage> ColorImage(new TPngImage(COLOR_RGB, 16, ImageList->Width, ImageList->Height));
|
||||
|
||||
TColor MaskTransparentColor = MaskImage->Pixels[0][0];
|
||||
TColor TransparentColor = MaskTransparentColor;
|
||||
// Expecting that the color to be replaced is in the centre of the image (HACK)
|
||||
TColor MaskColor = MaskImage->Pixels[ImageList->Width / 2][ImageList->Height / 2];
|
||||
|
||||
for (int Y = 0; Y < ImageList->Height; Y++)
|
||||
int Result;
|
||||
TSessionColors::TColorMap::const_iterator I = SessionColors->ColorMap.find(Color);
|
||||
if (I != SessionColors->ColorMap.end())
|
||||
{
|
||||
for (int X = 0; X < ImageList->Width; X++)
|
||||
Result = I->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This overly complex drawing is here to support color button on SiteAdvanced
|
||||
// dialog. There we use plain TImageList, instead of TPngImageList,
|
||||
// TButton does not work with transparent images
|
||||
// (not even TBitmap with Transparent = true)
|
||||
std::unique_ptr<TBitmap> MaskBitmap(new TBitmap());
|
||||
ImageList->GetBitmap(MaskIndex, MaskBitmap.get());
|
||||
|
||||
std::unique_ptr<TPngImage> MaskImage(new TPngImage());
|
||||
MaskImage->Assign(MaskBitmap.get());
|
||||
|
||||
std::unique_ptr<TPngImage> ColorImage(new TPngImage(COLOR_RGB, 16, ImageList->Width, ImageList->Height));
|
||||
|
||||
TColor MaskTransparentColor = MaskImage->Pixels[0][0];
|
||||
TColor TransparentColor = MaskTransparentColor;
|
||||
// Expecting that the color to be replaced is in the centre of the image (HACK)
|
||||
TColor MaskColor = MaskImage->Pixels[ImageList->Width / 2][ImageList->Height / 2];
|
||||
|
||||
for (int Y = 0; Y < ImageList->Height; Y++)
|
||||
{
|
||||
TColor SourceColor = MaskImage->Pixels[X][Y];
|
||||
TColor DestColor;
|
||||
// this branch is pointless as long as MaskTransparentColor and
|
||||
// TransparentColor are the same
|
||||
if (SourceColor == MaskTransparentColor)
|
||||
for (int X = 0; X < ImageList->Width; X++)
|
||||
{
|
||||
DestColor = TransparentColor;
|
||||
TColor SourceColor = MaskImage->Pixels[X][Y];
|
||||
TColor DestColor;
|
||||
// this branch is pointless as long as MaskTransparentColor and
|
||||
// TransparentColor are the same
|
||||
if (SourceColor == MaskTransparentColor)
|
||||
{
|
||||
DestColor = TransparentColor;
|
||||
}
|
||||
else if (SourceColor == MaskColor)
|
||||
{
|
||||
DestColor = Color;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestColor = SourceColor;
|
||||
}
|
||||
ColorImage->Pixels[X][Y] = DestColor;
|
||||
}
|
||||
else if (SourceColor == MaskColor)
|
||||
{
|
||||
DestColor = Color;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestColor = SourceColor;
|
||||
}
|
||||
ColorImage->Pixels[X][Y] = DestColor;
|
||||
}
|
||||
|
||||
std::unique_ptr<TBitmap> Bitmap(new TBitmap());
|
||||
Bitmap->SetSize(ImageList->Width, ImageList->Height);
|
||||
ColorImage->AssignTo(Bitmap.get());
|
||||
|
||||
Result = ImageList->AddMasked(Bitmap.get(), TransparentColor);
|
||||
|
||||
SessionColors->ColorMap.insert(std::make_pair(Color, Result));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall RegenerateSessionColorsImageList(TCustomImageList * ImageList, int MaskIndex)
|
||||
{
|
||||
TSessionColors * SessionColors = TSessionColors::Retrieve(ImageList);
|
||||
|
||||
std::vector<TColor> Colors;
|
||||
int FixedImages = ImageList->Count;
|
||||
Colors.resize(FixedImages + SessionColors->ColorMap.size());
|
||||
TSessionColors::TColorMap::const_iterator I = SessionColors->ColorMap.begin();
|
||||
while (I != SessionColors->ColorMap.end())
|
||||
{
|
||||
DebugAssert(Colors[I->second] == TColor());
|
||||
Colors[I->second] = I->first;
|
||||
I++;
|
||||
}
|
||||
|
||||
TSessionColors::TColorMap ColorMap = SessionColors->ColorMap;
|
||||
SessionColors->ColorMap.clear();
|
||||
|
||||
for (size_t Index = 0; Index < Colors.size(); Index++)
|
||||
{
|
||||
bool IsFixedImageIndex = (Index < FixedImages);
|
||||
DebugAssert((Colors[Index] == TColor()) == IsFixedImageIndex);
|
||||
if (!IsFixedImageIndex)
|
||||
{
|
||||
GetSessionColorImage(ImageList, Colors[Index], MaskIndex);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TBitmap> Bitmap(new TBitmap());
|
||||
Bitmap->SetSize(ImageList->Width, ImageList->Height);
|
||||
ColorImage->AssignTo(Bitmap.get());
|
||||
|
||||
ImageList->AddMasked(Bitmap.get(), TransparentColor);
|
||||
DebugAssert(SessionColors->ColorMap == ColorMap);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall SetSubmenu(TTBXCustomItem * Item)
|
||||
|
||||
@@ -27,7 +27,8 @@ bool __fastcall SpecialFolderLocation(int PathID, UnicodeString & Path);
|
||||
UnicodeString __fastcall UniqTempDir(const UnicodeString BaseDir,
|
||||
const UnicodeString Identity, bool Mask = false);
|
||||
bool __fastcall DeleteDirectory(const UnicodeString DirName);
|
||||
void __fastcall AddSessionColorImage(TCustomImageList * ImageList, TColor Color, int MaskIndex);
|
||||
int __fastcall GetSessionColorImage(TCustomImageList * ImageList, TColor Color, int MaskIndex);
|
||||
void __fastcall RegenerateSessionColorsImageList(TCustomImageList * ImageList, int MaskIndex);
|
||||
void __fastcall SetSubmenu(TTBXCustomItem * Item);
|
||||
typedef int __fastcall (*TCalculateWidth)(UnicodeString Text, void * Arg);
|
||||
void __fastcall ApplyTabs(
|
||||
|
||||
Reference in New Issue
Block a user