Gw Temp


Tutorial - 'User Friendly CMS III: Scrollbar' by Jerm

An item about RPGMaker 2000 posted on


Part three in Jerm's CMS tutorials, this time on navigation!


User Friendly CMS III: Scrollbar

Well, we've created a list that organizes and structures itself, and a means to navigate it. Now it's time to get a little cosmetic, but hopefully not in a gratuitous way. In part 3, we're going to create a scrollbar that will tell us where in the list we currently are and disappear when the number of items no longer exceeds the space limit.

If for some reason you're not sure what a scrollbar is, just look to the right side of your browser. I'm sure this tutorial will be more than a page long, so it should be there. At the top is the happy little up arrow, with the sad little down arrow at the bottom. And in between is the rectangle/box (depends) that at the moment will probably be cuddling with the up arrow (which is why it's so happy).

Problem #1 with this tutorial however; it's very number heavy. Not just that, there's sometimes a bit of guesswork in figuring these numbers out. You may have to do a test run or two to make the necessary adjustments. So this will be an EXCITING tutorial. Unless it's not. Anyway, time to quit stalling and start.

The coding itself is extremely short, good news. The problem is figuring out the specifics of the coding. Hence the "number heavy" part. To start, we will need to create two images, and three variables.

The first of the two images will be the Scroll Bar Arrows. The up arrow and down arrow at the top and bottom respectively. But how far apart? Yeah, numbers time. Okay, in this demo menu, we had 5 visible item images that are 16 pixels tall. So 16*5 would be 80. Pic:[ScrollBarArrows] would match that, so the dimensions of Pic:[ScrollBarArrows] would be 80 pixels tall. That's an easy number to find. The width isn't nearly as important, just make it narrow enough that it doesn't fight for room with the item images. Put the up arrow icon at the top, the down arrow icon at the bottom and fill the middle with beautiful, vivid empty space.

Image #2 is the scrollbar picture itself. It's dimensions don't really matter, but I'd recommend, making it as wide as Pic:[ScrollBarArrows], and as tall as it is wide. Because you can't stretch an image vertically or horizontally (independently) in RM2k3, so it's going to remain static.

The variables? Well, two are the X and Y coordinates that will be needed to find where Pic:[ScrollBar] will be placed. So Var:[Scroll X] and Var:[Scroll Y]. The third, you've probably already created it already, probably with another name. Var:[Back-Up]. It's purpose will be to take the place of another variable that's going to be multiplied/divided/added/subtracted to a point where you can't regain the original number afterwards.

So now for the coding. Since I'm suddenly feeling lazy, I'll just cut and paste the finished code from part II of this series and insert the new coding into the place it belongs:

(1) Variable Oper: [Scroll Slot] Set, 1
(2) Variable Oper: [Current Slot] Set, 1
(3) Variable Oper: [Menu X] Set, 25
(4) Variable Oper: [Menu Y] Set, 50
(5) Show Picture: 1, (V[Menu X],V[Menu Y])
(6) Loop
(7) Move Picture: 1, (V[Menu X],V[Menu Y]), 0.1 Sec (No Wait)
(8) Call Event: Item Organizer[1]
(9) Branch if Var [Max Slot] is 6 or more
(9.1) Variable Oper: [Scroll X] set, ???
(9.2) Variable Oper: [Scroll Y] set, ???
(9.3) Variable Oper: [Back-Up] set, Var [Scroll Slot]'s Value
(9.4) Variable Oper: [Back-Up] -, 1
(9.5) Variable Oper: [Max Slot] -, 5
(9.6) Variable Oper: [Back-Up] *, 100
(9.7) Variable Oper: [Back-Up] /, Var [Max Slot]'s Value
(9.8) Variable Oper: [Back-Up] *, ???
(9.9) Variable Oper: [Back-Up] /, 100
(9.A) Variable Oper: [Scroll Y] +, Var [Back-Up]'s Value
(9.B) Variable Oper: [Max Slot] +, 5
(9.C) Show Picture: 7, (???,???)
(9.D) Show Picture: 8, (V[Scroll X],V[Scroll Y])
(10) Else Handler
(10.1) Erase Picture: 7
(10.2) Erase Picture: 8
(11) Variable Oper: [PASSWORD] Set, 0
(12) Wait: 0.1 Sec
(13) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(14) Branch if Var [PASSWORD] is 1 or more
(14.1) Branch if Switch [CURSOR PAUSE] is OFF
(14.11) Switch Operation: [CURSOR PAUSE] ON
(14.12) Variable Oper: [PASSWORD] Set, 0
(14.13) Wait: 0.2 Sec
(14.14) Key Input Proc: [PASSWORD] (1,2,3,4) (No Wait)
(14.2) Jump to Label: 1
(15) Key Input Proc: [PASSWORD] (1,2,3,4,5,6) (Wait)
(16) Switch Operation: [CURSOR PAUSE] OFF
(17) Label: 1
(18) Branch if Var [PASSWORD] is 1
(18.1) Branch if Var [Current Slot] is Var [Max Slot] Equal
(18.11) Variable Oper: [Current Slot] Set, 1
(18.12) Variable Oper: [Scroll Slot] Set, 1
(18.13) Variable Oper: [Menu Y] Set, 50
(18.2) Else Handler
(18.21) Branch if Var [Menu Y] is 114
(18.211) Variable Oper: [Scroll Slot] Set, 1
(18.212) Variable Oper: [Current Slot] Set, 1
(18.22) Else Handler
(18.221) Variable Oper: [Current Slot] +, 1
(18.222) Variable Oper: [Menu Y] +, 16
(19) Branch if Var [PASSWORD] is 2
(20) Branch if Var [PASSWORD] is 3
(21) Branch if Var [PASSWORD] is 4
(21.1) Branch if Var [Menu Y] is 50
(21.11) Branch if Var [Current Slot] is 1
(21.111) Variable Oper: [Scroll Slot] Set, Var:[Max Slot]
(21.112) Variable Oper: [Current Slot] Set, Var:[Max Slot]
(21.113) Branch if Var [Max Slot] is 5 or more
(21.1131) Variable Oper: [Scroll Slot] -, 4
(21.1132) Variable Oper: [Menu Y] Set, 114
(21.114) Else Handler
(21.1141) Variable Oper: [Scroll Slot] Set, 1
(21.1142) Branch if Var [Max Slot] is 4
(21.11421) Variable Oper: [Menu Y] Set, 98
(21.1143) Branch if Var [Max Slot] is 3
(21.11431) Variable Oper: [Menu Y] Set, 82
(21.1144) Branch if Var [Max Slot] is 2
(21.11441) Variable Oper: [Menu Y] Set, 66
(21.1145) Branch if Var [Max Slot] is 1
(21.11451) Variable Oper: [Menu Y] Set, 50
(21.12) Else Handler
(21.121) Variable Oper: [Scroll Slot] -, 1
(21.122) Variable Oper: [Current Slot] -, 1
(21.2) Else Handler
(21.21) Variable Oper: [Current Slot] -, 1
(21.22) Variable Oper: [Menu Y] -, 16
(22) Branch if Var [PASSWORD] is 5
(23) Branch if Var [PASSWORD] is 6
(24) End Loop

Lines (9) - (10.2) are new. And very short, you'll notice. Also, you will probably notice a lot of ???'s hiding in there. We'll get to those numbers in due time. Instead, let's start at the top.

In line (9), it merely sets up the question is Var:[Max Slot] more than five, since a scrollbar would not be necessary if all items are already visible. In this fake menu only five items can appear at once, but the number will change to accomodate other menus, of course.

Jumping down to lines (10) - (10.2) to get them out of the way, the two scrollbar pictures are deleted if Var:[Max Slot] is 5 or less.

Lines (9.1) and (9.2) begin next, and we finally get to the ???'s. Hooray. Var:[Scroll X] will be static after it's placed, as Pic:[ScrollBar] only moves up and down, so figuring it out is a bit easier. It's number will be such that the picture that will end up using the variable for placement is to the far right of the menu list. Mentioned in previous parts of this tutorial, the X coordinate centering for the cursor was 25. So the item image it would highlight couldn't be more than 50 pixels long (without being pushed off the left side of the screen. So for this demo, let's say the width of the item images (and cursor) are 48 pixels. This would give a buffer of 1 pixel from the left wall (and also keep it from getting confused with the Y coordinate, which is 50 at the top of the list). So 48 pixels wide and centered at X coordinate: 25. That would put the right tip at X coordinate: 49 ((48 / 2) + 25). Now give a bit of space between the items and the scrollbar, let's say 16 pixels (the width of a tile). Now we're at 65. But the image needs to be centered at that spot, so a little bit more to go. Let's say both pictures (Pic:[ScrollBarArrows] and Pic:[ScrollBar]) in this demo are 8 pixels wide. So 65 + 8 will put us at 73. Var:[Scroll X] = 73.

For (9.2), Var:[Scroll Y] will be a little easier to figure out initially, before the adjustments made below. It's starting point will be it's highest possible spot to be. So now for some more numbers. Since Pic:[ScrollBar] will be 8 pixels wide here, let's make it 8 pixels tall as well. This will be needed imformation for spacing.

As per earlier, the final height of the entire demo menu is 80 pixels tall (16*5) and the top item is centered at 50. CENTERED at 50. To find the real top, just take the image height (16 pixels), and take out half of it. So the top of the menu is 42 (50 - (16 / 2)). From there we start heading back down. We want Pic:[ScrollBar] to be centered so that it doesn't go higher than the top to start with, so let's drop back down half of it's height (8 / 2 = 4) which will put us at 46. But now it overlaps the up arrow from Pic:[ScrollBarArrows]. So we descend again. Let's say for this demo the up and down arrows are both 8 pixels tall as well. So we will drop down 8 more pixels to 54. So Var:[Scroll Y] = 54.

Now we hit line (9.3), and Var:[Back-Up] is set to Var:[Scroll Slot]. To determine the final resting point of Var:[Scroll Y], we have to compare Var:[Scroll Slot] to Var:[Max Slot].

First thing's first though, we have to make two adjustments. In line (9.4) Var:[Back-Up] goes down a point. This is so that if it (posing as Var:[Scroll Slot]) is 1 (at the top), turning it to 0 will insure that 0 is added to Var:[Scroll Y] in line (9.A). If it remained as one, then Pic:[ScrollBar] would never reach the top. As something would still be added to the default location.

To match this, 1 is subtracted from Var:[Max Slot] as well in line (9.5)... But the line says 5 is subtracted there. This is because of another adjustment. Along with the 1 needed to pace Var:[Scroll Slot], 4 more are subtracted. While the 1 is to insure no bugs at the top of the scrollbar, subtracting 4 from Var:[Max Slot] secures the bottom. If you'll remember, the max of Var:[Scroll Slot] is always Var:[Max Slot] subtracted by one less than how many items can appear on the screen at once. As five items can appear simultaneously in this demo, the difference is 4. So Var:[Max Slot] would descend 4. Without this, Pic:[ScrollBar] would never reach the bottom.

Next is (9.6), and it is connected with (9.9). These may seem silly initially, as they cancel each other out. But the main purpose is because RM2k3 doesn't use decimals. By inflating Var:[Back-Up], it will insure that rounding off won't take as big a bite out of the final number in the end.

To be more specific about this formula, the purpose of lines (9.6) - (9.9) (all four of them) is to turn the ratio of Var:[Back-Up] and Var:[Max Slot] into a percentage. This will be played against the distance between the up and down arrows, causing Pic:[ScrollBar] to move up and down accordingly to how Var:[Scroll Slot] compares to Var:[Max Slot].

Which brings us to line (9.7), where said distance finally rears its ugly head. This was the part that gave me the most trouble when creating this. To find this number, you have to find the distance between where Pic:[ScrollBar] can be centered at the top, and where it can be centered at the bottom.

Soooo... Seven paragraphs above, we determined that it is centered at the top at 54. To determine where it is centered at the bottom, we take that same formula, but apply it in reverse. The very tippy top pixel of the menu list is located at 42. WE drop down the length of the list (80 pixels), so the bottom is 122. Pic:[ScrollBar] is eight pixels tall so we go up half that to 118, and then up 8 more (for the height of the down arrow) to 110. So the difference between 110 and 54 would be 56.

An easier way to find that? Now that we've done it the hard way, let's try this. The list is 80 pixels tall, Up and down arrow icons within Pic:[ScrollBarArrows] are 8 pixels tall, as is Pic:[ScrollBar]. So subtract the height of the two icons combined and the height of Pic:[ScrollBar]. 80 - (8 + 8 + 8) = 80 - 24 = 56.

So to conclude, line (9.9) readjusts what (9.6) changed, line (9.A) adds the final tally to the starting point, and line (9.B) resets Var:[Max Slot] to where it belongs. Finally lines (9.C) and (9.D) center Pic:[ScrollBar] and Pic:[ScrollBarArrows] where they belong.

But the coordinates of (9.C) haven't been fleshed out yet. They determine where Pic:[ScrollBarArrows] goes. The X coordinate is simple, it'll be the same as Pic:[ScrollBar]'s, which is 73 as determined above. The Y coordinate will be the center of the menu. The top of the menu is at 42, and the bottom is 80 below it, 122. So the middle would be 82. So line (9.C)'s ???'s are X = 73, Y = 82.

And that's that for that. Now you have a bar on the side of the menu that tells you where in the list you are.

Extra notes:

1. For as short as it is, this can get very tricky. To help if you make your own menu on this diagram, open up Notepad and write down all image dimensions and key numbers down in a list. Total item quantity, how many of those items are visible at a time, etc.

2. If you're having trouble with figuring out the spacing, try to keep a mental visual of how your menu will look. I'd recommend as rudimentary a visual as possible, but if you want to pretend all sorts of Photoshop effects in there, go ahead. But they're not imporant yet. If you have a pencil and graph paper handy, even better.

3. Eight images are in use in this demo. #1 is the cursor, #'s 2-6 are the five visible item slots, #'s 7 and 8 are the scrollbar arrows and scrollbar. If any are going to overlap (specifically the cursor), just remember that the image with the higher designated number covers the lower numbered one. So you can rearrange however needed or wanted.

4. There will be a part IV, which will explain how to fix the cursor's place in a list when an item is used up (quantity goes to 0). That should finish this series and then I can start on a new section of the CMS. I have something in mind, but I keep forgetting what it is.

5. I've created a working demo of how all of this functions, including what part IV covers. Littered with Comments/Notes, hopefully it can be more specific as to how these things work. But I won't release it until I'm finished with said part, just in case things change. Also it uses different numbers and spacing than what I've written here and it could become confusing.