mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Bug 1393: Close button on session tab + Non-active session can be closed, as well as disconnected sessions without a need to reconnect them
https://winscp.net/tracker/1393 Source commit: b63ce2363155fa969d91e07f294cca9f1c5c2a98
This commit is contained in:
@@ -49,8 +49,8 @@
|
||||
<ILINK_Description>WinSCP components</ILINK_Description>
|
||||
<ILINK_GenerateImportLibrary>true</ILINK_GenerateImportLibrary>
|
||||
<ILINK_GenerateLibFile>true</ILINK_GenerateLibFile>
|
||||
<ILINK_LibraryPath>components\;$(ILINK_LibraryPath)</ILINK_LibraryPath>
|
||||
<IncludePath>components\;core;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
|
||||
<ILINK_LibraryPath>components\;$(INTERM_PATH)\Win32\Debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
|
||||
<IncludePath>components\;core;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
|
||||
<IntermediateOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</IntermediateOutputDir>
|
||||
<LinkPackageStatics>rtl.lib;vcl.lib;vclx.lib</LinkPackageStatics>
|
||||
<Multithreaded>true</Multithreaded>
|
||||
@@ -116,6 +116,9 @@
|
||||
<BuildOrder>20</BuildOrder>
|
||||
<BuildOrder>1</BuildOrder>
|
||||
</PackageImport>
|
||||
<PackageImport Include="tbxp.bpi">
|
||||
<BuildOrder>8</BuildOrder>
|
||||
</PackageImport>
|
||||
<PackageImport Include="vcl.bpi">
|
||||
<BuildOrder>23</BuildOrder>
|
||||
<BuildOrder>0</BuildOrder>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;$(DCC_Namespace)</DCC_Namespace>
|
||||
<FinalOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</FinalOutputDir>
|
||||
<ILINK_LibraryPath>$(BDS)\lib;$(ILINK_LibraryPath)</ILINK_LibraryPath>
|
||||
<IncludePath>components\;core;windows;packages\filemng;packages\dragndrop;packages\my;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
|
||||
<IncludePath>components\;core;windows;packages\filemng;packages\dragndrop;packages\my;packages\tb2k;packages\tbx;$(BDS)\include;$(BDS)\include\windows\vcl;$(IncludePath)</IncludePath>
|
||||
<IntermediateOutputDir>$(INTERM_PATH)\$(Platform)\$(Config)</IntermediateOutputDir>
|
||||
<Manifest_File>None</Manifest_File>
|
||||
<Multithreaded>true</Multithreaded>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <Common.h>
|
||||
#include <vsstyle.h>
|
||||
#include <memory>
|
||||
#include <PasTools.hpp>
|
||||
#include <TBXOfficeXPTheme.hpp>
|
||||
#include "ThemePageControl.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
@@ -39,6 +41,20 @@ __fastcall TThemeTabSheet::TThemeTabSheet(TComponent * Owner) :
|
||||
TTabSheet(Owner)
|
||||
{
|
||||
FShadowed = false;
|
||||
FShowCloseButton = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemeTabSheet::Invalidate()
|
||||
{
|
||||
TThemePageControl * ThemePageControl = dynamic_cast<TThemePageControl *>(Parent);
|
||||
if (DebugAlwaysTrue(ThemePageControl != NULL))
|
||||
{
|
||||
ThemePageControl->InvalidateTab(TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Parent->Invalidate();
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemeTabSheet::SetShadowed(bool Value)
|
||||
@@ -46,16 +62,16 @@ void __fastcall TThemeTabSheet::SetShadowed(bool Value)
|
||||
if (Shadowed != Value)
|
||||
{
|
||||
FShadowed = Value;
|
||||
|
||||
TThemePageControl * ThemePageControl = dynamic_cast<TThemePageControl *>(Parent);
|
||||
if (DebugAlwaysTrue(ThemePageControl != NULL))
|
||||
{
|
||||
ThemePageControl->InvalidateTab(TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Parent->Invalidate();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemeTabSheet::SetShowCloseButton(bool Value)
|
||||
{
|
||||
if (ShowCloseButton != Value)
|
||||
{
|
||||
FShowCloseButton = Value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
@@ -64,6 +80,7 @@ __fastcall TThemePageControl::TThemePageControl(TComponent * Owner) :
|
||||
TPageControl(Owner)
|
||||
{
|
||||
FOldTabIndex = -1;
|
||||
FHotCloseButton = -1;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
int __fastcall TThemePageControl::GetTabsHeight()
|
||||
@@ -116,32 +133,48 @@ void __fastcall TThemePageControl::PaintWindow(HDC DC)
|
||||
|
||||
// 2nd paint the inactive tabs
|
||||
|
||||
TPoint Point = ScreenToClient(Mouse->CursorPos);
|
||||
int HotIndex = IndexOfTabAt(Point.X, Point.Y);
|
||||
int SelectedIndex = TabIndex;
|
||||
int SelectedIndex = TabIndex; // optimization
|
||||
|
||||
for (int Tab = 0; Tab < PageCount; Tab++)
|
||||
{
|
||||
if (Tab != SelectedIndex)
|
||||
{
|
||||
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(Pages[Tab]);
|
||||
bool Shadowed = (ThemeTabSheet != NULL) ? ThemeTabSheet->Shadowed : false;
|
||||
TRect Rect = TabRect(Tab);
|
||||
int State = (Tab == HotIndex ? TIS_HOT : (Shadowed ? TIS_DISABLED : TIS_NORMAL));
|
||||
DrawThemesXpTabItem(DC, Tab, Rect, false, State);
|
||||
DrawThemesXpTab(DC, Tab);
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedIndex >= 0)
|
||||
{
|
||||
// 3rd paint the active selected tab
|
||||
TRect Rect = TabRect(SelectedIndex);
|
||||
Rect.Inflate(2, 2);
|
||||
Rect.Bottom--;
|
||||
DrawThemesXpTabItem(DC, SelectedIndex, Rect, false, TIS_SELECTED);
|
||||
DrawThemesXpTab(DC, TabIndex);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
bool __fastcall TThemePageControl::HasTabCloseButton(int Index)
|
||||
{
|
||||
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(Pages[Index]);
|
||||
return (ThemeTabSheet != NULL) ? ThemeTabSheet->ShowCloseButton : false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::DrawThemesXpTab(HDC DC, int Tab)
|
||||
{
|
||||
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(Pages[Tab]);
|
||||
bool Shadowed = (ThemeTabSheet != NULL) ? ThemeTabSheet->Shadowed : false;
|
||||
TRect Rect = TabRect(Tab);
|
||||
ItemTabRect(Tab, Rect);
|
||||
int State;
|
||||
if (Tab != TabIndex)
|
||||
{
|
||||
TPoint Point = ScreenToClient(Mouse->CursorPos);
|
||||
int HotIndex = IndexOfTabAt(Point.X, Point.Y);
|
||||
State = (Tab == HotIndex ? TIS_HOT : (Shadowed ? TIS_DISABLED : TIS_NORMAL));
|
||||
}
|
||||
else
|
||||
{
|
||||
State = TIS_SELECTED;
|
||||
}
|
||||
DrawThemesXpTabItem(DC, Tab, Rect, false, State);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// This function draws Themes Tab control parts: a) Tab-Body and b) Tab-tabs
|
||||
void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
|
||||
const TRect & Rect, bool Body, int State)
|
||||
@@ -154,6 +187,7 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
|
||||
HBITMAP BitmapOld = (HBITMAP)SelectObject(DCMem, BitmapMem);
|
||||
|
||||
TRect RectMem(0, 0, Size.Width, Size.Height);
|
||||
TRect RectItemMem(RectMem);
|
||||
if (!Body && (State == TIS_SELECTED))
|
||||
{
|
||||
RectMem.Bottom++;
|
||||
@@ -183,12 +217,7 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
|
||||
|
||||
if (!Body && (Item >= 0))
|
||||
{
|
||||
if ((State == TIS_SELECTED))
|
||||
{
|
||||
RectMem.Bottom--;
|
||||
}
|
||||
|
||||
DrawTabItem(DCMem, Item, RectMem, (State == TIS_SELECTED), (State == TIS_DISABLED));
|
||||
DrawTabItem(DCMem, Item, Rect, RectItemMem, (State == TIS_SELECTED), (State == TIS_DISABLED));
|
||||
}
|
||||
|
||||
// Blit image to the screen
|
||||
@@ -198,25 +227,78 @@ void __fastcall TThemePageControl::DrawThemesXpTabItem(HDC DC, int Item,
|
||||
DeleteDC(DCMem);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// draw tab item context: possible icon and text
|
||||
void __fastcall TThemePageControl::DrawTabItem(HDC DC, int Item, TRect Rect,
|
||||
bool Selected, bool Shadowed)
|
||||
void __fastcall TThemePageControl::ItemTabRect(int Item, TRect & Rect)
|
||||
{
|
||||
if (Item == TabIndex)
|
||||
{
|
||||
// Countered in CloseButtonRect
|
||||
Rect.Inflate(2, 2);
|
||||
Rect.Bottom--;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::ItemContentsRect(int Item, TRect & Rect)
|
||||
{
|
||||
bool Selected = (Item == TabIndex);
|
||||
|
||||
Rect.Left += 6;
|
||||
Rect.Top += 2;
|
||||
|
||||
if (Selected)
|
||||
{
|
||||
Rect.Bottom -= 1;
|
||||
Rect.Bottom -= 2;
|
||||
Rect.Top += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect.Bottom += 2;
|
||||
Rect.Top += 3;
|
||||
}
|
||||
|
||||
Rect.Left += 6;
|
||||
Rect.Top += 2 + (Selected ? 1 : 3);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
bool __fastcall TThemePageControl::HasItemImage(int Item)
|
||||
{
|
||||
return (Images != NULL) && (Pages[Item]->ImageIndex >= 0);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::ItemTextRect(int Item, TRect & Rect)
|
||||
{
|
||||
if (HasItemImage(Item))
|
||||
{
|
||||
Rect.Left += Images->Width + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect.Left -= 2;
|
||||
}
|
||||
Rect.Right -= 3;
|
||||
OffsetRect(&Rect, 0, ((Item == TabIndex) ? 0 : -2));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::DrawCross(HDC DC, int Width, COLORREF Color, const TRect & Rect)
|
||||
{
|
||||
HPEN Pen = CreatePen(PS_SOLID, Width, Color);
|
||||
HPEN OldPen = static_cast<HPEN>(SelectObject(DC, Pen));
|
||||
// To-and-back - to make both ends look the same
|
||||
MoveToEx(DC, Rect.Left, Rect.Bottom - 1, NULL);
|
||||
LineTo(DC, Rect.Right - 1, Rect.Top);
|
||||
LineTo(DC, Rect.Left, Rect.Bottom - 1);
|
||||
MoveToEx(DC, Rect.Left, Rect.Top, NULL);
|
||||
LineTo(DC, Rect.Right - 1, Rect.Bottom - 1);
|
||||
LineTo(DC, Rect.Left, Rect.Top);
|
||||
SelectObject(DC, OldPen);
|
||||
DeleteObject(Pen);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// draw tab item context: possible icon and text
|
||||
void __fastcall TThemePageControl::DrawTabItem(
|
||||
HDC DC, int Item, TRect TabRect, TRect Rect, bool Selected, bool Shadowed)
|
||||
{
|
||||
ItemContentsRect(Item, Rect);
|
||||
|
||||
UnicodeString Text = Pages[Item]->Caption;
|
||||
|
||||
if ((Images != NULL) && (Pages[Item]->ImageIndex >= 0))
|
||||
if (HasItemImage(Item))
|
||||
{
|
||||
int Left;
|
||||
if (!Text.IsEmpty())
|
||||
@@ -231,32 +313,132 @@ void __fastcall TThemePageControl::DrawTabItem(HDC DC, int Item, TRect Rect,
|
||||
std::unique_ptr<TCanvas> Canvas(new TCanvas());
|
||||
Canvas->Handle = DC;
|
||||
Images->Draw(Canvas.get(), Left, Y, Pages[Item]->ImageIndex, !Shadowed);
|
||||
Rect.Left += Images->Width + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect.Left -= 2;
|
||||
}
|
||||
|
||||
int TextHeight = 20;
|
||||
int OldMode = SetBkMode(DC, TRANSPARENT);
|
||||
if (!Text.IsEmpty())
|
||||
{
|
||||
ItemTextRect(Item, Rect);
|
||||
HFONT OldFont = (HFONT)SelectObject(DC, Font->Handle);
|
||||
Rect.Right -= 3;
|
||||
wchar_t * Buf = new wchar_t[Text.Length() + 1 + 4];
|
||||
wcscpy(Buf, Text.c_str());
|
||||
TRect TextRect(0, 0, Rect.Right - Rect.Left, 20);
|
||||
TRect TextRect(0, 0, Rect.Right - Rect.Left, TextHeight);
|
||||
// Truncates too long texts with ellipsis
|
||||
::DrawText(DC, Buf, -1, &TextRect, DT_CALCRECT | DT_SINGLELINE | DT_MODIFYSTRING | DT_END_ELLIPSIS);
|
||||
|
||||
OffsetRect(&Rect, 0, (Selected ? 0 : -2));
|
||||
DrawText(DC, Buf, -1, &Rect, DT_NOPREFIX | DT_CENTER);
|
||||
delete[] Buf;
|
||||
|
||||
if (HasTabCloseButton(Item))
|
||||
{
|
||||
Rect = CloseButtonRect(Item);
|
||||
Rect.Offset(-TabRect.Left, -TabRect.Top);
|
||||
|
||||
if (FHotCloseButton == Item)
|
||||
{
|
||||
HBRUSH Brush = CreateSolidBrush(GetSelectedBodyColor());
|
||||
FillRect(DC, &Rect, Brush);
|
||||
DeleteObject(Brush);
|
||||
|
||||
HPEN Pen = CreatePen(PS_SOLID, 1, ColorToRGB(clHighlight));
|
||||
HPEN OldPen = static_cast<HPEN>(SelectObject(DC, Pen));
|
||||
Rectangle(DC, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom);
|
||||
SelectObject(DC, OldPen);
|
||||
DeleteObject(Pen);
|
||||
}
|
||||
|
||||
int CrossPadding = GetCrossPadding();
|
||||
|
||||
COLORREF BackColor = GetPixel(DC, Rect.Left + (Rect.Width() / 2), Rect.Top + (Rect.Height() / 2));
|
||||
COLORREF CrossColor = ColorToRGB(Font->Color);
|
||||
#define BlendValue(FN) (((4 * static_cast<int>(FN(BackColor))) + static_cast<int>(FN(CrossColor))) / 5)
|
||||
COLORREF BlendColor = RGB(BlendValue(GetRValue), BlendValue(GetGValue), BlendValue(GetBValue));
|
||||
#undef BlendValue
|
||||
|
||||
TRect CrossRect(Rect);
|
||||
CrossRect.Inflate(-CrossPadding, -CrossPadding);
|
||||
|
||||
int CrossWidth = ScaleByTextHeight(this, 1);
|
||||
DrawCross(DC, CrossWidth + 1, BlendColor, CrossRect);
|
||||
DrawCross(DC, CrossWidth, CrossColor, CrossRect);
|
||||
}
|
||||
|
||||
SelectObject(DC, OldFont);
|
||||
}
|
||||
|
||||
SetBkMode(DC, OldMode);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
int __fastcall TThemePageControl::CloseButtonSize()
|
||||
{
|
||||
return ScaleByTextHeight(this, 16);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
int __fastcall TThemePageControl::GetCrossPadding()
|
||||
{
|
||||
return ScaleByTextHeight(this, 4);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
TRect __fastcall TThemePageControl::CloseButtonRect(int Index)
|
||||
{
|
||||
TRect Rect = TabRect(Index);
|
||||
ItemTabRect(Index, Rect);
|
||||
ItemContentsRect(Index, Rect);
|
||||
ItemTextRect(Index, Rect);
|
||||
|
||||
int ACloseButtonSize = CloseButtonSize();
|
||||
int CrossPadding = GetCrossPadding();
|
||||
|
||||
TEXTMETRIC TextMetric;
|
||||
Canvas->Font = Font;
|
||||
GetTextMetrics(Canvas->Handle, &TextMetric);
|
||||
|
||||
Rect.Top += TextMetric.tmAscent - ACloseButtonSize + CrossPadding;
|
||||
Rect.Left = Rect.Right - ACloseButtonSize - ScaleByTextHeight(this, 1);
|
||||
if (Index == TabIndex)
|
||||
{
|
||||
// To counter Inflate(2, 2) in ItemTabRect
|
||||
Rect.Left -= 2;
|
||||
}
|
||||
Rect.Right = Rect.Left + ACloseButtonSize;
|
||||
Rect.Bottom = Rect.Top + ACloseButtonSize;
|
||||
return Rect;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::SetHotCloseButton(int Index)
|
||||
{
|
||||
if (Index != FHotCloseButton)
|
||||
{
|
||||
if (FHotCloseButton >= 0)
|
||||
{
|
||||
InvalidateTab(FHotCloseButton);
|
||||
}
|
||||
FHotCloseButton = Index;
|
||||
if (FHotCloseButton >= 0)
|
||||
{
|
||||
InvalidateTab(FHotCloseButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::MouseMove(TShiftState /*Shift*/, int X, int Y)
|
||||
{
|
||||
SetHotCloseButton(IndexOfCloseButtonAt(X, Y));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
int __fastcall TThemePageControl::IndexOfCloseButtonAt(int X, int Y)
|
||||
{
|
||||
int Result = IndexOfTabAt(X, Y);
|
||||
if ((Result < 0) ||
|
||||
!HasTabCloseButton(Result) ||
|
||||
!CloseButtonRect(Result).Contains(TPoint(X, Y)))
|
||||
{
|
||||
Result = -1;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::DrawThemesPart(HDC DC, int PartId,
|
||||
int StateId, LPCWSTR PartNameID, LPRECT Rect)
|
||||
{
|
||||
@@ -267,8 +449,7 @@ void __fastcall TThemePageControl::DrawThemesPart(HDC DC, int PartId,
|
||||
CloseThemeData(Theme);
|
||||
}
|
||||
}
|
||||
//==========================================================================================================
|
||||
// these two messages are necessary only to properly redraw deselected tab background, because
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
bool __fastcall TThemePageControl::CanChange()
|
||||
{
|
||||
FOldTabIndex = ActivePageIndex;
|
||||
@@ -303,6 +484,53 @@ void __fastcall TThemePageControl::Change()
|
||||
TPageControl::Change();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
UnicodeString __fastcall TThemePageControl::FormatCaptionWithCloseButton(const UnicodeString & Caption)
|
||||
{
|
||||
int OrigWidth = Canvas->TextWidth(Caption);
|
||||
UnicodeString Result = Caption;
|
||||
int CloseButtonWidth = CloseButtonSize();
|
||||
while (Canvas->TextWidth(Result) < OrigWidth + CloseButtonWidth)
|
||||
{
|
||||
Result += L" ";
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::WMLButtonDown(TWMLButtonDown & Message)
|
||||
{
|
||||
int Index = IndexOfCloseButtonAt(Message.XPos, Message.YPos);
|
||||
if (Index >= 0)
|
||||
{
|
||||
Message.Result = 1;
|
||||
if (FOnCloseButtonClick != NULL)
|
||||
{
|
||||
FOnCloseButtonClick(this, Index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TPageControl::Dispatch(&Message);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TThemePageControl::Dispatch(void * Message)
|
||||
{
|
||||
TMessage * M = reinterpret_cast<TMessage*>(Message);
|
||||
if (M->Msg == CM_MOUSELEAVE)
|
||||
{
|
||||
SetHotCloseButton(-1);
|
||||
TPageControl::Dispatch(Message);
|
||||
}
|
||||
else if (M->Msg == WM_LBUTTONDOWN)
|
||||
{
|
||||
WMLButtonDown(*reinterpret_cast<TWMLButtonDown *>(M));
|
||||
}
|
||||
else
|
||||
{
|
||||
TPageControl::Dispatch(Message);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
#ifdef _DEBUG
|
||||
void __fastcall TThemePageControl::RequestAlign()
|
||||
{
|
||||
|
||||
@@ -10,36 +10,64 @@ public:
|
||||
__fastcall TThemeTabSheet(TComponent * Owner);
|
||||
|
||||
__property bool Shadowed = { read = FShadowed, write = SetShadowed };
|
||||
__property bool ShowCloseButton = { read = FShowCloseButton, write = SetShowCloseButton };
|
||||
|
||||
private:
|
||||
void __fastcall SetShadowed(bool Value);
|
||||
void __fastcall SetShowCloseButton(bool Value);
|
||||
void __fastcall Invalidate();
|
||||
|
||||
bool FShadowed;
|
||||
bool FShowCloseButton;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
typedef void __fastcall (__closure *TPageControlCloseButtonClick)(TPageControl * Sender, int Index);
|
||||
//---------------------------------------------------------------------------
|
||||
class TThemePageControl : public TPageControl
|
||||
{
|
||||
friend class TThemeTabSheet;
|
||||
|
||||
__published:
|
||||
__property TPageControlCloseButtonClick OnCloseButtonClick = { read = FOnCloseButtonClick, write = FOnCloseButtonClick };
|
||||
|
||||
public:
|
||||
__fastcall TThemePageControl(TComponent * Owner);
|
||||
|
||||
int __fastcall GetTabsHeight();
|
||||
UnicodeString __fastcall FormatCaptionWithCloseButton(const UnicodeString & Caption);
|
||||
|
||||
protected:
|
||||
virtual void __fastcall PaintWindow(HDC DC);
|
||||
DYNAMIC bool __fastcall CanChange();
|
||||
DYNAMIC void __fastcall Change();
|
||||
DYNAMIC void __fastcall MouseMove(TShiftState Shift, int X, int Y);
|
||||
virtual void __fastcall Dispatch(void * Message);
|
||||
#ifdef _DEBUG
|
||||
virtual void __fastcall RequestAlign();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void __fastcall DrawThemesXpTab(HDC DC, int Tab);
|
||||
void __fastcall DrawThemesXpTabItem(HDC DC, int Item, const TRect & Rect, bool Body, int State);
|
||||
void __fastcall DrawTabItem(HDC DC, int Item, TRect Rect, bool Selected, bool Shadowed);
|
||||
void __fastcall DrawTabItem(HDC DC, int Item, TRect TabRect, TRect Rect, bool Selected, bool Shadowed);
|
||||
void __fastcall DrawThemesPart(HDC DC, int PartId, int StateId, LPCWSTR PartNameID, LPRECT Rect);
|
||||
void __fastcall InvalidateTab(int Index);
|
||||
int __fastcall CloseButtonSize();
|
||||
int __fastcall GetCrossPadding();
|
||||
TRect __fastcall CloseButtonRect(int Index);
|
||||
int __fastcall IndexOfCloseButtonAt(int X, int Y);
|
||||
void __fastcall ItemContentsRect(int Item, TRect & Rect);
|
||||
bool __fastcall HasItemImage(int Item);
|
||||
void __fastcall ItemTextRect(int Item, TRect & Rect);
|
||||
void __fastcall ItemTabRect(int Item, TRect & Rect);
|
||||
bool __fastcall HasTabCloseButton(int Index);
|
||||
void __fastcall SetHotCloseButton(int Index);
|
||||
void __fastcall DrawCross(HDC DC, int Width, COLORREF Color, const TRect & Rect);
|
||||
void __fastcall WMLButtonDown(TWMLButtonDown & Message);
|
||||
|
||||
int FOldTabIndex;
|
||||
int FHotCloseButton;
|
||||
TPageControlCloseButtonClick FOnCloseButtonClick;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -4672,10 +4672,10 @@ void __fastcall TCustomScpExplorerForm::DuplicateSession()
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
|
||||
bool __fastcall TCustomScpExplorerForm::CanCloseQueue(TTerminalQueue * Queue)
|
||||
{
|
||||
DebugAssert(FQueue != NULL);
|
||||
bool Result = FQueue->IsEmpty;
|
||||
DebugAssert(Queue != NULL);
|
||||
bool Result = Queue->IsEmpty;
|
||||
if (!Result)
|
||||
{
|
||||
SetFocus();
|
||||
@@ -4684,6 +4684,11 @@ bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
|
||||
return Result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TCustomScpExplorerForm::CanCloseQueue()
|
||||
{
|
||||
return CanCloseQueue(FQueue);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::CloseSession()
|
||||
{
|
||||
if (CanCloseQueue())
|
||||
@@ -6256,7 +6261,7 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
|
||||
|
||||
for (int Index = 0; Index <= TerminalList->Count; Index++)
|
||||
{
|
||||
TTabSheet * TabSheet;
|
||||
TThemeTabSheet * TabSheet;
|
||||
if (Index >= SessionsPageControl->PageCount)
|
||||
{
|
||||
TabSheet = new TThemeTabSheet(SessionsPageControl);
|
||||
@@ -6264,10 +6269,11 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
|
||||
}
|
||||
else
|
||||
{
|
||||
TabSheet = SessionsPageControl->Pages[Index];
|
||||
TabSheet = DebugNotNull(dynamic_cast<TThemeTabSheet *>(SessionsPageControl->Pages[Index]));
|
||||
}
|
||||
|
||||
if (Index < TerminalList->Count)
|
||||
bool IsSessionTab = (Index < TerminalList->Count);
|
||||
if (IsSessionTab)
|
||||
{
|
||||
TTerminal * Terminal = dynamic_cast<TTerminal *>(TerminalList->Objects[Index]);
|
||||
TabSheet->Tag = reinterpret_cast<int>(Terminal);
|
||||
@@ -6281,6 +6287,8 @@ void __fastcall TCustomScpExplorerForm::DoTerminalListChanged()
|
||||
// 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();
|
||||
}
|
||||
|
||||
TabSheet->ShowCloseButton = IsSessionTab;
|
||||
}
|
||||
}
|
||||
__finally
|
||||
@@ -6325,7 +6333,7 @@ void __fastcall TCustomScpExplorerForm::UpdateSessionTab(TTabSheet * TabSheet)
|
||||
TabSheet->ImageIndex = AddSessionColor(Color);
|
||||
|
||||
UnicodeString TabCaption = TTerminalManager::Instance()->GetTerminalTitle(ManagedTerminal, true);
|
||||
TabSheet->Caption = TabCaption;
|
||||
TabSheet->Caption = SessionsPageControl->FormatCaptionWithCloseButton(TabCaption);
|
||||
|
||||
TThemeTabSheet * ThemeTabSheet = dynamic_cast<TThemeTabSheet *>(TabSheet);
|
||||
if (DebugAlwaysTrue(ThemeTabSheet != NULL))
|
||||
@@ -9843,3 +9851,29 @@ void __fastcall TCustomScpExplorerForm::ReloadDirectory(TOperationSide Side)
|
||||
DirView(Side)->ReloadDirectory();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TCustomScpExplorerForm::SessionsPageControlCloseButtonClick(TPageControl * /*Sender*/, int Index)
|
||||
{
|
||||
if (Index == SessionsPageControl->TabIndex)
|
||||
{
|
||||
CloseSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
TTabSheet * TabSheet = SessionsPageControl->Pages[Index];
|
||||
TTerminal * Terminal = GetSessionTabTerminal(TabSheet);
|
||||
TTerminalManager * Manager = TTerminalManager::Instance();
|
||||
if (!Terminal->Active)
|
||||
{
|
||||
Manager->FreeTerminal(Terminal);
|
||||
}
|
||||
else
|
||||
{
|
||||
TTerminalQueue * Queue = Manager->FindQueueForTerminal(Terminal);
|
||||
if (CanCloseQueue(Queue))
|
||||
{
|
||||
Manager->FreeTerminal(Terminal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -313,6 +313,7 @@ object CustomScpExplorerForm: TCustomScpExplorerForm
|
||||
OnDragDrop = SessionsPageControlDragDrop
|
||||
OnDragOver = SessionsPageControlDragOver
|
||||
OnMouseDown = SessionsPageControlMouseDown
|
||||
OnCloseButtonClick = SessionsPageControlCloseButtonClick
|
||||
object TabSheet1: TTabSheet
|
||||
Caption = 'TabSheet1'
|
||||
end
|
||||
|
||||
@@ -189,6 +189,7 @@ __published:
|
||||
void __fastcall DirViewBusy(TObject *Sender, int Busy, bool & Allow);
|
||||
void __fastcall SessionsPageControlContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
|
||||
void __fastcall DockContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled);
|
||||
void __fastcall SessionsPageControlCloseButtonClick(TPageControl *Sender, int Index);
|
||||
|
||||
private:
|
||||
TTerminal * FTerminal;
|
||||
@@ -450,6 +451,7 @@ protected:
|
||||
void __fastcall QueueViewDeleteItem(int Index);
|
||||
void __fastcall UserActionTimer(TObject * Sender);
|
||||
void __fastcall UpdateQueueView();
|
||||
bool __fastcall CanCloseQueue(TTerminalQueue * Queue);
|
||||
bool __fastcall CanCloseQueue();
|
||||
virtual bool __fastcall IsFileControl(TObject * Control, TOperationSide Side);
|
||||
virtual void __fastcall ReloadLocalDirectory(const UnicodeString Directory = L"");
|
||||
|
||||
9
source/packages/tbx/TBXOfficeXPTheme.pas
vendored
9
source/packages/tbx/TBXOfficeXPTheme.pas
vendored
@@ -86,6 +86,8 @@ type
|
||||
procedure PaintStatusBar(Control: TWinControl; Canvas: TCanvas; R: TRect; Part: Integer); override;
|
||||
end;
|
||||
|
||||
function GetSelectedBodyColor: TColor;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -1227,7 +1229,7 @@ begin
|
||||
BtnItemColors[bisDisabled, ipText] := DisabledText;
|
||||
SetContrast(BtnItemColors[bisDisabled, ipText], ToolbarColor, 80);
|
||||
BtnItemColors[bisDisabled, ipFrame] := clNone;
|
||||
BtnItemColors[bisSelected, ipBody] := Blend(clHighlight, Blend(clBtnFace, clWindow, 50), 10);
|
||||
BtnItemColors[bisSelected, ipBody] := GetSelectedBodyColor;
|
||||
SetContrast(BtnItemColors[bisSelected, ipBody], ToolbarColor, 5);
|
||||
BtnItemColors[bisSelected, ipText] := BtnItemColors[bisNormal, ipText];
|
||||
BtnItemColors[bisSelected, ipFrame] := clHighlight;
|
||||
@@ -1409,4 +1411,9 @@ begin
|
||||
if Message.WParam = TSC_VIEWCHANGE then SetupColorCache;
|
||||
end;
|
||||
|
||||
function GetSelectedBodyColor: TColor;
|
||||
begin
|
||||
Result := Blend(clHighlight, Blend(clBtnFace, clWindow, 50), 10);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user