Sign up

Deeper into the mire

OK, checking for the null ListSG, my getTags method appears to work. But then, having got a tag or more, I want to know what font and color are in effect at that point in the TextBuffer. The example is getting bigger, as now I have to select and apply a color to some selected text.

Relevant (I think) section is marked with //************************:

module tb;

import std.stdio;
import glib.ListSG;
import gtk.Main;
import gtk.MainWindow;
import gtk.Layout;
import gtk.TextTag;
import gtk.TextView;
import gtk.TextBuffer;
import gtk.TextIter;
import gtk.Button;
import gtk.Label;
import gdk.Color;
import gtk.ColorSelectionDialog;
import gtk.ColorSelection;
import gobject.Value;

class Tb : MainWindow
{
    TextView te;
    TextBuffer tb;
    ubyte[] ub;
    Label l;

   void setColor()
   {
      Color color = new Color();
      ColorSelectionDialog csd = new ColorSelectionDialog("Choose a Color");
      ColorSelection cs = csd.getColorSelection();
      int response = csd.run();
      if (response != ResponseType.OK)
      {
         csd.destroy();
         return;
      }
      cs.getCurrentColor(color);
      csd.destroy();
      TextIter start, end;
      start = new TextIter();
      end = new TextIter();
      TextBuffer tb = te.getBuffer();
      if (tb.getSelectionBounds(start, end))
      {
         TextTag tt = tb.createTag("T42", "foreground", color.toString());
         tb.applyTag(tt, start, end);
      }
   }

   private static TextTag[] getTagArray(TextIter ti)
   {
      TextTag[] tta;
      ListSG sll = ti.getTags();
      if (!sll)
      {
         tta.length = 0;
         return tta;
      }
      tta.length = sll.length;
      for (int i = 0; i < sll.length; i++)
      {
         tta[i] = *(cast(TextTag*) sll.data);
         if (i < sll.length-1)
            sll.next();
      }
      return tta;
   }

    this()
    {
        super("TextIter.getTags() test");
        Layout f = new Layout(null, null);
        f.setSizeRequest(300, 300);
        te = new TextView();
        tb = te.getBuffer();
        te.setSizeRequest(290, 200);
        te.setRightMargin(2);
        te.doref();

        f.put(te, 5, 5);

        Button b = new Button("Color");
        b.addOnClicked(&btnClick);
        f.put(b, 5, 210);

        l = new Label("??");
        f.put(l, 5, 240);
        add(f);
        showAll();
    }

   void btnClick(Button b)
   {
      setColor();

// **************************************************************************
// Ok, we set a color for the first word of the text, so at offset 0, there
// should be a tag in effect
      TextIter cp = new TextIter();
      tb.getIterAtOffset(cp, 0);
      TextTag[] ta = getTagArray(cp);
      // We see one tag here
      writefln("Tags %d", ta.length);
      Value v = new Value();
      v.init(GType.STRING);
      writeln("before getProperty()");
      // In my app, I want to know if color or font, or both have changed
      // I try font first
      ta[0].getProperty ("font", v);
      writeln("after getProperty()");
      string f = v.getString();
      writeln(f); // We have not changed the font - should be 'normal'
      l.setText(f);
// **************************************************************************
   }

}

void main(string[] args)
{
   Main.init(args);
   new Tb();
   Main.run();
}

Run it and enter a couple of words in the TextView. Select the first word, then press the Color button, that will let you set a color for the word, and will then run the offending code.

Re: Deeper into the mire

On 11/12/2013 10:09 AM, Steve Teale wrote:

OK, checking for the null ListSG, my getTags method appears to work. But then, having got a tag or more, I want to know what font and color are in effect at that point in the TextBuffer. The example is getting bigger, as now I have to select and apply a color to some selected text.

Relevant (I think) section is marked with //************************:

... code ...

Run it and enter a couple of words in the TextView. Select the first word, then press the Color button, that will let you set a color for the word, and will then run the offending code.

This is something that can use some improvement within GtkD, The linked
list contains pointers to the C struct a GtkTextTag* and not a D class.

To fix the example code change line 62 from:

          tta[i] = *(cast(TextTag*) sll.data);

to:

          tta[i] = new TextTag(cast(GtkTextTag*) sll.data);

As for the bast way to improve GtkD in this respect, i will probably add
something like "getTagArray" to TextIter, and ditto for similar
functions. What do you think?

Re: Deeper into the mire

This is something that can use some improvement within GtkD, The linked
list contains pointers to the C struct a GtkTextTag* and not a D class.

To fix the example code change line 62 from:

          tta[i] = *(cast(TextTag*) sll.data);

to:

          tta[i] = new TextTag(cast(GtkTextTag*) sll.data);

As for the bast way to improve GtkD in this respect, i will probably add
something like "getTagArray" to TextIter, and ditto for similar
functions. What do you think?

Ah, all is clear now. getTagArray is a nice idea, but if you do it here then you might end up having to do similar things everywhere. Would it be feasible to provide an opAssign from GtkTextTag*. Then people could write even more naive code like

    tta[i] = sll.data;

and get the result they wanted? But you'd have to do that everywhere as well ;=(

Thank you for your excellent assistance Mike.

Re: Deeper into the mire

On 11/13/2013 08:04 AM, Steve Teale wrote:

Ah, all is clear now. getTagArray is a nice idea, but if you do it here then you might end up having to do similar things everywhere. Would it be feasible to provide an opAssign from GtkTextTag*. Then people could write even more naive code like

     tta[i] = sll.data;

and get the result they wanted? But you'd have to do that everywhere as well ;=(

Looks good, but i whould like:

	tta ~= sll.data;

to also work in that case.

Thank you for your excellent assistance Mike.

For now i added a toArray function to the linked list, with that the
code would be:

tta = sll.toArray!TextTag();