Cell borders in ListBox

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.
Post Reply
shakeshuck
Posts: 31
Joined: Tue Dec 01, 2015 6:52 pm

Cell borders in ListBox

Post by shakeshuck »

Hi, newbie here :)

Is there somewhere to look to find out what all the properties do? It's a bit overwhelming!

I haven't managed to find one that puts a border round the cells in the listbox. Can someone please point me in the right direction?

As a side note (I haven't signed up for the bug tracker), on Windows 7 opening the DataControls sample, if you go to the listbox properties, under Misc, and click the + next to currentField cell, the IDE crashes. I was poking around trying to work out what things did when this happened - Sorry!
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Cell borders in ListBox

Post by jerome »

Hi shakeshuck,

Welcome to the Ecere community!

F1 in the IDE/Documentor would be the place to look for what the properties do, in addition to hopefully tooltips in the IDE in the future as well, but as you may already have noticed, the documentation is still lacking quite a bit. The actual Ecere source code might be one place to look to have an idea what things do, but of course you are welcome to ask here in the forums or on #ecere on irc.freenode.net, we'll be happy to help you out.

Regarding putting a border around the cells, this is (not very nicely) tied to the listbox behavior.
Lines are only drawn if the 'alwaysEdit' property is set to true. (alwaysEdit refers to the data cells always in 'edit' mode, rather than popping up a data editor each time you select an editable cell, and displaying the data in a different manner otherwise).

Here is some example code:

Code: Select all

import "ecere"
 
class Form1 : Window
{
   caption = $"Form1";
   background = formColor;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   clientSize = { 632, 438 };
 
   ListBox listBox1
   {
      this, caption = $"listBox1", size = { 320, 164 }, position = { 120, 56 };
      background = slateGray;
      foreground = white;
      alwaysEdit = true;
      hasHeader = true;
   };
 
   DataField fld1 { width = 80, header = "One" };
   DataField fld2 { width = 80, header = "Two" };
   DataField fld3 { width = 120, header = "Three" };
 
   Form1()
   {
      DataRow row;
      listBox1.AddField(fld1);
      listBox1.AddField(fld2);
      listBox1.AddField(fld3);
 
      row = listBox1.AddRow();
      row.SetData(fld1, "Test");
      row.SetData(fld2, "Test");
      row.SetData(fld3, "Test");
 
      row = listBox1.AddRow();
      row.SetData(fld1, "row2");
      row.SetData(fld2, "row2");
      row.SetData(fld3, "row2");
   }
}
 
Form1 form1 {};
As for the crash with Data Controls sample, thank you for reporting that. 'currentField' shouldn't show up in the properties sheet at all as it's meant to be a run time property only (it is the active column when using a ListBox in a multi-columns grid mode).

Hope this helps!

Cheers,

Jerome
shakeshuck
Posts: 31
Joined: Tue Dec 01, 2015 6:52 pm

Re: Cell borders in ListBox

Post by shakeshuck »

Thanks, Jerome.

I was concerned for a minute that alwaysEdit would make things editable, but it doesn't. ;)

This works until you have fullRowSelect set to false, in which case the cell boundaries disappear again. This also causes odd behaviour in the listbox; selecting a third column cell, for instance, also highlights the first column (but in a different way)?

And if you have clear headings set, you lose the cell boundaries between the cells and the headers.

Perhaps I'm missing another setting, but tabbing doesn't seem to work between listbox cells, either - I don't know if it's supposed to?

Sorry for lots of questions at once. :shock:
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Cell borders in ListBox

Post by jerome »

Hi again!

Make things editable -- Each field must be set editable with 'editable = true'.

Currently, the ListBox supports a range of use case scenarios, but there may be combinations of those options which do not work as you would expect.

For example, selecting individual cells rather than entire rows is limited to editable fields only.
The left/right arrow keys can then be used to move through the cells (Not TAB, TAB moves through controls usually, if the parent dialog/control has tabCycle = true).

Regarding the 'fullRowSelect' property, I think its name is confusing, it is a display-only property, it doesn't change the behavior. When it is false, only the first column is selected.

Regarding clear headers, you're right, you lose that border.

If there is a specific scenario you are trying to use the ListBox for, please let us know what you're trying to achieve and we'll discuss how to best make use of the ListBox as it is, or we could discuss doing some improvements to make it capable, or how to work around it.

For example all controls can be fully customized by e.g. deriving a class from ListBox, and overriding methods such as OnRedraw(), OnLeftButtonDown(), OnKeyHit() etc.
At one point though you end up rewriting the whole control...

We are aware of the usability limitations and hope to do better in our next generation GUI toolkit, when we get around to have the chance to work on it! :) We're also always looking for contributors if you're interested ;)

