Browse Source

DiabloUI: Render scrollbar as PCX

pull/4702/head
Gleb Mazovetskiy 4 years ago
parent
commit
5df03f56e3
  1. 25
      Source/DiabloUI/diabloui.cpp
  2. 20
      Source/DiabloUI/scrollbar.cpp
  3. 25
      Source/DiabloUI/scrollbar.h
  4. 2
      Source/DiabloUI/selgame.cpp
  5. 2
      Source/DiabloUI/selhero.cpp
  6. 2
      Source/DiabloUI/settingsmenu.cpp
  7. 8
      Source/DiabloUI/ui_item.h

25
Source/DiabloUI/diabloui.cpp

@ -891,33 +891,36 @@ void Render(const UiList *uiList)
void Render(const UiScrollbar *uiSb)
{
const Surface out = Surface(DiabloUiSurface());
// Bar background (tiled):
{
const int bgYEnd = DownArrowRect(uiSb).y;
int bgY = uiSb->m_rect.y + uiSb->m_arrow->h();
while (bgY < bgYEnd) {
std::size_t drawH = std::min(bgY + uiSb->m_bg->h(), bgYEnd) - bgY;
DrawArt({ uiSb->m_rect.x, bgY }, uiSb->m_bg, 0, SCROLLBAR_BG_WIDTH, drawH);
bgY += drawH;
const int bgY = uiSb->m_rect.y + uiSb->m_arrow.frameHeight();
const int bgH = DownArrowRect(uiSb).y - bgY;
const Surface backgroundOut = out.subregion(uiSb->m_rect.x, bgY, SCROLLBAR_BG_WIDTH, bgH);
int y = 0;
while (y < bgH) {
RenderPcxSprite(backgroundOut, uiSb->m_bg, { 0, y });
y += uiSb->m_bg.height();
}
}
// Arrows:
{
const SDL_Rect rect = UpArrowRect(uiSb);
const int frame = static_cast<int>(scrollBarState.upArrowPressed ? ScrollBarArrowFrame_UP_ACTIVE : ScrollBarArrowFrame_UP);
DrawArt({ rect.x, rect.y }, uiSb->m_arrow, frame, rect.w);
const auto frame = static_cast<uint16_t>(scrollBarState.upArrowPressed ? ScrollBarArrowFrame_UP_ACTIVE : ScrollBarArrowFrame_UP);
RenderPcxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow.sprite(frame), { 0, rect.y });
}
{
const SDL_Rect rect = DownArrowRect(uiSb);
const int frame = static_cast<int>(scrollBarState.downArrowPressed ? ScrollBarArrowFrame_DOWN_ACTIVE : ScrollBarArrowFrame_DOWN);
DrawArt({ rect.x, rect.y }, uiSb->m_arrow, frame, rect.w);
const auto frame = static_cast<uint16_t>(scrollBarState.downArrowPressed ? ScrollBarArrowFrame_DOWN_ACTIVE : ScrollBarArrowFrame_DOWN);
RenderPcxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow.sprite(frame), { 0, rect.y });
}
// Thumb:
if (SelectedItemMax > 0) {
const SDL_Rect rect = ThumbRect(uiSb, SelectedItem, SelectedItemMax + 1);
DrawArt({ rect.x, rect.y }, uiSb->m_thumb);
RenderPcxSprite(out, uiSb->m_thumb, { rect.x, rect.y });
}
}

20
Source/DiabloUI/scrollbar.cpp

