Browse Source

Designed a scalable image for the scroll knob.

David Piuva 5 years ago
parent
commit
11a400c82b

+ 27 - 0
Source/DFPSR/gui/VisualTheme.cpp

@@ -125,6 +125,33 @@ BEGIN: ScrollButton
 	PACK_RGBA: colorImage, redImage, greenImage, blueImage, 255
 	PACK_RGBA: colorImage, redImage, greenImage, blueImage, 255
 	END:
 	END:
 
 
+BEGIN: ScrollKnob
+	INPUT: FixedPoint, width
+	INPUT: FixedPoint, height
+	INPUT: FixedPoint, pressed
+	INPUT: FixedPoint, red
+	INPUT: FixedPoint, green
+	INPUT: FixedPoint, blue
+	OUTPUT: ImageRgbaU8, colorImage
+	# Scale by 2 / 255 so that 127.5 represents full intensity in patternImage
+	MUL: normRed<FixedPoint>, red, 0.007843138
+	MUL: normGreen<FixedPoint>, green, 0.007843138
+	MUL: normBlue<FixedPoint>, blue, 0.007843138
+	CREATE: patternImage<ImageU8>, width, height
+	MUL: pressDarknessHigh<FixedPoint>, pressed, 80
+	MUL: pressDarknessLow<FixedPoint>, pressed, 10
+	SUB: highLuma<FixedPoint>, 150, pressDarknessHigh
+	SUB: lowLuma<FixedPoint>, 100, pressDarknessLow
+	FADE_LINEAR: patternImage,  0, 0, highLuma,  0, height, lowLuma
+	CALL: generate_rounded_rectangle, lumaImage<ImageU8>, width, height, 5, 1
+	MUL: lumaImage, lumaImage, patternImage, 0.003921569
+	CALL: generate_rounded_rectangle, visImage<ImageU8>, width, height, 5, 0
+	MUL: redImage<ImageU8>, lumaImage, normRed
+	MUL: greenImage<ImageU8>, lumaImage, normGreen
+	MUL: blueImage<ImageU8>, lumaImage, normBlue
+	PACK_RGBA: colorImage, redImage, greenImage, blueImage, visImage
+	END:
+
 BEGIN: Panel
 BEGIN: Panel
 	INPUT: FixedPoint, width
 	INPUT: FixedPoint, width
 	INPUT: FixedPoint, height
 	INPUT: FixedPoint, height

+ 19 - 12
Source/DFPSR/gui/components/ListBox.cpp

@@ -61,7 +61,6 @@ static const int textBorderTop = 4;
 static const int scrollWidth = 16; // The width of the scroll bar
 static const int scrollWidth = 16; // The width of the scroll bar
 static const int scrollEndHeight = 14; // The height of upper and lower scroll buttons
 static const int scrollEndHeight = 14; // The height of upper and lower scroll buttons
 static const int border = 1; // Scroll-bar edge thickness
 static const int border = 1; // Scroll-bar edge thickness
