Book and Scroll GUI

Everything about development and the OpenMW source code.
Locked
User avatar
lgromanowski
Site Admin
Posts: 1193
Joined: 05 Aug 2011, 22:21
Location: Wroclaw, Poland
Contact:

Book and Scroll GUI

Post by lgromanowski »

Zini wrote: Here is my brain dump for the book and scroll GUI:

The window manager class should get a new function, that opens the book and scroll interface. I will hook it up later.

This function should have the follwoing signature:

void viewDocument (const std::string& text, bool scroll, const MWWorld::Ptr& ptr);

The ptr argument will be used when the user clicks on the take-book/scroll button. For now we can't implement this feature. The GUI should store ptr for later usage and write an error message to std::cout (unimplemented feature or something) when the take button is clicked.

The book/scroll interface needs a new GUI mode (see window manager class). But the actual implementation needs to go into a separate class, of which the window manager should have a pointer to or an instance of.
If found desirable books and scrolls can be implemented as two separate classes.

Text in books and scrolls can have some formatting. IIRC a html subset and even with embedded pictures. But that needs to be checked against the MW documentation and MW. I am really not sure, if I remember correctly here.

Also, I am not sure if the same formatting can be applied to the journal. If it can, the layout and formatting implementation should be shared with the journal GUI, which is currently in the planning stage.
ObsidianBlk wrote: I've been working on something for the book GUI for the last couple of hours. So far, I've only really roughed out a xml layout for books and am hacking together a bookWindow class. I'm really very very new and am struggling with how the window will even get called and how I'm going to get the book data.

For the core of the window, I'd only really need the book's text as that's the only really important thing about the book the dialog deals with (I'm assuming the special skill-up and scripting events are triggered just before the dialog itself is). With the text, it's just a matter of hacking it up into "pages" that the user then goes back and forth through using the "prev" and "next" buttons.

As for books vs. scrolls... they're almost the same thing, except a scroll would be more like a scrolling text window without "prev" or "next" page buttons. If there's a) a way to identify a book vs a scroll and b) a way to switch between GUI layouts then they could both be handled by the same class, with little issue, I would think.

I do know some books have images but little else in the way of formatting. As for scrolls, I do not recall a single one that's even in a readable language. Usually just glyphs (as a font or image, I do not know).
Star-Demon wrote: @pictures:

HTML. The whole thing is just HTML.

@scrolls: scrolls use a language tag to change language.\

There are many scrolls written in english and/or deadric.
Zini wrote:
I've been working on something for the book GUI for the last couple of hours. So far, I've only really roughed out a xml layout for books and am hacking together a bookWindow class. I'm really very very new and am struggling with how the window will even get called and how I'm going to get the book data.
Quoting myself:
The window manager class should get a new function, that opens the book and scroll interface. I will hook it up later.

This function should have the follwoing signature:

void viewDocument (const std::string& text, bool scroll, const MWWorld::Ptr& ptr);
Zini wrote:
The window manager class should get a new function, that opens the book and scroll interface. I will hook it up later.
Done. Please merge in my reading branch and use it as a basis for your work.

Regarding skill increase from skill books, that is a separate issue. You don't need to bother with it for now. And all the script related functionality is already in place.

btw. I was wrong about us not being able to implement book pickup. But we can handle that later.
Zini wrote: @ObsidianBlk: It seems you haven't registered on our issue tracker yet: http://bugs.openmw.org/
ObsidianBlk wrote:
Zini wrote:@ObsidianBlk: It seems you haven't registered on our issue tracker yet: http://bugs.openmw.org/
Gah! You found me out! Lol... yeah, I know. Will register as soon as im home.
Star-Demon wrote: I just realized that this task is closely related to the journal one -

How can this feature be generalized in a way that it provides a base for the Journal task?

I'd guess that the basic interface could be just copy and paste, except the buttons will be different.

Do a good job on this, Obsidian - your work here will go much farther than your own tasks if it's done well. :)

Heh. Idea: Imagine if you could write journal entries in Deadric or using pictures simply because of inheritance.
Zini wrote: The Book/Scroll GUI and the journal GUI don't really have much in common, except for the text layout/html rendering code (which admittedly is a rather big part). This part should indeed be shared by both features. Either a common base class or a layout helper class, that is used by both the book/scroll GUI class and the journal main class.
ObsidianBlk wrote:
Star-Demon wrote:I just realized that this task is closely related to the journal one -

How can this feature be generalized in a way that it provides a base for the Journal task?

I'd guess that the basic interface could be just copy and paste, except the buttons will be different.

Do a good job on this, Obsidian - your work here will go much farther than your own tasks if it's done well. :)