@ -1,23 +1,25 @@
#include "scrollbar.h"
#include "engine/load_pcx.hpp"
namespace devilution {
Art ArtScrollBarBackground;
Art ArtScrollBarThumb;
Art ArtScrollBarArrow;
std::optional<OwnedPcxSprite> ArtScrollBarBackground;
std::optional<OwnedPcxSprite> ArtScrollBarThumb;
std::optional<OwnedPcxSpriteSheet> ArtScrollBarArrow;
void LoadScrollBar()
{
LoadArt("ui_art\\sb_bg.pcx", &ArtScrollBarBackground);
LoadArt("ui_art\\sb_thumb.pcx", &ArtScrollBarThumb);
LoadArt("ui_art\\sb_arrow.pcx", &ArtScrollBarArrow, 4);
ArtScrollBarBackground = LoadPcxAsset("ui_art\\sb_bg.pcx");
ArtScrollBarThumb = LoadPcxAsset("ui_art\\sb_thumb.pcx");
ArtScrollBarArrow = LoadPcxSpriteSheetAsset("ui_art\\sb_arrow.pcx", 4);
}
void UnloadScrollBar()
{
ArtScrollBarArrow.Unload();
ArtScrollBarThumb.Unload();
ArtScrollBarBackground.Unload();
ArtScrollBarArrow = std::nullopt;
ArtScrollBarThumb = std::nullopt;
ArtScrollBarBackground = std::nullopt;
}
} // namespace devilution

25
Source/DiabloUI/scrollbar.h

@ -2,14 +2,14 @@
#include <cstdint>
#include "DiabloUI/art.h"
#include "DiabloUI/ui_item.h"
#include "engine/pcx_sprite.hpp"
namespace devilution {
extern Art ArtScrollBarBackground;
extern Art ArtScrollBarThumb;
extern Art ArtScrollBarArrow;
extern std::optional<OwnedPcxSprite> ArtScrollBarBackground;
extern std::optional<OwnedPcxSprite> ArtScrollBarThumb;
extern std::optional<OwnedPcxSpriteSheet> ArtScrollBarArrow;
const Uint16 SCROLLBAR_BG_WIDTH = 25;
enum ScrollBarArrowFrame : uint8_t {
@ -19,7 +19,6 @@ enum ScrollBarArrowFrame : uint8_t {
ScrollBarArrowFrame_DOWN,
};
extern Art ArtScrollBarThumb;
const Uint16 SCROLLBAR_ARROW_WIDTH = 25;
inline SDL_Rect UpArrowRect(const UiScrollbar *sb)
@ -28,7 +27,7 @@ inline SDL_Rect UpArrowRect(const UiScrollbar *sb)
Tmp.x = sb->m_rect.x;
Tmp.y = sb->m_rect.y;
Tmp.w = SCROLLBAR_ARROW_WIDTH;
Tmp.h = static_cast<Uint16>(sb->m_arrow->h());
Tmp.h = static_cast<Uint16>(sb->m_arrow.frameHeight());
return Tmp;
}
@ -37,23 +36,23 @@ inline SDL_Rect DownArrowRect(const UiScrollbar *sb)
{
SDL_Rect Tmp;
Tmp.x = sb->m_rect.x;
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_rect.h - sb->m_arrow->h());
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_rect.h - sb->m_arrow.frameHeight());
Tmp.w = SCROLLBAR_ARROW_WIDTH,
Tmp.h = static_cast<Uint16>(sb->m_arrow->h());
Tmp.h = static_cast<Uint16>(sb->m_arrow.frameHeight());
return Tmp;
}
inline Uint16 BarHeight(const UiScrollbar *sb)
{
return sb->m_rect.h - 2 * sb->m_arrow->h();
return sb->m_rect.h - 2 * sb->m_arrow.frameHeight();
}
inline SDL_Rect BarRect(const UiScrollbar *sb)
{
SDL_Rect Tmp;
Tmp.x = sb->m_rect.x;
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_arrow->h());
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_arrow.frameHeight());
Tmp.w = SCROLLBAR_ARROW_WIDTH,
Tmp.h = BarHeight(sb);
@ -63,14 +62,14 @@ inline SDL_Rect BarRect(const UiScrollbar *sb)
inline SDL_Rect ThumbRect(const UiScrollbar *sb, std::size_t selected_index, std::size_t num_items)
{
const int THUMB_OFFSET_X = 3;
const int thumb_max_y = BarHeight(sb) - sb->m_thumb->h();
const int thumb_max_y = BarHeight(sb) - sb->m_thumb.height();
const int thumb_y = static_cast<int>(selected_index * thumb_max_y / (num_items - 1));
SDL_Rect Tmp;
Tmp.x = static_cast<Sint16>(sb->m_rect.x + THUMB_OFFSET_X);
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_arrow->h() + thumb_y);
Tmp.y = static_cast<Sint16>(sb->m_rect.y + sb->m_arrow.frameHeight() + thumb_y);
Tmp.w = static_cast<Uint16>(sb->m_rect.w - THUMB_OFFSET_X);
Tmp.h = static_cast<Uint16>(sb->m_thumb->h());
Tmp.h = static_cast<Uint16>(sb->m_thumb.height());
return Tmp;
}

