Generalised UI slider-drawing code

This commit is contained in:
Maruno17
2024-09-19 23:08:25 +01:00
parent 2816cbcd92
commit 44c4a50a1a
3 changed files with 91 additions and 70 deletions

View File

@@ -135,6 +135,66 @@ module UI
end
end
SLIDER_COORDS = { # Size of elements in slider graphic
:arrow_size => [24, 28],
:box_heights => [4, 8, 18] # Heights of top, middle and bottom segments of slider box
}
# slider_height includes the heights of the arrows at either end.
def draw_slider(bitmap, slider_x, slider_y, slider_height, visible_top, visible_height, total_height, hide_if_inactive: :false, overlay: :overlay)
coords = self.class::SLIDER_COORDS
bar_y = slider_y + coords[:arrow_size][1]
bar_height = slider_height - (2 * coords[:arrow_size][1])
bar_segment_height = coords[:box_heights].sum # Also minimum height of slider box
show_up_arrow = (visible_top > 0)
show_down_arrow = (visible_top + visible_height < total_height)
return if hide_if_inactive && !show_up_arrow && !show_down_arrow
# Draw up arrow
x_offset = (show_up_arrow) ? coords[:arrow_size][0] : 0
draw_image(bitmap, slider_x, slider_y,
x_offset, 0, *coords[:arrow_size], overlay: overlay)
# Draw down arrow
x_offset = (show_down_arrow) ? coords[:arrow_size][0] : 0
draw_image(bitmap, slider_x, slider_y + slider_height - coords[:arrow_size][1],
x_offset, coords[:arrow_size][1] + bar_segment_height, *coords[:arrow_size], overlay: overlay)
# Draw bar background
iterations = (bar_height / bar_segment_height.to_f).ceil
iterations.times do |i|
segment_y = bar_y + (i * bar_segment_height)
iteration_height = bar_segment_height
iteration_height = bar_height - (i * bar_segment_height) if i == iterations - 1 # Last part
draw_image(bitmap, slider_x, segment_y,
0, coords[:arrow_size][1], coords[:arrow_size][0], iteration_height, overlay: overlay)
end
# Draw slider box
if show_up_arrow || show_down_arrow
box_height = (bar_height * visible_height / total_height).floor
box_height += [(bar_height - box_height) / 2, bar_height / 6].min # Make it bigger than expected
box_height = [box_height.floor, bar_segment_height].max
box_y = bar_y
box_y += ((bar_height - box_height) * visible_top / (total_height - visible_height)).floor
# Draw slider box top
draw_image(bitmap, slider_x, box_y,
coords[:arrow_size][0], coords[:arrow_size][1],
coords[:arrow_size][0], coords[:box_heights][0], overlay: overlay)
# Draw slider box middle
middle_height = box_height - coords[:box_heights][0] - coords[:box_heights][2]
iterations = (middle_height / coords[:box_heights][1].to_f).ceil
iterations.times do |i|
segment_y = box_y + coords[:box_heights][0] + (i * coords[:box_heights][1])
iteration_height = coords[:box_heights][1]
iteration_height = middle_height - (i * coords[:box_heights][1]) if i == iterations - 1 # Last part
draw_image(bitmap, slider_x, segment_y,
coords[:arrow_size][0], coords[:arrow_size][1] + coords[:box_heights][0],
coords[:arrow_size][0], iteration_height, overlay: overlay)
end
# Draw slider box bottom
draw_image(bitmap, slider_x, box_y + box_height - coords[:box_heights][2],
coords[:arrow_size][0], coords[:arrow_size][1] + coords[:box_heights][0] + coords[:box_heights][1],
coords[:arrow_size][0], coords[:box_heights][2], overlay: overlay)
end
end
#---------------------------------------------------------------------------
# Redraw everything on the screen.

View File