Heh. Idea: Imagine if you could write journal entries in Deadric or using pictures simply because of inheritance.
*Looks up from MyGUI documentations and source code* Huh? *Looks back down at code and continues*
ObsidianBlk wrote: Well... good news is I have created a book class that properly links with the windows manager and I can get text to display in a window when I click a book in game... hazah

Bad news is... I discovered that the book window doesn't automatically take mouse control. I suppose I should have know that, but still. Furthermore... ummm... I have to write an HTML parser? Oh boy... this is going to be fun :D
Zini wrote:
I discovered that the book window doesn't automatically take mouse control. I suppose I should have know that, but still.
I am not entirely sure what you mean with this.
I have to write an HTML parser? Oh boy... this is going to be fun
Only a subset of HTML and no CSS. Shouldn't be too hard. The first task would be to find out which tags are supported.
ObsidianBlk wrote:
Zini wrote:
I discovered that the book window doesn't automatically take mouse control. I suppose I should have know that, but still.
I am not entirely sure what you mean with this.
Meaning, when you open a book you should no longer be able to move your character. Instead a mouse pointer should appear allowing me to press buttons. I didn't get that mouse pointer, so I know I did something wrong.
Zini wrote:
I have to write an HTML parser? Oh boy... this is going to be fun
Only a subset of HTML and no CSS. Shouldn't be too hard. The first task would be to find out which tags are supported.
I understand that, but the thing that worries me are the images. Some books do have them and, as such, I need to figure out how I use MyGUI to handle text and images in arbitrary locations.

For now I think I'll start by worrying about the subset of HTML and ignore the image tag for the moment, but if anyone has ideas, I'm all ears!
Star-Demon wrote:Star-Demon
As I brought the rough window for books to life, I thought over how you said books, scrolls, and journal are the same... and while I agree with Zini that the Journal is a significantly different beast, theres one huge chunk of functionality they all share... the HTML parser.

This leads to the question... where should I write the HTML parser? It seems silly to write it into the GUI. For one, there's at least four GUIs that could use it (books, scrolls, journals, and NPC dialogs).
Zini wrote:
Meaning, when you open a book you should no longer be able to move your character. Instead a mouse pointer should appear allowing me to press buttons. I didn't get that mouse pointer, so I know I did something wrong.
Look how the other GUI elements work. You need to define a GUI mode.
This leads to the question... where should I write the HTML parser? It seems silly to write it into the GUI.
Belongs into the mwgui subsystem, but into a separate class or function, that can be re-used by all GUI elements that require HTML rendering.
For one, there's at least four GUIs that could use it (books, scrolls, journals, and NPC dialogs).
AFAIK dialogues are plain text.
ObsidianBlk wrote:
Zini wrote:AFAIK dialogues are plain text.
Are they? I sort of assumed that since there's highlighting (topics) in the dialog, they may have been using <a>link tags</a>. In any case, hope to get on the HTML parser soon.

In the mean time, if anyone's interested, the dialog is functional (with clicky buttons!) Ok, ok, everyone here's probably done that already, but still, it's nice to see ones first piece of work coming together. :)

--edit--
OH! Does anyone know the name of the textures used for book and scroll dialogs in the game. Since we're pulling from the game data, I need to hunt these done as opposed to building my own.
Zini wrote: Hyperlinks in dialogue texts are generated automatically by checking against available topics. No markup required.
Zini wrote: btw. your branch does not work for me:
Activation failed: basic_string::at
Also, the game locked partially up after this exception. I think we need to improve the error handling in the GUI subsystem.
ObsidianBlk wrote:
Zini wrote:btw. your branch does not work for me:
Activation failed: basic_string::at
Also, the game locked partially up after this exception. I think we need to improve the error handling in the GUI subsystem.
You pulled the "Books" branch?
I have no idea what basic_string::at is. As far as I can recall, I don't have anything by that name used anywhere in my code (but I'll double check).

