mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Refactor editor image list using CScrollRegion
, split method
This commit is contained in:
parent
9f01c6fe66
commit
5dc6c90a50
|
@ -3922,133 +3922,20 @@ void CEditor::SortImages()
|
|||
}
|
||||
}
|
||||
|
||||
void CEditor::RenderImages(CUIRect ToolBox, CUIRect View)
|
||||
void CEditor::RenderImagesList(CUIRect ToolBox)
|
||||
{
|
||||
static float s_ScrollValue = 0;
|
||||
float ImagesHeight = 30.0f + 14.0f * m_Map.m_vpImages.size() + 27.0f;
|
||||
float ScrollDifference = ImagesHeight - ToolBox.h;
|
||||
const float RowHeight = 12.0f;
|
||||
|
||||
if(ImagesHeight > ToolBox.h) // Do we even need a scrollbar?
|
||||
{
|
||||
CUIRect Scroll;
|
||||
ToolBox.VSplitRight(20.0f, &ToolBox, &Scroll);
|
||||
s_ScrollValue = UI()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue);
|
||||
|
||||
if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&ToolBox))
|
||||
{
|
||||
int ScrollNum = (int)((ImagesHeight - ToolBox.h) / 14.0f) + 1;
|
||||
if(ScrollNum > 0)
|
||||
{
|
||||
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP))
|
||||
s_ScrollValue = clamp(s_ScrollValue - 1.0f / ScrollNum, 0.0f, 1.0f);
|
||||
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN))
|
||||
s_ScrollValue = clamp(s_ScrollValue + 1.0f / ScrollNum, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float ImageStartAt = ScrollDifference * s_ScrollValue;
|
||||
if(ImageStartAt < 0.0f)
|
||||
ImageStartAt = 0.0f;
|
||||
|
||||
float ImageStopAt = ImagesHeight - ScrollDifference * (1 - s_ScrollValue);
|
||||
float ImageCur = 0.0f;
|
||||
|
||||
for(int e = 0; e < 2; e++) // two passes, first embedded, then external
|
||||
{
|
||||
CUIRect Slot;
|
||||
|
||||
if(ImageCur > ImageStopAt)
|
||||
break;
|
||||
else if(ImageCur >= ImageStartAt)
|
||||
{
|
||||
ToolBox.HSplitTop(15.0f, &Slot, &ToolBox);
|
||||
if(e == 0)
|
||||
UI()->DoLabel(&Slot, "Embedded", 12.0f, TEXTALIGN_CENTER);
|
||||
else
|
||||
UI()->DoLabel(&Slot, "External", 12.0f, TEXTALIGN_CENTER);
|
||||
}
|
||||
ImageCur += 15.0f;
|
||||
|
||||
for(int i = 0; i < (int)m_Map.m_vpImages.size(); i++)
|
||||
{
|
||||
if((e && !m_Map.m_vpImages[i]->m_External) ||
|
||||
(!e && m_Map.m_vpImages[i]->m_External))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ImageCur > ImageStopAt)
|
||||
break;
|
||||
else if(ImageCur < ImageStartAt)
|
||||
{
|
||||
ImageCur += 14.0f;
|
||||
continue;
|
||||
}
|
||||
ImageCur += 14.0f;
|
||||
|
||||
char aBuf[128];
|
||||
str_copy(aBuf, m_Map.m_vpImages[i]->m_aName, sizeof(aBuf));
|
||||
ToolBox.HSplitTop(12.0f, &Slot, &ToolBox);
|
||||
|
||||
int Selected = m_SelectedImage == i;
|
||||
|
||||
const bool ImageUsed = std::any_of(m_Map.m_vpGroups.cbegin(), m_Map.m_vpGroups.cend(), [i](const auto &pGroup) {
|
||||
return std::any_of(pGroup->m_vpLayers.cbegin(), pGroup->m_vpLayers.cend(), [i](const auto &pLayer) {
|
||||
if(pLayer->m_Type == LAYERTYPE_QUADS)
|
||||
return static_cast<CLayerQuads *>(pLayer)->m_Image == i;
|
||||
else if(pLayer->m_Type == LAYERTYPE_TILES)
|
||||
return static_cast<CLayerTiles *>(pLayer)->m_Image == i;
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
if(!ImageUsed)
|
||||
Selected += 2; // Image is unused
|
||||
|
||||
if(Selected < 2 && e == 1)
|
||||
{
|
||||
if(!IsVanillaImage(m_Map.m_vpImages[i]->m_aName))
|
||||
{
|
||||
Selected += 4; // Image should be embedded
|
||||
}
|
||||
}
|
||||
|
||||
float FontSize = 10.0f;
|
||||
while(TextRender()->TextWidth(nullptr, FontSize, aBuf, -1, -1.0f) > Slot.w)
|
||||
FontSize--;
|
||||
|
||||
if(int Result = DoButton_Ex(&m_Map.m_vpImages[i], aBuf, Selected, &Slot,
|
||||
BUTTON_CONTEXT, "Select image.", 0, FontSize))
|
||||
{
|
||||
m_SelectedImage = i;
|
||||
|
||||
static int s_PopupImageID = 0;
|
||||
if(Result == 2)
|
||||
{
|
||||
CEditorImage *pImg = m_Map.m_vpImages[m_SelectedImage];
|
||||
int Height;
|
||||
if(pImg->m_External || IsVanillaImage(pImg->m_aName))
|
||||
Height = 60;
|
||||
else
|
||||
Height = 43;
|
||||
UiInvokePopupMenu(&s_PopupImageID, 0, UI()->MouseX(), UI()->MouseY(), 120, Height, PopupImage);
|
||||
}
|
||||
}
|
||||
|
||||
ToolBox.HSplitTop(2.0f, nullptr, &ToolBox);
|
||||
}
|
||||
|
||||
// separator
|
||||
ToolBox.HSplitTop(5.0f, &Slot, &ToolBox);
|
||||
ImageCur += 5.0f;
|
||||
IGraphics::CLineItem LineItem(Slot.x, Slot.y + Slot.h / 2, Slot.x + Slot.w, Slot.y + Slot.h / 2);
|
||||
Graphics()->TextureClear();
|
||||
Graphics()->LinesBegin();
|
||||
Graphics()->LinesDraw(&LineItem, 1);
|
||||
Graphics()->LinesEnd();
|
||||
}
|
||||
static CScrollRegion s_ScrollRegion;
|
||||
vec2 ScrollOffset(0.0f, 0.0f);
|
||||
CScrollRegionParams ScrollParams;
|
||||
ScrollParams.m_ScrollbarWidth = 10.0f;
|
||||
ScrollParams.m_ScrollbarMargin = 3.0f;
|
||||
ScrollParams.m_ScrollUnit = RowHeight * 5;
|
||||
s_ScrollRegion.Begin(&ToolBox, &ScrollOffset, &ScrollParams);
|
||||
ToolBox.y += ScrollOffset.y;
|
||||
|
||||
bool ScrollToSelection = false;
|
||||
if(Input()->KeyPress(KEY_DOWN) && m_Dialog == DIALOG_NONE)
|
||||
{
|
||||
int OldImage = m_SelectedImage;
|
||||
|
@ -4072,6 +3959,7 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect View)
|
|||
}
|
||||
}
|
||||
}
|
||||
ScrollToSelection = OldImage != m_SelectedImage;
|
||||
}
|
||||
if(Input()->KeyPress(KEY_UP) && m_Dialog == DIALOG_NONE)
|
||||
{
|
||||
|
@ -4096,44 +3984,124 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect View)
|
|||
}
|
||||
}
|
||||
}
|
||||
ScrollToSelection = OldImage != m_SelectedImage;
|
||||
}
|
||||
|
||||
// render image
|
||||
int i = m_SelectedImage;
|
||||
if(i >= 0 && (size_t)i < m_Map.m_vpImages.size())
|
||||
for(int e = 0; e < 2; e++) // two passes, first embedded, then external
|
||||
{
|
||||
CUIRect r;
|
||||
View.Margin(10.0f, &r);
|
||||
if(r.h < r.w)
|
||||
r.w = r.h;
|
||||
else
|
||||
r.h = r.w;
|
||||
float Max = (float)(maximum(m_Map.m_vpImages[i]->m_Width, m_Map.m_vpImages[i]->m_Height));
|
||||
r.w *= m_Map.m_vpImages[i]->m_Width / Max;
|
||||
r.h *= m_Map.m_vpImages[i]->m_Height / Max;
|
||||
Graphics()->TextureSet(m_Map.m_vpImages[i]->m_Texture);
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->WrapClamp();
|
||||
Graphics()->QuadsBegin();
|
||||
IGraphics::CQuadItem QuadItem(r.x, r.y, r.w, r.h);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
Graphics()->WrapNormal();
|
||||
}
|
||||
//if(ImageCur + 27.0f > ImageStopAt)
|
||||
// return;
|
||||
CUIRect Slot;
|
||||
ToolBox.HSplitTop(RowHeight + 3.0f, &Slot, &ToolBox);
|
||||
if(s_ScrollRegion.AddRect(Slot))
|
||||
UI()->DoLabel(&Slot, e == 0 ? "Embedded" : "External", 12.0f, TEXTALIGN_CENTER);
|
||||
|
||||
CUIRect Slot;
|
||||
ToolBox.HSplitTop(5.0f, &Slot, &ToolBox);
|
||||
for(int i = 0; i < (int)m_Map.m_vpImages.size(); i++)
|
||||
{
|
||||
if((e && !m_Map.m_vpImages[i]->m_External) ||
|
||||
(!e && m_Map.m_vpImages[i]->m_External))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ToolBox.HSplitTop(RowHeight + 2.0f, &Slot, &ToolBox);
|
||||
int Selected = m_SelectedImage == i;
|
||||
if(!s_ScrollRegion.AddRect(Slot, Selected && ScrollToSelection))
|
||||
continue;
|
||||
Slot.HSplitTop(RowHeight, &Slot, nullptr);
|
||||
|
||||
const bool ImageUsed = std::any_of(m_Map.m_vpGroups.cbegin(), m_Map.m_vpGroups.cend(), [i](const auto &pGroup) {
|
||||
return std::any_of(pGroup->m_vpLayers.cbegin(), pGroup->m_vpLayers.cend(), [i](const auto &pLayer) {
|
||||
if(pLayer->m_Type == LAYERTYPE_QUADS)
|
||||
return static_cast<CLayerQuads *>(pLayer)->m_Image == i;
|
||||
else if(pLayer->m_Type == LAYERTYPE_TILES)
|
||||
return static_cast<CLayerTiles *>(pLayer)->m_Image == i;
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
if(!ImageUsed)
|
||||
Selected += 2; // Image is unused
|
||||
|
||||
if(Selected < 2 && e == 1)
|
||||
{
|
||||
if(!IsVanillaImage(m_Map.m_vpImages[i]->m_aName))
|
||||
{
|
||||
Selected += 4; // Image should be embedded
|
||||
}
|
||||
}
|
||||
|
||||
float FontSize = 10.0f;
|
||||
while(TextRender()->TextWidth(nullptr, FontSize, m_Map.m_vpImages[i]->m_aName, -1, -1.0f) > Slot.w)
|
||||
FontSize--;
|
||||
|
||||
if(int Result = DoButton_Ex(&m_Map.m_vpImages[i], m_Map.m_vpImages[i]->m_aName, Selected, &Slot,
|
||||
BUTTON_CONTEXT, "Select image.", IGraphics::CORNER_ALL, FontSize))
|
||||
{
|
||||
m_SelectedImage = i;
|
||||
|
||||
static int s_PopupImageID = 0;
|
||||
if(Result == 2)
|
||||
{
|
||||
CEditorImage *pImg = m_Map.m_vpImages[m_SelectedImage];
|
||||
int Height;
|
||||
if(pImg->m_External || IsVanillaImage(pImg->m_aName))
|
||||
Height = 60;
|
||||
else
|
||||
Height = 43;
|
||||
UiInvokePopupMenu(&s_PopupImageID, 0, UI()->MouseX(), UI()->MouseY(), 120, Height, PopupImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// separator
|
||||
ToolBox.HSplitTop(5.0f, &Slot, &ToolBox);
|
||||
if(s_ScrollRegion.AddRect(Slot))
|
||||
{
|
||||
IGraphics::CLineItem LineItem(Slot.x, Slot.y + Slot.h / 2, Slot.x + Slot.w, Slot.y + Slot.h / 2);
|
||||
Graphics()->TextureClear();
|
||||
Graphics()->LinesBegin();
|
||||
Graphics()->LinesDraw(&LineItem, 1);
|
||||
Graphics()->LinesEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// new image
|
||||
static int s_NewImageButton = 0;
|
||||
ToolBox.HSplitTop(12.0f, &Slot, &ToolBox);
|
||||
if(DoButton_Editor(&s_NewImageButton, "Add", 0, &Slot, 0, "Load a new image to use in the map"))
|
||||
InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", "", AddImage, this);
|
||||
static int s_AddImageButton = 0;
|
||||
CUIRect AddImageButton;
|
||||
ToolBox.HSplitTop(5.0f + RowHeight + 1.0f, &AddImageButton, &ToolBox);
|
||||
if(s_ScrollRegion.AddRect(AddImageButton))
|
||||
{
|
||||
AddImageButton.HSplitTop(5.0f, nullptr, &AddImageButton);
|
||||
AddImageButton.HSplitTop(RowHeight, &AddImageButton, nullptr);
|
||||
if(DoButton_Editor(&s_AddImageButton, "Add", 0, &AddImageButton, 0, "Load a new image to use in the map"))
|
||||
InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", "", AddImage, this);
|
||||
}
|
||||
s_ScrollRegion.End();
|
||||
}
|
||||
|
||||
void CEditor::RenderSounds(CUIRect ToolBox, CUIRect View)
|
||||
void CEditor::RenderSelectedImage(CUIRect View)
|
||||
{
|
||||
if(m_SelectedImage < 0 || (size_t)m_SelectedImage >= m_Map.m_vpImages.size())
|
||||
return;
|
||||
|
||||
View.Margin(10.0f, &View);
|
||||
if(View.h < View.w)
|
||||
View.w = View.h;
|
||||
else
|
||||
View.h = View.w;
|
||||
float Max = maximum<float>(m_Map.m_vpImages[m_SelectedImage]->m_Width, m_Map.m_vpImages[m_SelectedImage]->m_Height);
|
||||
View.w *= m_Map.m_vpImages[m_SelectedImage]->m_Width / Max;
|
||||
View.h *= m_Map.m_vpImages[m_SelectedImage]->m_Height / Max;
|
||||
Graphics()->TextureSet(m_Map.m_vpImages[m_SelectedImage]->m_Texture);
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->WrapClamp();
|
||||
Graphics()->QuadsBegin();
|
||||
IGraphics::CQuadItem QuadItem(View.x, View.y, View.w, View.h);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
Graphics()->WrapNormal();
|
||||
}
|
||||
|
||||
void CEditor::RenderSounds(CUIRect ToolBox)
|
||||
{
|
||||
static float s_ScrollValue = 0;
|
||||
float SoundsHeight = 30.0f + 14.0f * m_Map.m_vpSounds.size() + 27.0f;
|
||||
|
@ -5902,7 +5870,10 @@ void CEditor::Render()
|
|||
if(m_Mode == MODE_LAYERS)
|
||||
RenderLayers(ToolBox);
|
||||
else if(m_Mode == MODE_IMAGES)
|
||||
RenderImages(ToolBox, View);
|
||||
{
|
||||
RenderImagesList(ToolBox);
|
||||
RenderSelectedImage(View);
|
||||
}
|
||||
else if(m_Mode == MODE_SOUNDS)
|
||||
RenderSounds(ToolBox, View);
|
||||
}
|
||||
|
|
|
@ -1127,7 +1127,8 @@ public:
|
|||
bool IsEnvelopeUsed(int EnvelopeIndex) const;
|
||||
|
||||
void RenderLayers(CUIRect LayersBox);
|
||||
void RenderImages(CUIRect Toolbox, CUIRect View);
|
||||
void RenderImagesList(CUIRect Toolbox);
|
||||
void RenderSelectedImage(CUIRect View);
|
||||
void RenderSounds(CUIRect Toolbox, CUIRect View);
|
||||
void RenderModebar(CUIRect View);
|
||||
void RenderStatusbar(CUIRect View);
|
||||
|
|
Loading…
Reference in a new issue