garrigue/lablgtk

Custom widget

Opened this issue · 2 comments

dakk commented

Is it possible to create a custom widget using lablgtk3? If it is possible I beg for some hints, since reading the library code I'm unable to understand

dakk commented

I may have found a valid solution (not sure if the best) by inheriting from an instantiated drawing area (ora another widget); this is the cairo example modified:

open Cairo

let pi2 = 8. *. atan 1.

class dial_widget ?packing ?show () =
  let da = GMisc.drawing_area ?packing ?show () in
  object (self)
    inherit GObj.widget da#as_widget

    val mutable opac = 0.5

    method change_opacity () =
      opac <- if opac = 0.5 then 1.0 else 0.5;
      self#misc#queue_draw ()

    method draw cr =
      let allocation = self#misc#allocation in
      let width = float allocation.Gtk.width in
      let height = float allocation.Gtk.height in

      let r = 0.25 *. width in
      set_source_rgba cr 0. 1. 0. opac;
      arc cr (0.5 *. width) (0.35 *. height) ~r ~a1:0. ~a2:pi2;
      fill cr;
      set_source_rgba cr 1. 0. 0. opac;
      arc cr (0.35 *. width) (0.65 *. height) ~r ~a1:0. ~a2:pi2;
      fill cr;
      set_source_rgba cr 0. 0. 1. opac;
      arc cr (0.65 *. width) (0.65 *. height) ~r ~a1:0. ~a2:pi2;
      fill cr;
      
      true

    initializer
      ignore(self#misc#connect#draw ~callback:(self#draw))
end

   
let () =
  let _ = GMain.init () in
  let w = GWindow.window ~title:"Cairo custom widget demo" ~width:500 ~height:400 () in
  ignore(w#connect#destroy ~callback:GMain.quit);
   
  let hbox = GPack.hbox ~packing:w#add () in
  let button = GButton.button ~packing:(hbox#pack ~padding:5) () in
  let d = new dial_widget ~packing:hbox#add () in

  button#connect#clicked ~callback:
    (fun () -> d#change_opacity ());

  w#show();
  GMain.main()

Thanks for you example, I suppose we should document this somewhere (or just add your example).

Note that creating custom widgets in lablgtk is low level, and there is virtually no support for that.