Things have been working for me, but I'll be honest in that I've only been testing one book (can't tell you which. It was the first one I found in the cave openmw starts in and I just automatically wander over to it when the game starts)
Zini wrote: Its an exception thrown when you try to access a character in a string beyond its end.
ObsidianBlk wrote:
Zini wrote:Its an exception thrown when you try to access a character in a string beyond its end.
Still don't know. I'm not doing anything with the book string yet other than giving it to the mygui text box. What book are you viewing that this occurs? If I can find it, ill try it out myself.
Zini wrote: Happens with all books as far as I can tell. I tried the one in the back of the start cave (the one with a few NPCs, some boxes and a caged area), but also several books in the Balmora Mage guild.
ObsidianBlk wrote:
Zini wrote:Happens with all books as far as I can tell. I tried the one in the back of the start cave (the one with a few NPCs, some boxes and a caged area), but also several books in the Balmora Mage guild.
Wow... ok... I have no idea. I just went in and tested again. In both the start cave and the Balmora Mages Guild I could read almost every book without issue.

When I say almost, there were a couple books (Mages Guild only) that didn't trigger. The first was the open book near the teleporter on the bottom level in the far back. The other book was the book on the second floor on the desk (The charter, I think). I didn't crash, they just didn't trigger. Also, there were no errors on the console for the untriggered books, so, for me, as far as my code, it seems to be running fine.

Is base_string part of the C++ standard library or some Ogre, MyGUI or one of the other libraries? Sorry for the 20 questions, I just can't replicate the issue.
Zini wrote:
Is base_string part of the C++ standard library or some Ogre, MyGUI or one of the other libraries? Sorry for the 20 questions, I just can't replicate the issue.
std::string is a typedef for std::basic_string<char>.
ObsidianBlk wrote:
Zini wrote:
Is base_string part of the C++ standard library or some Ogre, MyGUI or one of the other libraries? Sorry for the 20 questions, I just can't replicate the issue.
std::string is a typedef for std::basic_string<char>.
Ok, so... part of the C++ standard library... Hmmm...
I'm compiling against "GNU libstdc++6-4.4" just for reference.
Zini wrote: Okay, found it: Your forgot to add the file openmw_book_window_layout.xml to the CMakeLists.txt file. And that is why you should always work with an out-of-source build.
Zini wrote: Pushed a partially fix to github (books branch). Looks still wrong (window without background in the left upper part of the screen), but at least the book GUI comes up. Maybe some other files were left out.

btw. the cmake files are in a terrible state. A cleanup/rewrite is definitely needed.
ObsidianBlk wrote:
Zini wrote:Pushed a partially fix to github (books branch). Looks still wrong (window without background in the left upper part of the screen), but at least the book GUI comes up. Maybe some other files were left out.

btw. the cmake files are in a terrible state. A cleanup/rewrite is definitely needed.
Lol... didn't even think the resource files were included in the cmake files, which is an oversight on my part.

As for the GUI, no, you're seeing it right. It's complete garbage (graphics wise). I still don't know the name of the texture for opened books and scrolls so that I can use them as the background of the dialog instead of what I currently have. So, for the moment, it looks like total drek, but it works :)

I should have some cleanup over the weekend.
Zini wrote: Try: Tx_menubook.dds. Not entirely sure if it is the right one, but I found a mod that improves book textures and it has this file.
heilkitty wrote: Here's the list of files from Morrowind.bsa that very likely seem to be related with books/scrolls/journal GUI. Send me a PM, if you want to see them without messing with bsa file,

I'll email the textures then.

Mod Edit: We don't support the redistribution of any bethesda files, those who want access to the files within the BSA should use BSA commander or similar tools. Please do not email any Bethesda textures.
OK
ObsidianBlk wrote: @heilkitty - Thanks man, that actually helps a LOT!

Sorry for disappearing a couple days. 4th of July took over my weekend :)
I've spent the last 4 hours trying to fix-up the book layout. Almost the entire time all I've been trying to do is get the background image (tx_menubooks.dds) to show up and fit the book window. Well... it shows up, that's the easy part, but I can't get it to fill the window (by window, I mean the book gui window, not the screen).

I've been able to figure the texture is 512x256 because if I go any lower than 512 in the width, I don't get the whole book texture. It seems to be filling up only about 2/3 of the window and centered in the horizontal direction, but filling all vertical. If anyone has a moment and can give a fresh pair of eyes, I'd be greatful... then, when you see my stupid mistake, you can hit me :)

In the mean time... I eat dinner now... foooooood
ObsidianBlk wrote: MyGUI is killing me! After a WEEK I still cannot figure out why the book background isn't fitting properly to the defined widget size. I did update the layout and skin to support the proper buttons and... surprise surprise, those skin correctly (at least it looks that way), however... and I do not know why this is... the buttons have stopped responding to click events. I haven't touched the code in a while, so it couldn't be that *le sigh*

If anyone knows what I'm doing wrong, I'd love to hear it. MyGUI documentation sucks and OpenMW (as far as I can see) does not have any GUI elements that use a single image for a background, nor anything other than a single button style, so the examples I have available in the project are lacking.