@@ -51,6 +51,14 @@ class UI::BagVisualsList < Window_DrawableCommand
@disable_sorting = value
end
def switching_base_color=(value)
@switching_base_color = value
end
def switching_shadow_color=(value)
@switching_shadow_color = value
end
#-----------------------------------------------------------------------------
# Custom method that allows for an extra option to be displayed above and
@@ -84,14 +92,6 @@ class UI::BagVisualsList < Window_DrawableCommand
drawCursor(self.index, itemRect(self.index))
end
def switching_base_color=(value)
@switching_base_color = value
end
def switching_shadow_color=(value)
@switching_shadow_color = value
end
def drawItem(index, _count, rect)
textpos = []
rect = Rect.new(rect.x + 16, rect.y + 16, rect.width - 16, rect.height)
@@ -170,12 +170,14 @@ class UI::BagVisuals < UI::BaseVisuals
GRAPHICS_FOLDER = "Bag/" # Subfolder in Graphics/UI
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
:default => [Color.new(248, 248, 248), Color.new(56, 56, 56)], # Base and shadow colour
# :white => [Color.new(248, 248, 248), Color.new(104, 104, 104)], # Summary screen's white
# :black => [Color.new(64, 64, 64), Color.new(176, 176, 176)] # Summary screen's black
:white => [Color.new(248, 248, 248), Color.new(56, 56, 56)],
:black => [Color.new(88, 88, 80), Color.new(168, 184, 184)],
:switching => [Color.new(224, 0, 0), Color.new(248, 144, 144)]
}
SLIDER_COORDS = { # Size of elements in slider graphic
:arrow_size => [24, 28],
:box_heights => [4, 8, 18] # Heights of top, middle and bottom segments of slider box
}
ITEMS_VISIBLE = 6
def initialize(bag, mode = :normal)
@@ -509,63 +511,16 @@ class UI::BagVisuals < UI::BaseVisuals
@sprites[:item_list].refresh
end
# TODO: Probably turn this method into a helper method. Put the defined values
# in constants so that initializing the slider overlay can use them to
# automatically determine its size.
def refresh_slider
@sprites[:slider_overlay].bitmap.clear
# Define useful values
slider_rects = {
:up_arrow => [0, 0, 24, 28],
:down_arrow => [0, 28, 24, 28],
:box_top => [24, 0, 24, 4],
:box_middle => [24, 4, 24, 8],
:box_bottom => [24, 12, 24, 18]
}
slider_x = 0
slider_y = slider_rects[:up_arrow][3]
slider_height = 168
min_box_height = slider_rects[:box_top][3] + slider_rects[:box_middle][3] + slider_rects[:box_bottom][3]
# Draw things
show_slider = false
# Draw slider up arrow
if @sprites[:item_list].top_row > 0
draw_image(@bitmaps[:slider], slider_x, slider_y - slider_rects[:up_arrow][3],
*slider_rects[:up_arrow], overlay: :slider_overlay)
show_slider = true
end
# Draw slider down arrow
if @sprites[:item_list].top_item + @sprites[:item_list].page_item_max < @sprites[:item_list].itemCount
draw_image(@bitmaps[:slider], slider_x, slider_y + slider_height,
*slider_rects[:down_arrow], overlay: :slider_overlay)
show_slider = true
end
# Draw slider box
if show_slider
box_height = (slider_height * @sprites[:item_list].page_row_max / @sprites[:item_list].row_max).floor
box_height += [(slider_height - box_height) / 2, slider_height / 6].min # Make it bigger than expected
box_height = [box_height.floor, min_box_height].max
box_y = slider_rects[:up_arrow][3]
box_y += ((slider_height - box_height) * @sprites[:item_list].top_row / (@sprites[:item_list].row_max - @sprites[:item_list].page_row_max)).floor
# Draw slider box top
draw_image(@bitmaps[:slider], slider_x, box_y,
*slider_rects[:box_top], overlay: :slider_overlay)
# Draw slider box middle
middle_height = box_height - slider_rects[:box_top][3] - slider_rects[:box_bottom][3]
iterations = (middle_height / slider_rects[:box_middle][3].to_f).ceil
iterations.times do |i|
segment_y = box_y + slider_rects[:box_top][3] + (i * slider_rects[:box_middle][3])
box_middle_rect = slider_rects[:box_middle].clone
if i == iterations - 1 # Last part
box_middle_rect[3] = middle_height - (i * slider_rects[:box_middle][3])
end
draw_image(@bitmaps[:slider], slider_x, segment_y,
*box_middle_rect, overlay: :slider_overlay)
end
# Draw slider box bottom
draw_image(@bitmaps[:slider], slider_x, box_y + box_height - slider_rects[:box_bottom][3],
*slider_rects[:box_bottom], overlay: :slider_overlay)
end
slider_x = 0
slider_y = 0
slider_height = 224 # Includes heights of arrows at either end
visible_top = @sprites[:item_list].top_row
visible_height = @sprites[:item_list].page_row_max
total_height = @sprites[:item_list].row_max
draw_slider(@bitmaps[:slider], slider_x, slider_y, slider_height,
visible_top, visible_height, total_height, overlay: :slider_overlay)
end
def refresh_selected_item

View File

@@ -55,11 +55,17 @@ class UI::TrainerCardVisuals < UI::BaseVisuals
play_time_text = (hour > 0) ? _INTL("{1}h {2}m", hour, min) : _INTL("{1}m", min)
# Create start date text
$PokemonGlobal.startTime = Time.now if !$PokemonGlobal.startTime
# TODO: Put this date the proper way round for non-United States of Americans.
start_date_text = _INTL("{1} {2}, {3}",
pbGetAbbrevMonthName($PokemonGlobal.startTime.mon),
$PokemonGlobal.startTime.day,
$PokemonGlobal.startTime.year)
if System.user_language[3..4] == "US"
start_date_text = _INTL("{1} {2}, {3}",
pbGetAbbrevMonthName($PokemonGlobal.startTime.mon),
$PokemonGlobal.startTime.day,
$PokemonGlobal.startTime.year)
else
start_date_text = _INTL("{1} {2}, {3}",
$PokemonGlobal.startTime.day,
pbGetAbbrevMonthName($PokemonGlobal.startTime.mon),
$PokemonGlobal.startTime.year)
end
# Draw text
draw_text(_INTL("Money"), 34, 118)
draw_text(money_text, 302, 118, align: :right)