Page 1 of 2

RichView - Table Row Height ?

Posted: Sat Jun 25, 2011 1:16 pm
by reiser
Hello, I have table:

Code: Select all

      tmpTable := TRVTableItemInfo.CreateEx(1, 3, ChatBox.RVData);
      tmpTable.BorderWidth := 0;
      tmpTable.CellBorderWidth := 0;
      tmpTable.Color := clNone;
      tmpTable.Cells[0, 0].BestWidth := 100;
      tmpTable.Cells[0, 2].BestWidth := 55;

      If ANick <> '' Then
        If ANick = UserDetails.Username Then
          tmpTable.Cells[0, 0].AddNL(Format('%s:', [ANick]), 4, 0)
        else
          tmpTable.Cells[0, 0].AddNL(Format('%s:', [ANick]), 3, 0);
      tmpTable.Cells[0, 1].AddNL(ALine, AStyle, 1);
      tmpTable.Cells[0, 2].AddNL(TimeToStr(Time), 1, 2);
Problem is, table row height is too big. How can I reduce line height ? Thanks

Posted: Sat Jun 25, 2011 5:04 pm
by Sergey Tkachenko
Probably, it is because an empty line that exists in empty cells initially.
Call Cell.Clear before Cell.AddNL.

Posted: Sat Jun 25, 2011 6:15 pm
by reiser
Thanks, that worked.

Now one more question, can I furhermore reduce line spacing ? I tried setting CellVSpacing to 0, but no effect:

Image

Posted: Sun Jun 26, 2011 7:08 am
by Sergey Tkachenko
Distance between cells = CellVPadding*2 + CellBorderWidth*2 + CellVSpacing.

Posted: Wed Jun 29, 2011 7:49 pm
by reiser
Hey, sorry for late response, that worked, thanks !

Is it possible to hide selection arrow ? The one that appears when you position cursor on top or left of every line, and that selects whole line or table cell ?

Posted: Wed Jun 29, 2011 9:17 pm
by reiser
Also, can I make text to be clickable and assign some event on it ? Specificaly, I want user to be able to click on text in first table column, and to code some action after click on item.

Posted: Thu Jun 30, 2011 7:41 am
by Sergey Tkachenko
To disable row/column selection, remove rvtoRowSelect and rvtoColSelect from table.Options.
To disallow multicell selection, include rvtoNoCellSelect as well.

Posted: Thu Jun 30, 2011 7:50 am
by Sergey Tkachenko
Use OnRVMouseUp to detect clicking:

Code: Select all

procedure TForm3.RichViewEdit1RVMouseUp(Sender: TCustomRichView;
  Button: TMouseButton; Shift: TShiftState; ItemNo, X, Y: Integer);
var pt: TPoint;
    RVData: TCustomRVFormattedData;
    LItemNo, LOffs, Row, Col: Integer;
    Table: TRVTableItemInfo;
    Cell: TRVTableCellData;
begin
  if Sender.SelectionExists then
    exit;
  pt := Sender.ClientToDocument(Point(X,Y));
  if not Sender.GetItemAt(pt.X, pt.Y, RVData, LItemNo, LOffs, True) then
    exit;
  if RVData.GetSourceRVData is TRVTableCellData then begin
    Cell := TRVTableCellData(RVData.GetSourceRVData);
    Table := Cell.GetTable;
    Table.GetCellPosition(Cell, Row, Col);
    Caption := Format('Clicked at (%d,%d)', [Row, Col]);
  end;
end;
The code above detects clicks on items inside table cells.
If you want to detect clicks anywhere inside cells, do not exit if GetItemAt returns False.

Posted: Thu Jun 30, 2011 9:23 am
by reiser
Thank you very, very much :)

Posted: Wed Jul 06, 2011 2:24 pm
by reiser
Hello, me again :)

I'm making chat alike application. After some testing, I noticed that TRichView eats much memory if there is alot of spam and I leave it to work overnight. This is how I add lines at the moment:

Code: Select all

      tmpTable := TRVTableItemInfo.CreateEx(1, 3, ChatBox.RVData);
      tmpTable.BorderWidth := 0;
      tmpTable.CellVPadding := 0;
      tmpTable.CellBorderWidth := 0;
      tmpTable.CellVSpacing := 0;
      tmpTable.BorderVSpacing := 0;
      tmpTable.Color := clNone;
      tmpTable.Options := [rvtoColSizing, rvtoRTFAllowAutofit];
      tmpTable.Cells[0, 0].BestWidth := 135;
      tmpTable.Cells[0, 2].BestWidth := 55;
      tmpTable.Cells[0, 0].Clear;
      tmpTable.Cells[0, 1].Clear;
      tmpTable.Cells[0, 2].Clear;

      tmpTable.Cells[0, 0].AddFmt('%s:', [ANick], ANickStyle, 0);
      tmpTable.Cells[0, 1].AddFmt(ALine, [], ALineStyle, 1);

      fmtTime.LongTimeFormat := 'HH:MM:SS';
      fmtTime.TimeSeparator := ':';
      tmpTable.Cells[0, 2].AddFmt(TimeToStr(Time, fmtTime), [], 1, 2);

      ChatBox.AddItem('', tmpTable);
Basically, I create one table for each row added. Can I create table once, then just expand it for each line ? And how to do this ? I can create table outside function that adds line to chat, but how can I get its reference and add row to it from function ?

Posted: Thu Jul 07, 2011 2:20 pm
by Sergey Tkachenko
If you want to save memory and make selection more convenient for the user, I suggest to use tabs instead of tables.
The following settings can be made for the paragraph:
Tabs.Add(135);
LeftIndent = 180;
FirstIndent = -180.
Then add Nick, #9, Time, #9, message text.

After adding, call ChatBox.FormatTail for fast formatting.
Your method also allows using FormatTail. But if you decide using a single table, you will need to reformat the whole table after adding each new message; it may be slow for long chats.

Posted: Thu Jul 07, 2011 2:42 pm
by reiser
Ok, but that creates the problem when user types line longer than one row can contain, it gets cutted bad after that. So I think table is best option. Can I somehow limit how many lines RichView can contain ? E.g. limit it to 400 lines, then if limit is reached, delete first line etc.

Posted: Sun Jul 10, 2011 9:31 am
by Sergey Tkachenko
It should not be look bad for long lines.
See, the first line has two tab stops: 135 and (implicit tab stop at left indent) 180. User text starts at 180, and, if it wraps, it continues at 180, because the left indent = 180.
So it should look exactly like with tables. The only difference is long username. In tables, it will be wrapped. In tabs, it will goes beyond the tab (so, for tabs, it's better to use the order time+username+message, instead of username+time+message).

As for size limitation, it would be simpler to limit a number of messages. You can calculate the count of messages yourself, then use DeleteParas to delete the first message when necessary (this method is fast and does not reformat the whole document).

Posted: Sun Jul 10, 2011 9:42 am
by reiser
Thanks, this fixed it! :)

Code: Select all

      If ChatBox.LineCount >= maxLineCount Then
        ChatBox.DeleteParas(0, 0);

Posted: Sun Jul 10, 2011 10:24 am
by Sergey Tkachenko
Yes, it should work. But note that LineCount property is not actually a line count, it's another name for ItemCount, maintained for compatibility.
But if your chat window consists of one table for one message, then one table = one item = one line.
But if you will use tabs, then one message = text + tab + text + tab + text = 5 items.