Q3 - ScrollBars

General help with the Ecere Cross Platform GUI toolkit: Window, common controls, events, etc.
Help with the 2D Graphics library: Surface, Display, Bitmap, Font and others.
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Q3 - ScrollBars

Post by D.Bane »

I hope I am not boring out anyone, but since I have some time I am using it to learn so here is another question :)

This question goes together with the Q2, but is problem for itself. I like to draw my controls etc, instead of using many labels and while doing things like that I have come to the point where I have a lot of text (the text needs to be drawn to the form, similar to the way you would have the text in the notepad) and that all works. The problem is that when I want to make the vertical scrollbar follow the height of text 'field' (when you slide it all the way down, it should have about 50px more then the end of the text), but it does not.

In fact, when I made

Code: Select all

 
clientSize.h = lastPosition + 50;
scrollArea.h = clientSize.h;
hasVertScroll = true;
 
it had either shown me the scrollbar with almost 2x more space behind the last line then all together needed, or it had cut part of the text.. It was also only possible to update the scrollbar by going with mouse and resizing the form.

This is nothing specific, just a regular form with plain text, but I am not able to figure it out. I would expect that it is very simple, but then again, I must be missing something..

The short question would then be, if I write the text or Blit the picture that is bigger then the form is, how can I make the scrollbar follow the change and update, allowing me to scroll trough entire text or see entire picture.

Thank you once again,
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: Q3 - ScrollBars

Post by D.Bane »

Hi.

Just to say some more details.

I have noticed that the text written down was located in CommonControl class, so I did create big enough window, but I needed to do that to the parent as well.

Now there is this code:

Code: Select all

      size.h = lastPosition + 40;
      parent.clientSize.h = position.y + size.h + 70;
While it works great if there is more text then before, it also is not working when there is less text. For example, if you had a function that adds 30 lines of text it will show the scrollbar as it should, while if your run other function that takes 30 lines out, you will be left with the same scrollbar value as before. The only way for the scrollbar to 'recuperate' is to resize the window even by a pixel.

D.Bane
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Q3 - ScrollBars

Post by jerome »

D.Bane,

No you're not boring anyone for sure :) Again, sorry it took me so long to reply, I was deep in multithreading deadlocks, crashes and glitches headaches at the time. :oops:

I'm not sure I fully understand what you're doing, but I have a feeling that you could do this with the built in scrollArea functionality.

I built this TextScrollerDemo for you to see how it's usually done:

Code: Select all

public import "ecere"
 
TextScrollerDemo demo {};
 
class TextScrollerDemo : Window
{
   text = "Text Scroller Demo";
   background = activeBorder;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   size = { 576, 432 };
   TextScroller scroller
   {
      this, anchor = { 10, 10, 10, 10 };
      contents = "Could not load ./textScroller.ec";
   };
 
   TextScrollerDemo()
   {
      File f = FileOpen("textScroller.ec", read);
      if(f)
      {
         uint size = f.GetSize();
         String s = new char[size+1];
         f.Read(s, 1, size);
         scroller.contents = s;
         delete s;
         delete f;
      }
   }
}
 
public class TextScroller : Window
{
   borderStyle = deepContour;
   font = { "Consolas", 12 };
   background = black;
   foreground = lime;
 
   hasHorzScroll = true;
   hasVertScroll = true;
 
   int maxW, lh;
   int linesCount;
   String contents;
   String linesText;
   char * lines[1024];
 
   ~TextScroller()
   {
      delete linesText;
      delete contents;
   }
 
   property String contents
   {
      set
      {
         delete contents;
         contents = CopyString(value);
         delete linesText;
         linesText = CopyString(contents);
         // Lazy lines splitting: it will unfortunately ignore empty lines...
         linesCount = TokenizeWith(linesText, sizeof(lines), lines, "\n", false);
         OnLoadGraphics();
      }
      get { return contents; }
   };
 
   bool OnLoadGraphics()
   {
      int c;
      maxW = 0;
      display.FontExtent(fontObject, " ", 1, null, &lh);
      for(c = 0; c < linesCount; c++)
      {
         int w;
         display.FontExtent(fontObject, lines[c], strlen(lines[c]), &w, null);
         if(w > maxW) maxW = w;
      }
      snapVertScroll = lh; // Snap to line height vertically
      snapHorzScroll = 1;
      // Not sure what your +50 is all about, but I included it here =)
      scrollArea = { maxW, lh * (linesCount-1) + 50 };
      return true;
   }
 
