Page 1 of 1

Show Caret even when editor does not have focus?

Posted: Mon Sep 10, 2012 5:04 pm
by MarkElder
Hello,

Is there a way to show the caret even when editor does not have focus? I am building a template editor where my customers can create templates that are used to merge with data. I have a list of available fields in a panel next to the editor. If the focus switches to the list box the caret is not drawn in the editor.

I understand why that would be the default. In my case once I find the field I want to insert I look back at the document to make sure it will be added to the right location before I click on my "Add Field" button. I can't visually confirm that because the cursor is gone.

I looked at the OnDrawCustomCaret but that seems to also only be called if the editor has focus.

Thanks,

Mark

Posted: Fri Sep 14, 2012 7:21 am
by Sergey Tkachenko
It's not possible to display a system caret when the editor is not focused (well, it is possible, but the result will be very buggy, with editors from different windows and even applications stealing the caret from each other back and forth)
Theoretically, a custom caret could be modified to be used in an inactive window. But it is not a good idea as well, because the caret means that when the user types, the input goes to the caret position. If the focus is not in the editor, it does not happen, so users will be confused.

So I strongly suggest to reconsider your UI.
Either use controls that cannot have focus (like toolbars), or use drag&drop to insert from list box to the editor, see http://www.trichview.com/forums/viewtopic.php?t=3407

Posted: Fri Sep 14, 2012 9:52 pm
by MarkElder
I understand your suggestion, but things are working very well with the exception of being able to visually see where the cursor position is. I agree it should not actually be the cursor. That could confuse the user. This is more like having text highlighted. The selected text is still visible even when the editor does not have focus.

But all is not lost - Where there is a will there is a way :-). I've made this work by Painting on top of the page.

Thanks for providing such a great flexible component that allows this type of function.

Posted here in case it is useful to others.

Code: Select all


procedure TTemplateDesignerMain.RichViewPaintPage(Sender: TObject;
  PageNo: Integer; PageRect, R: TRect; Canvas: TCanvas; Prepaint,
  Printing: Boolean);
var
  AControl: TControl;
  ItemRect: TRect;
  CursorCenter: TPoint;

  Tri: Array[1..3] of TPoint;

  CursorPage: integer;

begin
  if (Printing = true) or (Prepaint = true) then
    exit;  // >>----->

  // There can be inplace editors that are not the main RichView.
  // Loop up through parents to see if we are the active control.
  // If we are then just exit.  Only draw the marker when the cursor
  // is not blinking.
  AControl := Self.ActiveControl;
  while AControl <> nil do
  begin
    if AControl = RichView then
      exit;  // >>-----> We are active - nothing to do right now.

    AControl := AControl.Parent;
  end;



  ItemRect := RichView.GetRVCaretRect(CursorPage);
  if CursorPage <> PageNo then
    exit; // >>-----> Drawing wronge page, nothing to draw


  // The cursor position is from the page top/left corner
  // When dawing here we need to adjust by the possible space around
  // the outside of the page.  The PageRec position tells us how much
  // filler space is there.
  OffsetRect(ItemRect, PageRect.Left, PageRect.Top);

  CursorCenter.X := (ItemRect.Left + ItemRect.Right) div 2;
  CursorCenter.Y := (ItemRect.Top + ItemRect.Bottom) div 2;

  Tri[1] := CursorCenter;

  Tri[2].X := CursorCenter.X - 5;
  Tri[2].Y := CursorCenter.Y + 5;

  Tri[3].X := CursorCenter.X + 5;
  Tri[3].Y := CursorCenter.Y + 5;

  Canvas.Pen.Color := clRed;
  Canvas.Brush.Color := clRed;
  Canvas.Brush.Style := bsSolid;

  Canvas.Polygon(Tri);
end;


procedure TTemplateDesignerMain.RichViewExit(Sender: TObject);
begin
  RichView.RichViewEdit.Repaint;
end;