2
Source/DiabloUI/selgame.cpp

@ -125,7 +125,7 @@ void UiInitGameSelectionList(string_view search)
const Point uiPosition = GetUIRectangle().position;
SDL_Rect rectScrollbar = { (Sint16)(uiPosition.x + 590), (Sint16)(uiPosition.y + 244), 25, 178 };
vecSelGameDialog.push_back(std::make_unique<UiScrollbar>(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rectScrollbar));
vecSelGameDialog.push_back(std::make_unique<UiScrollbar>(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, rectScrollbar));
SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 };
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_(ConnectionNames[provider]).c_str(), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));

2
Source/DiabloUI/selhero.cpp

@ -495,7 +495,7 @@ void selhero_List_Init()
vecSelDlgItems.push_back(std::make_unique<UiList>(vecSelHeroDlgItems, 6, uiPosition.x + 265, (uiPosition.y + 256), 320, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold));
SDL_Rect rect2 = { (Sint16)(uiPosition.x + 585), (Sint16)(uiPosition.y + 244), 25, 178 };
vecSelDlgItems.push_back(std::make_unique<UiScrollbar>(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rect2));
vecSelDlgItems.push_back(std::make_unique<UiScrollbar>(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, rect2));
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 239), (Sint16)(uiPosition.y + 429), 120, 35 };
vecSelDlgItems.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect3, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));

2
Source/DiabloUI/settingsmenu.cpp

@ -261,7 +261,7 @@ void UiSettingsMenu()
string_view titleText = shownMenu == ShownMenuType::Settings ? _("Settings") : selectedOption->GetName();
vecDialog.push_back(std::make_unique<UiArtText>(titleText.data(), MakeSdlRect(uiRectangle.position.x, uiRectangle.position.y + 161, uiRectangle.size.width, 35), UiFlags::FontSize30 | UiFlags::ColorUiSilver | UiFlags::AlignCenter, 8));
vecDialog.push_back(std::make_unique<UiScrollbar>(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height)));
vecDialog.push_back(std::make_unique<UiScrollbar>(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height)));
vecDialog.push_back(std::make_unique<UiArtText>(optionDescription, MakeSdlRect(rectDescription), UiFlags::FontSize12 | UiFlags::ColorUiSilverDark | UiFlags::AlignCenter, 1, IsSmallFontTall() ? 22 : 18));
size_t itemToSelect = 1;

8
Source/DiabloUI/ui_item.h

@ -287,7 +287,7 @@ private:
class UiScrollbar : public UiItemBase {
public:
UiScrollbar(Art *bg, Art *thumb, Art *arrow, SDL_Rect rect, UiFlags flags = UiFlags::None)
UiScrollbar(PcxSprite bg, PcxSprite thumb, PcxSpriteSheet arrow, SDL_Rect rect, UiFlags flags = UiFlags::None)
: UiItemBase(UiType::Scrollbar, rect, flags)
, m_bg(bg)
, m_thumb(thumb)
@ -296,9 +296,9 @@ public:
}
// private:
Art *m_bg;
Art *m_thumb;
Art *m_arrow;
PcxSprite m_bg;
PcxSprite m_thumb;
PcxSpriteSheet m_arrow;
};
//=============================================================================

Loading…
Cancel
Save