ultimatepp/uppsrc/ide/Bottom.cpp
2025-10-09 09:12:01 +02:00

295 lines
5.6 KiB
C++

#include "ide.h"
RightTabs::RightTabs()
{
cx = 3;
cursor = -1;
Transparent();
}
void RightTabs::Clear()
{
tab.Clear();
cx = 3;
cursor = -1;
Refresh();
}
void RightTabs::Repos()
{
int y = 0;
for(int i = 0; i < tab.GetCount(); i++) {
tab[i].y = y;
y += tab[i].GetHeight();
}
RefreshParentLayout();
}
void RightTabs::Add(const Image& img, const String& tip, bool highlight)
{
Tab& t = tab.Add();
t.img = img;
t.tip = tip;
t.highlight = highlight;
cx = max(cx, DPI(1) + max(img.GetWidth(), DPI(16)) + Zx(80) + DPI(2));
Repos();
}
void RightTabs::Set(int i, const String& text, Color ink, Font font)
{
auto& m = tab[i];
m.tip = text;
m.ink = ink;
m.font = font;
Refresh();
}
int RightTabs::Tab::GetHeight() const
{
return max(img.GetSize().cy, StdFont().GetCy()) + SPACE;
}
void RightTabs::PaintTab(Draw& w, int x, int y, int cx, int cy, Color paper, const Tab& t, Color hl)
{
Color fc = FieldFrameColor();
w.DrawRect(x, y + 1, cx - 1, cy - 2, paper);
w.DrawRect(x, y, cx - 1, 1, fc);
w.DrawRect(x + cx - 1, y + 1, 1, cy - 2, fc);
w.DrawRect(x, y + cy - 1, cx - 1, 1, fc);
w.Clip(x, y, cx - 1, cy);
Size isz = t.img.GetSize();
int icx = max(DPI(16), isz.cx);
w.DrawImage(x + DPI(1) + (icx - isz.cx) / 2, (cy - isz.cy) / 2 + y, t.img);
w.DrawText(x + icx + DPI(3), (cy - StdFont().GetCy()) / 2 + y, t.tip, t.font, t.highlight ? SLtBlue() : t.ink);
w.End();
}
void RightTabs::Paint(Draw& w)
{
Size sz = GetSize();
w.DrawRect(sz, Blend(SColorFace, SColorPaper));
Color hc = Blend(Yellow, LtRed, 100);
for(int i = 0; i < tab.GetCount(); i++) {
Tab& t = tab[i];
if(i != cursor)
PaintTab(w, 0, t.y + 2, cx - 1, t.GetHeight() - 1,
i == hl ? Blend(SColorFace(), SColorPaper()) : SColorFace(),
t, i == hl ? hc : Null);
}
if(cursor >= 0 && cursor < tab.GetCount()) {
Tab& t = tab[cursor];
PaintTab(w, 0, t.y, cx, t.GetHeight() + 3, SColorPaper(), t, cursor == hl ? hc : Null);
}
}
int RightTabs::GetPos(Point p)
{
for(int i = 0; i < tab.GetCount(); i++)
if(p.y < tab[i].GetRight())
return i;
return -1;
}
void RightTabs::SetCursor(int i)
{
ASSERT(cursor < tab.GetCount());
cursor = i;
Refresh();
}
void RightTabs::LeftDown(Point p, dword)
{
int c = GetPos(p);
if(c >= 0 && c != cursor) {
cursor = c;
UpdateActionRefresh();
if(GetParent())
GetParent()->RefreshFrame();
}
}
void RightTabs::MouseMove(Point p, dword)
{
int c = GetPos(p);
if(c != hl) {
hl = c;
Refresh();
}
}
void RightTabs::MouseLeave()
{
CancelMode();
}
void RightTabs::CancelMode()
{
hl = -1;
Refresh();
if(GetParent())
GetParent()->RefreshFrame();
}
void RightTabs::FramePaint(Draw& w, const Rect& rr)
{
Rect r = rr;
r.right -= cx;
DrawFrame(w, r, FieldFrameColor());
DrawFrame(w, r.Deflated(1), SColorPaper);
if(cursor >= 0 && cursor < tab.GetCount()) {
Tab& t = tab[cursor];
w.DrawRect(r.right - 1, t.y + 1, 1, t.GetHeight() + 1, SColorFace);
}
}
void RightTabs::FrameLayout(Rect& r)
{
LayoutFrameRight(r, this, cx);
r.top += 2;
r.right -= 2;
r.left += 2;
r.bottom -= 2;
}
void RightTabs::FrameAddSize(Size& sz)
{
sz += 4;
sz.cx += cx + 2;
}
String Ide::GetFoundText(const ArrayCtrl& list)
{
for(int i = 0; i < list.GetCount(); i++) {
Value v = list.Get(i, "INFO");
if(v.Is<ListLineInfo>()) {
const ListLineInfo& f = ValueTo<ListLineInfo>(v);
if(*f.message == '\1') {
Vector<String> h = Split(~f.message + 1, '\1', false);
if(h.GetCount() > 3)
if(f.linepos > 0) // some lines are ignored
return h[3].Mid(f.linepos - 1, f.len);
}
}
}
return Null;
}
void Ide::BTabs()
{
btabs.Clear();
btabs.Add(IdeImg::close, "Close (Esc)");
btabs.Add(IdeImg::console, "Console");
error_tab_i = btabs.GetCount();
btabs.Add(IdeImg::errors, "Errors");
btabs.Add(IdeImg::calc, "Calculator");
if(bottomctrl)
btabs.Add(IdeCommonImg::Debugger, "Debug");
for(int i = 0; i < __countof(ffound); i++) {
if(!ffound[i])
break;
String h = GetFoundText(*ffound[i]);
btabs.Add(Nvl(ffound[i]->icon, IdeImg::query()), Nvl(h, "Empty"), h.GetCount());
}
}
void Ide::SyncBottom()
{
int q = btabs.GetCursor();
if(q == BCLOSE) {
HideBottom();
return;
}
if(editor_bottom.GetZoom() >= 0)
editor_bottom.NoZoom();
console.Show(q == BCONSOLE);
error.Show(q == BERRORS);
calc.Show(q == BCALC);
calc.LoadHlStyles(editor.StoreHlStyles());
calc.SetFont(editorfont);
SetBar();
if(q == BCALC)
ActiveFocus(calc);
if(bottomctrl)
bottomctrl->Show(q == BDEBUG);
else
q++; // no debug
for(int i = 0; i < __countof(ffound); i++) {
if(!ffound[i])
break;
if(ffound[i]->GetParent() != &bottom)
bottom << (*ffound[i]).SizePos();
ffound[i]->Show(q == BFINDINFILES1 + i);
}
}
void Ide::SetBottom(int i)
{
btabs.SetCursor(i - (!bottomctrl && i >= BFINDINFILES1));
SyncBottom();
}
void Ide::ShowBottom(int i)
{
if(i == btabs.GetCursor() && IsBottomShown())
return;
SetBottom(i);
}
void Ide::ToggleBottom(int i)
{
if(i == btabs.GetCursor() && IsBottomShown())
HideBottom();
else
SetBottom(i);
}
bool Ide::IsBottomShown() const
{
return editor_bottom.GetZoom() < 0;
}
void Ide::SwapBottom()
{
if(editor.Esc())
return;
if(editor.IsFindOpen())
editor.FindClose();
else
if(!designer && !editor.HasFocusDeep())
ActiveFocus(editor);
else
if(IsBottomShown())
HideBottom();
else {
if(btabs.GetCursor() <= 0)
btabs.SetCursor(1);
SyncBottom();
}
}
void Ide::HideBottom() {
editor_bottom.Zoom(0);
editor.SetWantFocus();
SetBar();
}
void Ide::IdeSetBottom(Ctrl& ctrl)
{
bottom.Add(ctrl.SizePos());
bottomctrl = &ctrl;
BTabs();
SetBottom(BDEBUG);
}
void Ide::IdeRemoveBottom(Ctrl& ctrl)
{
ctrl.Remove();
bottomctrl = NULL;
BTabs();
HideBottom();
}
void Ide::IdeActivateBottom()
{
SetBottom(BDEBUG);
}