I'll probably be leaving the GUI for a little while to at least get some of the HTML parser done.
Star-Demon wrote: Wanna post or link the parts that are giving you problems?
ObsidianBlk wrote:
Star-Demon wrote:Wanna post or link the parts that are giving you problems?
Sorry... figured everyone could easily grab my branch in GIT...

This is the skin for the background of the main book widget...

Code: Select all

<Skin name="MW_BookWindow" size="512 256" texture="textures\tx_menubook.dds">
        <BasisSkin type="MainSkin" offset="0 0 512 256">
            <State name="normal" offset="0 0 512 256"/>
        </BasisSkin>
    </Skin>
And this is the layout for the book GUI...

Code: Select all

<MyGUI type="Layout">
    <Widget type="Window" skin="MW_BookWindow" layer="Books" position="0 0 500 342" name="_Main">
        <!-- Book pages -->
        <Widget type="StaticText" skin="BookScrollText" position="8 8 234 306" name="LeftPage"/>
        <Widget type="StaticText" skin="BookScrollText" position="258 8 234 306" name="RightPage"/>

        <!-- Page-turn buttons -->
        <Widget type="Button" skin="MW_DocPrevButton" position="12 314 64 12" name="PrevPageBTN">
        </Widget>
        <Widget type="Button" skin="MW_DocNextButton" position="416 314 64 12" name="NextPageBTN">
        </Widget>

        <!-- Take/Close buttons -->
        <Widget type="Button" skin="MW_DocTakeButton" position="178 314 64 12" name="TakeBTN">
        </Widget>
        <Widget type="Button" skin="MW_DocCloseButton" position="258 314 64 12" name="CloseBTN">
        </Widget>
    </Widget>
</MyGUI>
From everything I read, they should be fine. I define the skin to the size of the image (or, actually, the "default" size of the window) and it should fit my widget regardless of the size... it's not the case :(
Star-Demon wrote: Thanks - reason I ask is I prefer showing to telling. Lemme see...
Star-Demon wrote: Some widget tags terminate themselves and others use a separate end-tag. I know it makes it shorter, but it's harder to trace when you're not inconsistent.

I'm not sure with the output looks like - but I wonder if texture's path is correct and able to be read?

Looks correct, I think I'd try adding or subtracting arguments, and look up to see what various arguments actually do.

I would try and see if the texture is properly repeating across the entire thing - isn't there a repeat-x and repeat-y argument?

Since you said it should work but doesn't - look at the code - how can assigning a skin remove the event handling to the widget?

Other than that -I don't know - you seem to have exhausted your references - maybe come back to it and you'll fix it in a moment of inspiration.
Peppe wrote:
ObsidianBlk wrote:MyGUI is killing me! After a WEEK I still cannot figure out why the book background isn't fitting properly to the defined widget size.
It can't be as simple as that it actually is scaled but just does not look like it?
The tx_menubook.dds I found have some fully transparent parts on the left and right sides. This would make it appear aligned a bit off since the actual edge of the image is not the visible edge.
ObsidianBlk wrote: @Star-Demon
No, I'm loading the texture. It actually shows up, however, if I tell the layout to be 500x340, the book texture will render something like 400x340 in the center. If I try loading the image in at a different resolution than 512x256, I get only a sub-section of the book.

@Peppe
Part of my issue and limitation is I'm working on Linux. None of the export tools that still exist run properly for me and, therefore, I cannot extract the original image to get a better understanding of how it looks (transparent edges, etc).

*writes a note to self about copious documentation in personal projects while cussing MyGUI*
Zini wrote: Exporting, as in getting it out of the bsa? If you have the CD version of MW, the CD with the CS should already contain an unpacked directory structure, containing all of the bsas.
Peppe wrote: So, it sounds like the problem is what I suspected then.
Looking at the image on the CD as Zini suggested shows that this image is similar to the one I found yesterday.

512x256px but with about 50px fully transparent to the left and right, leaving about 410px visible in the middle.
ObsidianBlk wrote: Ok... this is becoming ridiculous now!

@Zini
That is a help. I did not know about that directory in the CS CD... I never looked and when I played around with Morrowind modding, it was really in building new landmasses. Never had a need to look before.

So, I found the tx_menubook.tga image. It's 60px on either side and I adjusted the skin accordingly and... ... IT STILL DOESN'T FIT!!! According to everything I read, the <BasisSkin type="MainSkin"> is automatically aligned as "stretch", so I don't need to do that (but I did anyway in a couple experiments) and it doesn't work.

Here's what I have for the skin...

Code: Select all

<Skin name="MW_BookWindow" size="512 256" texture="textures\tx_menubook.dds">
    <BasisSkin type="MainSkin" offset="60 0 392 256" align="STRETCH">
        <State name="normal" offset="60 0 392 256" align="STRETCH" />
    </BasisSkin>