   void OnRedraw(Surface surface)
   {
      int c;
      int x = -scroll.x, y = -scroll.y;
      int ch = clientSize.h;
      for(c = 0; c < linesCount; c++, y += lh)
      {
         int w;
         if(y > -lh && y < ch)
            surface.WriteText(x, y, lines[c], strlen(lines[c]));
      }
   }
 
   // *** Brute force implementation ***
   // Could be optimized by using display.Scroll(), and only updating
   // the new portion of the screen
   // (See sdk/ecere/src/gui/controls/EditBox.ec for example)
   void OnVScroll(ScrollBarAction action, int position, Key key)
   {
      Update(null);
   }
 
   void OnHScroll(ScrollBarAction action, int position, Key key)
   {
      Update(null);
   }
}
Note: A bitmap scroller would be even simpler, since you have a readily available bitmap width/height, do not need to worry about lines etc., and the Surface::Blit method will handle all the clipping for you.

Hope it helps you figuring out how to do it right :)
If not, could you send me your whole project so I know exactly what you're doing?

Cheers,

Jerome
Attachments
textScroller.ec
Text Scroller Demo
(2.63 KiB) Downloaded 1071 times
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Q3 - ScrollBars

Post by jerome »

Just another note, modifying both the scrollArea and the size (especially through clientSize), is a messy business. That is because the ScrollBar itself reduces the width or height of the clientSize by the space it occupies when it is visible. It gets particularly messy when you have both a vertical and horizontal scrollBars, and they modify each other's available space. Keeping this in mind might help solve your issue :D

-Jerome
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: Q3 - ScrollBars

Post by D.Bane »

Hi.

Thank you Jerome for the info on scrollArea and size smoothie, I will stay clear from it. I tried it all but it was not working properly because I updated the common control that I used to write on, not the parent of it, so it had no scrollbar's at all.

I could add the sample later on, I would like to test something first. I just remembered the Tree view control that was used to search the folders... Basically that is what I wanted to create.

I do not know if you know (99.9% that you do :) ) about Notepad++. It has some nice features in its text editor, so I wanted to create something similar in Ecere.

Basically, lets take a simple text in the Ecere ide:

Code: Select all

 
+class Form1 : Window
 {
   text = "Form1";
   background = activeBorder;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   size = { 640, 480 };
 
 +bool OnCreate(void)
   {
 
      return true;
   }
 }
Now every time you press + (for example, it could be placed at the line numbers) you can minimize the code that you will not use as it works. This would help you navigate from one part to the other without much problems and make it easy to see those two or three functions that you are working on.

I also thought about making the fonts bigger with (example: ctrl+scrollUp) and smaller (ctrl+scrollDown) which I was only able to make with pre-fixed values, as it would not work with some float that stores the value. I may be laying now...Sorry, do not remember if I wanted to add float or it did not work. Anyway.. This helped making font normal, and in that very tired mode, easy to read :)

Now, I did not know how to do it (but thanks to you Jerome, I now know) there are ways to make the "class Form1 : Window" bigger then the rest of the text making it easy to find the functions, properties, etc.

Now, I am not sure how it will look in the end, nor will people like it, but that is something else I have been working on (well, for now it is just some random jibber-jabber to test it all out).

So I guess that I made it a bit longer...So short - I will take a look at the tree view control used in that sample, and try to see why I am missing parts of the text when the window opens (it needs to get resized first to be nicely shown, or to have mouse outside of the window when it gets created..)

Best wishes to all that come to these forums,
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Q3 - ScrollBars

Post by jerome »

Hi D.Bane,

I know Notepad++, though I don't use it (The Ecere IDE is my only text editor :P).

I also know this feature, which is getting pretty popular in most IDEs. I don't personally like it that much or feel much of a need for it.

We should support it at some point in time, but it would have to be integrated within the EditBox control which the IDE uses, and would not be so easy. At the moment we have a lot of other issues to focus on :)