( http://ecere.org/ideas/gui/ )

Regards,

Jerome
shakeshuck
Posts: 31
Joined: Tue Dec 01, 2015 6:52 pm

Re: Cell borders in ListBox

Post by shakeshuck »

I see what you say about fullRowSelect, I was hoping it would just highlight the selected cell, but instead it highlights the first column also:

Image

This looks a bit odd to me...?
For example, selecting individual cells rather than entire rows is limited to editable fields only.
That makes sense to me, and is how I think it should be.


There are other things I would like to be able to get into the cells (checkboxes, for one), but if it's going to need a lot of work I can always try to find a workaround and do it differently.
We're also always looking for contributors if you're interested ;)
I don't mind helping out if I can get things working the way I want them, but of course I'd have to understand how they work first... ;)
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Cell borders in ListBox

Post by jerome »

fullRowSelect -- basically, it is not meant to be used with editable / selectable fields.

It's meant for either having only a single field, or highlighting/selecting only the first field and displaying extra info on columns on the right. In most cases it's used with a single field (e.g. the project tree view in the Ecere IDE).

Your screenshot does look odd -- a very good example of the ListBox not working very well with certain combinations of options :)

As an alternative to 'not' highlighting the current row, perhaps try chosing a selectionColor closer to the background:

Code: Select all

selectionColor = { 240, 240, 240 };
selectionText = black;
For check boxes, you might want to take a look at extras/gui/controls/CheckListBox.ec.

The CheckListBox is meant as a tree view with a single field, but perhaps could be adapted to what you would like to do. The check boxes are not part of a DataField but check box buttons attached to the rows.

Note that in some scenarios perhaps having the check button actually part of a DataField might be an easier option. One way with our current system might be to define a datatype inheriting from 'bool' which overrides OnEdit() and pops up a checkbox (you would likely want 'alwaysEdit' to be true in this case, so that the checkbox remains there without requiring a separate 'F2' to edit the cell and then click).
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Cell borders in ListBox

Post by jerome »

After playing around with it, I think you would still require two clicks to check a check box part of a DataField, because the ListBox only supports a single DataBox (for editing) created at a time.

Here is an example:

Code: Select all

import "ecere"
 
class MyCheckBool : bool
{
   Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
   {
      Button button = dataBox.keepEditor ? (Button)dataBox.editor : null;
      if(!button)
      {
         button = Button
         {
            dataBox, borderStyle = 0, text = dataBox.text, anchor = { 0, 0, 0, 0 },
            modifyVirtualArea = false, isCheckbox = true;
 
            bool DataBox::NotifyClicked(Button control, int x, int y, Modifiers mods)
            {
               bool checked = control.checked;
               if(readOnly)
                  control.checked = !checked;
               else
                  SetData(&checked, false);
               return true;
            }
         };
      }
      button.checked = this;
      button.Create();
      return button;
   }
 
   const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
   {
      return this ? "√" : "";
   }
}
 
class Form1 : Window
{
   caption = $"Form1";
   background = formColor;
   borderStyle = sizable;
   hasMaximize = true;
   hasMinimize = true;
   hasClose = true;
   clientSize = { 632, 438 };
 
   ListBox listBox1
   {
      this, caption = $"listBox1", size = { 320, 164 }, position = { 120, 56 };
      selectionColor = { 240, 240, 240 };
      selectionText = black;
      alwaysEdit = true;
      hasHeader = true;
   };
 
   DataField fld1 { width = 80, editable = true, header = "One" };
   DataField fld2 { dataType = class(MyCheckBool), width = 8, editable = true };
   DataField fld3 { width = 120, editable = true, header = "Three" };
 
   Form1()
   {
      DataRow row;
      listBox1.AddField(fld1);
      listBox1.AddField(fld2);
      listBox1.AddField(fld3);
 
      row = listBox1.AddRow();
      row.SetData(fld1, "Test");
      row.SetData(fld2, bool::false);
      row.SetData(fld3, "Test");
 
      row = listBox1.AddRow();
      row.SetData(fld1, "row2");
      row.SetData(fld2, bool::false);
      row.SetData(fld3, "row2");
   }
}
 
Form1 form1 {};
Post Reply