</Skin>
Now... for the <Skin> tag, the "size" attribute is suppose to be for the expected default size of the widget, not the size of the texture, but, ultimately shouldn't matter as the skin gets scaled anyway (which leads me to wonder why have it in the first place?!)
The offset for both <BasisSkin> and <State> are the (x y w h) within the image. Again... why <State> doesn't just inherit from <BasisSkin> if unchanged is beyond me, but if I omit offset in either <BasisSkin> or <State> the skin does not show at all.

So... My offset is "60 0 392 256"... 60 for the horizontal offset, 0 for the verticle (as there is not transparent pixels there), 392 (because 512-(60*2)=392) for the width, and finally 256 for the height... And it still does not fit. Looks virtually unchanged, as a matter of fact, when compared to an offset of "0 0 512 256"

You know, this wouldn't bother me so much if it wasn't something that should be so simple!
Peppe wrote: Try

Code: Select all

<Skin name="MW_BookWindow" size="512 256" texture="textures\tx_menubook.dds">
    <BasisSkin type="MainSkin" offset="0 0 512 256" align="STRETCH">
        <State name="normal" offset="50 0 412 256" align="STRETCH" />
    </BasisSkin>
</Skin>
ObsidianBlk wrote:
Peppe wrote:Try

Code: Select all

<Skin name="MW_BookWindow" size="512 256" texture="textures\tx_menubook.dds">
    <BasisSkin type="MainSkin" offset="0 0 512 256" align="STRETCH">
        <State name="normal" offset="50 0 412 256" align="STRETCH" />
    </BasisSkin>
</Skin>
Now see... here I was getting excited at my newest idea of designing the GUI with the transparent sections in mind when you come and solve the original issue... LOL! Nice!!

Still doesn't make logical sense to me why, if you NEED a <State> tag as a child of the <Basis> tag that BOTH tags require an "offset" attribute. Just creates a TON of confusion... to me anyway.

Thanks Peppe... GUI layout is almost done now.
Peppe wrote:
ObsidianBlk wrote:Still doesn't make logical sense to me why, if you NEED a <State> tag as a child of the <Basis> tag that BOTH tags require an "offset" attribute. Just creates a TON of confusion... to me anyway.
My interpretation:
(This is based on how they seem to behave, not on documentation, so I may be wrong)

BasisSkin offset:
Defines the offsets in the window (or whatever you are skinning) on which the texture will be drawn.
So defining an x offset of 60 here means we will start drawing 60pixels from the left edge of the window.

State offset:
Defines the rectangle we want to use out of the texture.
Defining an x offset of 60 here means that the rectangle we cut out of the texture starts 60px from the images left edge.
Peppe wrote:
ObsidianBlk wrote:the buttons have stopped responding to click events.
I presume this was when you changed the layer to Books?
Setting peek to true for the Books layer in openmw_layers.xml should make it work.

Slightly unrelated, you do know the commit object contains author and timestamp as well as a pointer to the tree containing the modified files?
In other words, having that information in the commit message as well is a bit redundant.
Zini wrote: btw. I found this link about HTML tags in books/scrolls: http://cs.elderscrolls.com/constwiki/in ... Formatting

Looks like only a small subset of HTML is supported. Should be rather easy to implement.
ObsidianBlk wrote: @peppe
I do know that... now... but when I started using GIT, I didn't. At this point, it's just habbit, it's just my style. Yeah, it's probably redundant, but it doesn't really hurt anything, so I'm not going to change it.

Oh! And, yes, book layer, I completely forgot I did that. I'll definitely look into that! Do you, by any chance, have more detailed information on the workings of MyGUI? It's really like groping in the dark for me.

@Zini
Awesome link, thank you! I do plan on getting to the HTML this week. Sorry, I've been slow. My luck is that as soon as I decide "I'm bored... let me join this team and help with this awesome game!" things come from nowhere and take up a lot of my time. :)
Zini wrote: No problem.

Try to make the html code generic enough that it can be used for books as well as for scrolls as well as for the journal. The only difference between books and scrolls are the page breaks. The journal is like a book, but additionally it needs to know how much fits on a page without actually rendering the text (when you open the journal on the last page, all previous pages need to be analysed for layout so the journal knows the layout of the two open pages).
Peppe wrote:
ObsidianBlk wrote:Do you, by any chance, have more detailed information on the workings of MyGUI? It's really like groping in the dark for me.
Not really, I have a full clone of their repository so I have the full source available instead of of our stripped copy.

There is also their forum.
Locked