About using the TreeView control (currently implemented as part of the Ecere ListBox control) for doing this, it would be quite difficult to get it to work like a text editor. The TreeView/ListBox is row-based, and I believe at the moment all rows must be the same size, so every line of text would have to be one row. The ListBox does have an 'editable' mode, but it would probably require some tweaks to get it to behave exactly like a text editor, i.e. always being in proper editable mode, and not auto-selecting the text when you change row, and keeping the current column position when you go up and down. Certainly it would be possible, must may not be the way I would go about it. (In fact I never really thought much how I would do it, which is partly why it's not a feature of the IDE yet!)

I think I would prefer adding it as a new functionality of the EditBox, or rather, a control derived from the EditBox. You could use some code from the ListBox (TreeView) however, e.g. for code to draw and toggle those +/- icons. The derived control could keep a separate buffer of collapsed code, and simply take out the lines from the base EditBox control, and adding them back in when expanding. Line numbers would have to be kept correct however. And there would be issues with other things like the context look up and debugger :shock: Not easy at all!

Cheers,

Jerome
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: Q3 - ScrollBars

Post by D.Bane »

Hi Jerome.

I was thinking in a different way. For example lets take EditBox class and then a new HasExpand class. Now what if you select the options that you would like to have line numbers as well as the +- option and you receive it but nothing really needs to be changed.

What I want to say is this, like always you get the IDE EditBox shown, but you also get another class that 'hides' the EditBox. So, instead of contents, you would see 'contentsA' and send every keyhit to both places. This way the compiler would still use the EditBox.contents that would receive everything from the contentsA (everything besides the removal of the lines). For example it has a property that holds line numbers (start-end).

Also, this would depend on detecting "{}" in .eC, .c .cpp files. Also <tag></tag> in html..etc....

Where should I take a look in order to have IDE detect the "{}"? - Where to make it or what file in ecere.dll is/should this code be located in so that it can know what to search for in order to find the start and end 'tag'/scope marker depending on the file?

Thanks, all the best.
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Q3 - ScrollBars

Post by jerome »

Hi D.Bane,

Most of the IDE's code editing functionality right now is within Ecere's EditBox control class.
At some point some of it should be moved up to a higher level, which is partly why I'm reticent to add more functionality to the EdtiBox itself...

I believe we would be still able to implement that +/- feature somehow within the CodeEditor class by adding/removing lines to the EditBox.

Or we could try to be more efficient and implement it at the EditBox class, taking out from the list the lines but not deleting them...

Either way, it's quite tricky. About the detection of { } or <> </> this would still have to be done by accessing the EditBox contents, again either within the EditBox class or the CodeEditor class...

If it can be optimal enough, I would prefer to leave the EditBox control alone and implement it in the CodeEditor.

If you're set on implementing this IDE feature, we can discuss more in the IDE Development Forum, or on IRC :)

Cheers,

Jerome
D.Bane
Posts: 78
Joined: Thu Jul 29, 2010 2:51 pm

Re: Q3 - ScrollBars

Post by D.Bane »

Hi Jerome.

I started a new topic with this here.

Well if it is done in CodeEditor class then it may not be as nice as it would be in the EditBox.

Maybe call the EditBoxTags.ec (or any other name) which would have this implemented in it, so that anyone can use it in their code. For example for license or some documentation, you would be able to detect the tags and have the people click on the +- sign (just few examples, I am sure that there are much better examples and ways to use it).

OK. That is for now about that.

Now to answer the question about the scrollBars and their redrawing. Anyone looking to accomplish this should try to do it with scrollArea.

Oh Jerome, how do you update the scrollBar if the window inside of the other window got smaller, so small that it is two times smaller then the parent, as the scrollbars remain drawn the same as when it was bigger then the parent, that is until the resizeing start with a mouse?

Thank you again,
All the best.
D.Bane.
No army is to big, if the heart is beating strong.
There's no bad luck, it's just easier to blame someone else.
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Q3 - ScrollBars

Post by jerome »

D.Bane,

I'm really not sure what your question about updating the scrollbar is about.

Some code would help :D

Scrollbars take up space within a window... Windows usually have a default minimum size, and you can also set minClientSize to a value of minimum client area size of your choice.

Ah... Maybe you are talking about the "virtual" client area, i.e. dragging windows around a parent window...
There is a modifyVirtualArea boolean flag that can be set on a child, indicating whether its position and size will modify its parent virtual area or not.
Setting scrollArea to null will reset a parent to an automatically computed area based on children within it, whereas setting it to a specific value will make it a fixed size.

Hope this helps!

-Jerome
Post Reply