You've already forked lazarus-ccr
richmemo: improve gtk2 support. + InDel operation, + paragraph alignment, * improved getting / setting text attributes
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3734 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -42,10 +42,21 @@ type
|
||||
TGtk2WSCustomRichMemo = class(TWSCustomRichMemo)
|
||||
protected
|
||||
class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo);
|
||||
class procedure GetWidgetBuffer(const AWinControl: TWinControl; var TextWidget: PGtkWidget; var Buffer: PGtkTextBuffer);
|
||||
class function GetAttrAtPos(const AWinControl: TWinControl; TextStart: Integer): PGtkTextAttributes;
|
||||
class procedure ApplyTag(abuffer: PGtkTextBuffer; tag: PGtkTextTag; TextStart, TextLen: Integer; ToParagraphs: Boolean = False);
|
||||
published
|
||||
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
||||
class procedure SetTextAttributes(const AWinControl: TWinControl; TextStart, TextLen: Integer; const Params: TIntFontParams); override;
|
||||
|
||||
class function GetTextAttributes(const AWinControl: TWinControl; TextStart: Integer; var Params: TIntFontParams): Boolean; override;
|
||||
class procedure SetTextAttributes(const AWinControl: TWinControl; TextStart, TextLen: Integer; const Params: TIntFontParams); override;
|
||||
|
||||
class function GetParaAlignment(const AWinControl: TWinControl; TextStart: Integer;
|
||||
var AAlign: Integer): Boolean; override;
|
||||
class procedure SetParaAlignment(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||
const AAlign: Integer); override;
|
||||
|
||||
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -66,6 +77,10 @@ var
|
||||
w : integer;
|
||||
st : TPangoStyle;
|
||||
pf : PPangoFontDescription;
|
||||
sz : double;
|
||||
const
|
||||
ScreenDPI = 96; // todo: might change, should be received dynamically
|
||||
PageDPI = 72; // not expected to be changed
|
||||
begin
|
||||
FontParams.Style := [];
|
||||
FontParams.Name := '';
|
||||
@@ -79,9 +94,10 @@ begin
|
||||
if Assigned(pf) then begin
|
||||
FontParams.Name := pango_font_description_get_family(pf);
|
||||
FontParams.Size := pango_font_description_get_size(pf);
|
||||
if not pango_font_description_get_size_is_absolute(pf) then
|
||||
FontParams.Size := Round(FontParams.Size / PANGO_SCALE);
|
||||
|
||||
sz:=FontParams.Size / PANGO_SCALE;
|
||||
if pango_font_description_get_size_is_absolute(pf) then
|
||||
sz:=sz/(ScreenDPI/PageDPI);
|
||||
FontParams.Size:=round(sz);
|
||||
w := pango_font_description_get_weight(pf);
|
||||
if w > PANGO_WEIGHT_NORMAL then Include(FontParams.Style, fsBold);
|
||||
|
||||
@@ -101,6 +117,60 @@ begin
|
||||
TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomRichMemo.GetWidgetBuffer(const AWinControl: TWinControl;
|
||||
var TextWidget: PGtkWidget; var Buffer: PGtkTextBuffer);
|
||||
var
|
||||
Widget : PGtkWidget;
|
||||
list : PGList;
|
||||
begin
|
||||
TextWidget:=nil;
|
||||
Buffer:=nil;
|
||||
// todo: cache values?
|
||||
Widget := PGtkWidget(PtrUInt(AWinControl.Handle));
|
||||
|
||||
list := gtk_container_get_children(PGtkContainer(Widget));
|
||||
if not Assigned(list) then Exit;
|
||||
|
||||
TextWidget := PGtkWidget(list^.data);
|
||||
if not Assigned(TextWidget) then Exit;
|
||||
|
||||
buffer := gtk_text_view_get_buffer (PGtkTextView(TextWidget));
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomRichMemo.GetAttrAtPos(
|
||||
const AWinControl: TWinControl; TextStart: Integer): PGtkTextAttributes;
|
||||
var
|
||||
TextWidget : PGtkWidget;
|
||||
buffer : PGtkTextBuffer;
|
||||
iter : TGtkTextIter;
|
||||
attr : PGtkTextAttributes;
|
||||
begin
|
||||
Result:=nil;
|
||||
GetWidgetBuffer(AWinControl, TextWidget, buffer);
|
||||
|
||||
attr := gtk_text_view_get_default_attributes(PGtkTextView(TextWidget));
|
||||
if not Assigned(attr) then Exit;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset(buffer, @iter, TextStart);
|
||||
gtk_text_iter_get_attributes(@iter, attr);
|
||||
Result:=attr;
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomRichMemo.ApplyTag(abuffer: PGtkTextBuffer;
|
||||
tag: PGtkTextTag; TextStart, TextLen: Integer; ToParagraphs: Boolean = False);
|
||||
var
|
||||
istart : TGtkTextIter;
|
||||
iend : TGtkTextIter;
|
||||
begin
|
||||
gtk_text_buffer_get_iter_at_offset (abuffer, @istart, TextStart);
|
||||
gtk_text_buffer_get_iter_at_offset (abuffer, @iend, TextStart+TextLen);
|
||||
if ToParagraphs then begin
|
||||
gtk_text_iter_set_line_offset(@istart, 0);
|
||||
gtk_text_iter_forward_to_line_end(@iend);
|
||||
end;
|
||||
gtk_text_buffer_apply_tag(abuffer, tag, @istart, @iend);
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomRichMemo.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
|
||||
var
|
||||
Widget,
|
||||
@@ -152,12 +222,9 @@ end;
|
||||
|
||||
class procedure TGtk2WSCustomRichMemo.SetTextAttributes(const AWinControl: TWinControl; TextStart, TextLen: Integer; const Params: TIntFontParams);
|
||||
var
|
||||
Widget, TextWidget: PGtkWidget;
|
||||
list : PGList;
|
||||
TextWidget: PGtkWidget;
|
||||
buffer : PGtkTextBuffer;
|
||||
tag : Pointer;
|
||||
istart : TGtkTextIter;
|
||||
iend : TGtkTextIter;
|
||||
gcolor : TGdkColor;
|
||||
nm : string;
|
||||
const
|
||||
@@ -165,21 +232,12 @@ const
|
||||
PangoBold : array [Boolean] of Integer = (PANGO_WEIGHT_NORMAL, PANGO_WEIGHT_BOLD);
|
||||
PangoItalic : array [Boolean] of Integer = (PANGO_STYLE_NORMAL, PANGO_STYLE_ITALIC);
|
||||
begin
|
||||
Widget := PGtkWidget(PtrUInt(AWinControl.Handle));
|
||||
|
||||
list := gtk_container_get_children(PGtkContainer(Widget));
|
||||
if not Assigned(list) then Exit;
|
||||
|
||||
TextWidget := PGtkWidget(list^.data);
|
||||
if not Assigned(TextWidget) then Exit;
|
||||
|
||||
buffer := gtk_text_view_get_buffer (PGtkTextView(TextWidget));
|
||||
GetWidgetBuffer(AWinControl, TextWidget, buffer);
|
||||
if not Assigned(buffer) then Exit;
|
||||
|
||||
gcolor := TColortoTGDKColor(Params.Color);
|
||||
nm := Params.Name;
|
||||
if nm = '' then nm := #0;
|
||||
|
||||
tag := gtk_text_buffer_create_tag (buffer, nil,
|
||||
'family-set', [gboolean(gTRUE),
|
||||
'family', @nm[1],
|
||||
@@ -195,44 +253,82 @@ begin
|
||||
'strikethrough-set', gboolean(gTRUE),
|
||||
'strikethrough', gboolean(fsStrikeOut in Params.Style),
|
||||
nil]);
|
||||
ApplyTag(buffer, tag, TextStart, TextLen);
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, @istart, TextStart);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, @iend, TextStart+TextLen);
|
||||
gtk_text_buffer_apply_tag(buffer, tag, @istart, @iend);
|
||||
end;
|
||||
|
||||
class function TGtk2WSCustomRichMemo.GetParaAlignment(
|
||||
const AWinControl: TWinControl; TextStart: Integer; var AAlign: Integer
|
||||
): Boolean;
|
||||
var
|
||||
attr : PGtkTextAttributes;
|
||||
begin
|
||||
attr:=GetAttrAtPos(AWinControl, TextStart);
|
||||
Result := Assigned(attr);
|
||||
if Result then begin
|
||||
case attr^.justification of
|
||||
GTK_JUSTIFY_LEFT: AAlign:=AL_LEFT;
|
||||
GTK_JUSTIFY_RIGHT: AAlign:=AL_RIGHT;
|
||||
GTK_JUSTIFY_CENTER: AAlign:=AL_CENTER;
|
||||
GTK_JUSTIFY_FILL: AAlign:=AL_JUSTIFY;
|
||||
else
|
||||
AAlign:=AL_LEFT;
|
||||
end;
|
||||
gtk_text_attributes_unref(attr);
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomRichMemo.SetParaAlignment(
|
||||
const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||
const AAlign: Integer);
|
||||
var
|
||||
w : PGtkWidget;
|
||||
buffer : PGtkTextBuffer;
|
||||
tag : PGtkTextTag;
|
||||
val : Integer;
|
||||
begin
|
||||
val := GTK_JUSTIFY_LEFT;
|
||||
case AAlign of
|
||||
AL_RIGHT: val:=GTK_JUSTIFY_RIGHT;
|
||||
AL_CENTER: val:=GTK_JUSTIFY_CENTER;
|
||||
AL_JUSTIFY: val:=GTK_JUSTIFY_FILL;
|
||||
end;
|
||||
GetWidgetBuffer(AWinControl, w, buffer);
|
||||
tag := gtk_text_buffer_create_tag (buffer, nil,
|
||||
'justification', [ val,
|
||||
'justification-set', gboolean(gTRUE),
|
||||
nil]);
|
||||
ApplyTag(buffer, tag, TextStart, TextLen, true);
|
||||
end;
|
||||
|
||||
class procedure TGtk2WSCustomRichMemo.InDelText(const AWinControl: TWinControl;
|
||||
const TextUTF8: String; DstStart, DstLen: Integer);
|
||||
var
|
||||
w : PGtkWidget;
|
||||
b : PGtkTextBuffer;
|
||||
istart : TGtkTextIter;
|
||||
iend : TGtkTextIter;
|
||||
begin
|
||||
GetWidgetBuffer(AWinControl, w, b);
|
||||
if not Assigned(b) then Exit;
|
||||
gtk_text_buffer_get_iter_at_offset (b, @istart, DstStart);
|
||||
gtk_text_buffer_get_iter_at_offset (b, @iend, DstStart+DstLen);
|
||||
gtk_text_buffer_delete(b, @istart, @iend);
|
||||
if length(TextUTF8)>0 then
|
||||
gtk_text_buffer_insert(b, @istart, @textUTF8[1], length(TextUTF8));
|
||||
end;
|
||||
|
||||
|
||||
class function TGtk2WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl; TextStart: Integer; var Params: TIntFontParams): Boolean;
|
||||
var
|
||||
Widget : PGtkWidget;
|
||||
TextWidget : PGtkWidget;
|
||||
list : PGList;
|
||||
buffer : PGtkTextBuffer;
|
||||
iter : TGtkTextIter;
|
||||
attr : PGtkTextAttributes;
|
||||
begin
|
||||
Widget := PGtkWidget(PtrUInt(AWinControl.Handle));
|
||||
|
||||
list := gtk_container_get_children(PGtkContainer(Widget));
|
||||
if not Assigned(list) then Exit;
|
||||
|
||||
TextWidget := PGtkWidget(list^.data);
|
||||
if not Assigned(TextWidget) then Exit;
|
||||
|
||||
buffer := gtk_text_view_get_buffer (PGtkTextView(TextWidget));
|
||||
if not Assigned(buffer) then Exit;
|
||||
|
||||
attr := gtk_text_view_get_default_attributes(PGtkTextView(TextWidget));
|
||||
attr:=GetAttrAtPos(AWinControl, TextStart);
|
||||
Result := Assigned(attr);
|
||||
if not Assigned(attr) then Exit;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset(buffer, @iter, TextStart);
|
||||
Result := gtk_text_iter_get_attributes(@iter, attr);
|
||||
//if Result then
|
||||
{Result := }
|
||||
Result := true;
|
||||
if Result then begin
|
||||
GtkTextAttrToFontParams(attr^, Params);
|
||||
gtk_text_attributes_unref(attr);
|
||||
gtk_text_attributes_unref(attr);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Reference in New Issue
Block a user