-static const int knobErosion = border; // Scroll-bar knob erosion
 
 
 void ListBox::generateGraphics() {
 void ListBox::generateGraphics() {
 	int width = this->location.width();
 	int width = this->location.width();
@@ -70,7 +69,8 @@ void ListBox::generateGraphics() {
 	if (height < 1) { height = 1; }
 	if (height < 1) { height = 1; }
 	if (!this->hasImages) {
 	if (!this->hasImages) {
 		this->completeAssets();
 		this->completeAssets();
-	 	this->scalableImage_listBox(width, height, this->color.value.red, this->color.value.green, this->color.value.blue)(this->image);
+		ColorRgbI32 color = this->color.value;
+	 	this->scalableImage_listBox(width, height, color.red, color.green, color.blue)(this->image);
 		int verticalStep = font_getSize(this->font);
 		int verticalStep = font_getSize(this->font);
 		int left = textBorderLeft;
 		int left = textBorderLeft;
 		int top = textBorderTop;
 		int top = textBorderTop;
@@ -90,21 +90,27 @@ void ListBox::generateGraphics() {
 			top += verticalStep;
 			top += verticalStep;
 		}
 		}
 		if (this->hasVerticalScroll) {
 		if (this->hasVerticalScroll) {
-			ColorRgbaI32 buttonColor = ColorRgbaI32(this->color.value, 255);
-			ColorRgbaI32 barColor = ColorRgbaI32(this->color.value.red / 2, this->color.value.green / 2, this->color.value.blue / 2, 255);
+			ColorRgbaI32 buttonColor = ColorRgbaI32(color, 255);
+			ColorRgbaI32 barColor = ColorRgbaI32(color.red / 2, color.green / 2, color.blue / 2, 255);
 			ColorRgbaI32 borderColor = ColorRgbaI32(0, 0, 0, 255);
 			ColorRgbaI32 borderColor = ColorRgbaI32(0, 0, 0, 255);
 			IRect whole = IRect(this->location.width() - scrollWidth, 0, scrollWidth, this->location.height());
 			IRect whole = IRect(this->location.width() - scrollWidth, 0, scrollWidth, this->location.height());
 			IRect upper = IRect(whole.left(), whole.top(), whole.width(), scrollEndHeight);
 			IRect upper = IRect(whole.left(), whole.top(), whole.width(), scrollEndHeight);
 			IRect middle = IRect(whole.left() + border, whole.top() + scrollEndHeight + border, whole.width() - border * 2, whole.height() - (border + scrollEndHeight) * 2);
 			IRect middle = IRect(whole.left() + border, whole.top() + scrollEndHeight + border, whole.width() - border * 2, whole.height() - (border + scrollEndHeight) * 2);
 			IRect lower = IRect(whole.left(), whole.bottom() - scrollEndHeight, whole.width(), scrollEndHeight);
 			IRect lower = IRect(whole.left(), whole.bottom() - scrollEndHeight, whole.width(), scrollEndHeight);
 			IRect knob = this->getKnobLocation();
 			IRect knob = this->getKnobLocation();
+			// Only redraw the knob image if its dimensions changed
+			if (!image_exists(this->scrollKnob_normal)
+			  || image_getWidth(this->scrollKnob_normal) != knob.width()
+			  || image_getHeight(this->scrollKnob_normal) != knob.height()) {
+				this->scalableImage_scrollKnob(knob.width(), knob.height(), false, color.red, color.green, color.blue)(this->scrollKnob_normal);
+			}
 			// Scroll-bar
 			// Scroll-bar
 			draw_rectangle(this->image, whole, borderColor);
 			draw_rectangle(this->image, whole, borderColor);
 			draw_rectangle(this->image, upper, buttonColor);
 			draw_rectangle(this->image, upper, buttonColor);
 			draw_rectangle(this->image, middle, barColor);
 			draw_rectangle(this->image, middle, barColor);
 			draw_rectangle(this->image, lower, buttonColor);
 			draw_rectangle(this->image, lower, buttonColor);
-			draw_rectangle(this->image, knob, buttonColor);
 			draw_copy(this->image, (this->pressScrollUp) ? this->scrollButtonTop_pressed : this->scrollButtonTop_normal, upper.left(), upper.top());
 			draw_copy(this->image, (this->pressScrollUp) ? this->scrollButtonTop_pressed : this->scrollButtonTop_normal, upper.left(), upper.top());
+			draw_alphaFilter(this->image, this->scrollKnob_normal, knob.left(), knob.top());
 			draw_copy(this->image, (this->pressScrollDown && this->inside) ? this->scrollButtonBottom_pressed : this->scrollButtonBottom_normal, lower.left(), lower.top());
 			draw_copy(this->image, (this->pressScrollDown && this->inside) ? this->scrollButtonBottom_pressed : this->scrollButtonBottom_normal, lower.left(), lower.top());
 		}
 		}
 		this->hasImages = true;
 		this->hasImages = true;
@@ -217,6 +223,7 @@ void ListBox::receiveKeyboardEvent(const KeyboardEvent& event) {
 void ListBox::loadTheme(VisualTheme theme) {
 void ListBox::loadTheme(VisualTheme theme) {
 	this->scalableImage_listBox = theme_getScalableImage(theme, U"ListBox");
 	this->scalableImage_listBox = theme_getScalableImage(theme, U"ListBox");
 	this->scalableImage_scrollButton = theme_getScalableImage(theme, U"ScrollButton");
 	this->scalableImage_scrollButton = theme_getScalableImage(theme, U"ScrollButton");
+	this->scalableImage_scrollKnob = theme_getScalableImage(theme, U"ScrollKnob");
 	// Generate fixed size buttons for the scroll buttons (because their size is currently given by constants)
 	// Generate fixed size buttons for the scroll buttons (because their size is currently given by constants)
 	ColorRgbI32 color = this->color.value;
 	ColorRgbI32 color = this->color.value;
 	this->scalableImage_scrollButton(scrollWidth, scrollEndHeight, false, color.red, color.green, color.blue)(this->scrollButtonTop_normal);
 	this->scalableImage_scrollButton(scrollWidth, scrollEndHeight, false, color.red, color.green, color.blue)(this->scrollButtonTop_normal);
@@ -306,21 +313,21 @@ IRect ListBox::getScrollBarLocation_excludingButtons() {
 IRect ListBox::getKnobLocation() {
 IRect ListBox::getKnobLocation() {
 	// Eroded scroll-bar excluding buttons
 	// Eroded scroll-bar excluding buttons
 	// The final knob is a sub-set of this region corresponding to the visibility
 	// The final knob is a sub-set of this region corresponding to the visibility
-	IRect erodedBar = this->getScrollBarLocation_excludingButtons().expanded(-knobErosion);
+	IRect scrollBarRegion = this->getScrollBarLocation_excludingButtons();
 	// Item ranges
 	// Item ranges
 	int64_t visibleRange = this->getVisibleScrollRange(); // 0..visibleRange-1
 	int64_t visibleRange = this->getVisibleScrollRange(); // 0..visibleRange-1
 	int64_t itemCount = this->list.value.length(); // 0..itemCount-1
 	int64_t itemCount = this->list.value.length(); // 0..itemCount-1
 	int64_t maxScroll = itemCount - visibleRange; // 0..maxScroll
 	int64_t maxScroll = itemCount - visibleRange; // 0..maxScroll
 	// Dimensions
 	// Dimensions
-	int64_t knobHeight = (erodedBar.height() * visibleRange) / itemCount;
-	if (knobHeight < erodedBar.width()) {
-		knobHeight = erodedBar.width();
+	int64_t knobHeight = (scrollBarRegion.height() * visibleRange) / itemCount;
+	if (knobHeight < scrollBarRegion.width()) {
+		knobHeight = scrollBarRegion.width();
 	}
 	}
 	// Visual range for center
 	// Visual range for center
-	int64_t scrollStart = erodedBar.top() + knobHeight / 2;
-	int64_t scrollDistance = erodedBar.height() - knobHeight;
+	int64_t scrollStart = scrollBarRegion.top() + knobHeight / 2;
+	int64_t scrollDistance = scrollBarRegion.height() - knobHeight;
 	int64_t knobCenterY = scrollStart + ((this->firstVisible * scrollDistance) / maxScroll);
 	int64_t knobCenterY = scrollStart + ((this->firstVisible * scrollDistance) / maxScroll);
-	return IRect(erodedBar.left(), knobCenterY - (knobHeight / 2), erodedBar.width(), knobHeight);
+	return IRect(scrollBarRegion.left(), knobCenterY - (knobHeight / 2), scrollBarRegion.width(), knobHeight);
 }
 }
 
 
 // Optional limit of scrolling, to be applied when the user don't explicitly scroll away from the selection
 // Optional limit of scrolling, to be applied when the user don't explicitly scroll away from the selection

+ 2 - 0
Source/DFPSR/gui/components/ListBox.h

@@ -51,12 +51,14 @@ private:
 	// Given from the style
 	// Given from the style
 	MediaMethod scalableImage_listBox;
 	MediaMethod scalableImage_listBox;
 	MediaMethod scalableImage_scrollButton;
 	MediaMethod scalableImage_scrollButton;
+	MediaMethod scalableImage_scrollKnob;
 	RasterFont font;
 	RasterFont font;
 	void completeAssets();
 	void completeAssets();
 	void generateGraphics();
 	void generateGraphics();
 	// Generated
 	// Generated
 	bool hasImages = false;
 	bool hasImages = false;
 	OrderedImageRgbaU8 scrollButtonTop_normal, scrollButtonTop_pressed, scrollButtonBottom_normal, scrollButtonBottom_pressed;
 	OrderedImageRgbaU8 scrollButtonTop_normal, scrollButtonTop_pressed, scrollButtonBottom_normal, scrollButtonBottom_pressed;
+	OrderedImageRgbaU8 scrollKnob_normal;
 	OrderedImageRgbaU8 image;
 	OrderedImageRgbaU8 image;
 	// Helper methods
 	// Helper methods
 	// Returns the selected index referring to an existing element or -1 if none is selected
 	// Returns the selected index referring to an existing element or -1 if none is selected