IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Popup personnalisé en LablGtk


Sujet :

Caml

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Popup personnalisé en LablGtk
    Bonsoir,

    Je développe actuellement un IDE pour Ocaml et C sous linux dans le cadre d'un projet libre au sein de mon ecole d'informatique.
    J'en suis à la partie autocomplétion seulement j'aimerais affiché les résultats de mon autocomplétion dans une popup qui se positionnerai directement un peu avan le curseur de texte (et non celui de la souris).

    Mes problèmes :

    - Je ne trouve pas de widgets qui peuvent "pop" a des positions spécifiques (j'entend par la des positions que je définis moi même en x et en y), j'ai regarder du coté des GPack.fixed mais je ne vois pas comment mettre deux item les uns sur les autres.

    - Pour pouvoir placer correctement ma popup, il me faudrait recuperer les coordonnées du curseur de texte, j'utilise un GSourceView2 (widget heritant de GText.view).


    Ce que j'ai essayé de faire :

    - Créer un TextView et un GButton et les mettre dans un Gpack.fixed, seulement lorsque je positionne le button dans mon texte, il disparait, (j'en ai conclu donc que si je faisais de même avec un GMenu.menu ce serait le même problème.

    - Créer un GMenu.menu et représenter les résultats de l'autocomplétion par des GMenu.menu_item, mais le problème est que lorsque je fais pop le menu, il se place sous le curseur de la souris et non sur celui du texte, et le 2nd problème est que je ne peux plus écrire tant que je n'ai pas fait disparaitre le menu.

    Je remercie d'avance les courageux(ses) qui prendront le temps de trouver une solution à mon problème.

  2. #2
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    J'avais fait quelque chose de semblable pour mon projet OCamlTeX (toujours pas terminé...). Il s'agissait d'un GtkTreeView qui apparaissait au niveau du curseur pour compléter la saisie de commandes LaTeX dans un widget GtkSourceView2. Bref, ça semble approcher de ton problème.

    Je n'ai plus travaillé sur ce projet depuis longtemps. Les sources sont toujours en ligne sur SourceForge (lien dans ma signature) mais voici quand même le contenu du fichier qui te sera le plus utile. On peut s'en servir de base pour discuter de la meilleure façon de résoudre ton problème. J'ai mis en vert ce qui me semble le plus utile pour toi. Il y a des références à des bouts de code qui ne sont pas repris ici mais ils ne sont pas utiles à la compréhension de l'ensemble.

    Méthodes-clefs : source_view#add_child_in_window, source_view#get_iter_location et source_view#move_child.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    type data = {
      col_icon : GtkStock.id GTree.column;    (* LaTeX item stock id. *)
      col_text : string GTree.column;         (* LaTeX item markup.   *)
      col_item : LaTeX.Main.t GTree.column;   (* LaTeX item.          *)
      store : GTree.list_store;               (* List store.          *)
    }
    
    type area = {
      frame : GObj.widget;                    (* Popup frame.         *)
      scroll : GBin.scrolled_window;          (* Scrolled window.     *)
      view : GTree.view                       (* List view.           *)
    }
    
    type t = { 
      data : data; 
      vcol : GTree.view_column; 
      area : area;
      source : GSourceView2.source_view;
      buffer : GSourceView2.source_buffer
    }
    
    (* Some getters to hide the implementation in the code below. *)
    let col_icon t = t.data.col_icon
    let col_text t = t.data.col_text
    let col_item t = t.data.col_item
    let view_col t = t.vcol
    let store t = t.data.store
    let source t = t.source
    let buffer t = t.buffer
    let frame t = t.area.frame
    let view t = t.area.view
    
    (* Code completion popup window. *)
    module Popup =
      struct
        (* Show popup with suggestions. *)
        let show =
          let arrow = Gdk.Cursor.create `ARROW in
          fun t (x, y) ->
            let child = frame t in
            (source t)#move_child ~child ~x ~y;
            child#misc#show ();
            Gdk.Window.set_cursor (view t)#misc#window arrow
        (* Hide popup and clear contents. 
         * The unused second argument and the boolean value are both needed by 
         * button_press and scroll events. *)
        let hide t _ =
          (frame t)#misc#hide ();
          false
      end
    
    (* Get selected iter. *)
    let get_selected_iter t =
      match (view t)#selection#get_selected_rows with
      | path :: _ -> (store t)#get_iter path
      | [] -> 
        match (store t)#get_iter_first with
        | Some iter -> iter
        | _ -> Core.Print.failure 8 "Code completion list view is empty"
    
    (* Try to determine the best popup coordinates. *)
    let best_coord t =
      let r1 = (source t)#get_iter_location ((buffer t)#get_iter `INSERT)
      and r2 = (source t)#visible_rect in
      if Gdk.Rectangle.width r2 > 300 && Gdk.Rectangle.height r2 > 100 then (
        let x = Gdk.Rectangle.x r1 - Gdk.Rectangle.x r2 
        and y = Gdk.Rectangle.y r1 - Gdk.Rectangle.y r2 + 14 in
        Some ((x - if x + 280 >= Gdk.Rectangle.width  r2 then 280 else 0),
        (y - if y + 100 >= Gdk.Rectangle.height r2 then 114 else 0))
      ) else None
    
    (* Add suggestions and show popup. *)
    let suggest t trie =
      let store = store t in
      store#clear ();
      Core.Trie.ASCII.iteri (fun i id ->
        let item = LaTeX.Main.from_trie_id id in
        let row = store#append () in
        store#set ~row ~column:(col_item t) item;
        store#set ~row ~column:(col_icon t) (LaTeX.Main.get_icon item);
        store#set ~row ~column:(col_text t) (LaTeX.Main.to_markup item);
        if i = 0 then (view t)#selection#select_iter row
      ) trie;
      Gaux.may (Popup.show t) (best_coord t)
    
    (* Try to determine whether the current input is a LaTeX item. *)
    let check_input =
      let pat = Str.regexp_case_fold "\\\\[a-z]+" in
      fun t () ->
        let stop = (buffer t)#get_iter `INSERT in
        if stop#ends_word then (
          let start = stop#backward_word_start#backward_char in
          let str = (buffer t)#get_text ~start ~stop () in
          if Str.string_match pat str 0 then 
          match LaTeX.Main.get_prefix str with
          | Some trie when Core.Trie.ASCII.length trie > 0 -> suggest t trie
          | _ -> ignore (Popup.hide t ())
        ) else if (frame t)#misc#visible then ignore (Popup.hide t ())
    
    (* Display selected LaTeX item, then hide popup. *)
    let finalize t _ =
      let row = get_selected_iter t in
      let stop = (buffer t)#get_iter `INSERT in
      let start = stop#backward_word_start#backward_char in
      (buffer t)#delete ~start ~stop;
      let cmd = (store t)#get ~row ~column:(col_item t) in
      Core.FunTable.run_with_arg "latex-insert" cmd ();
      Popup.hide t ()
    
    (* Choose action when a key is pressed. *)
    let select_action t ev =
      if (frame t)#misc#visible then (
        let here = (store t)#get_path (get_selected_iter t) in
        match GdkEvent.Key.keyval ev with
          | 0xFF52 (* Up arrow *) -> GTree.Path.prev here;
            (view t)#set_cursor here (view_col t); true
          | 0xFF54 (* Down arrow *) -> GTree.Path.next here;
            (view t)#set_cursor here (view_col t); true
          | 0xFF0D | 0xFF8D (* Entry *) -> not (finalize t ())
          | 0xFF1B | 0xFF08 | 0xFF9A | 0xFF9B | 0xFF95
          | 0xFF96 | 0xFF98 | 0xFF51 | 0xFF53 -> Popup.hide t ()
          | _ -> false
      ) else false
    
    (* Tree view data. *)
    let get_data () =
      let cols = new GTree.column_list in
      let col_icon = cols#add GtkStock.conv
      and col_text = cols#add Gobject.Data.string
      and col_item = cols#add Gobject.Data.caml
      and store = GTree.list_store cols in
      { col_icon = col_icon; col_text = col_text; col_item = col_item; store = store }
    
    (* Tree view cell renderers and columns. *)
    let get_view data =
      let cell_icon = GTree.cell_renderer_pixbuf []
      and cell_text = GTree.cell_renderer_text [`XPAD 5] in
      let vcol = GTree.view_column () in
      vcol#pack ~expand:false cell_icon;
      vcol#add_attribute cell_icon "stock_id" data.col_icon;
      vcol#pack cell_text;
      vcol#add_attribute cell_text "markup" data.col_text;
      vcol
    
    (* Tree view and scrolled window. *)
    let get_area data vcol =
      let scroll = GBin.scrolled_window
        ~width:280 ~height:80
        ~hpolicy:`NEVER
        ~vpolicy:`ALWAYS
        ~shadow_type:`ETCHED_IN ~show:false () in
      let view = GTree.view 
        ~model:data.store
        ~headers_visible:false
        ~rules_hint:true 
        ~packing:scroll#add () in
      view#append_column vcol;
      view#set_hover_selection true;
      { frame = scroll#coerce; scroll = scroll; view = view }
    
    (* Main function. *)
    let add (source : GSourceView2.source_view) =
      let data = get_data () in
      let vcol = get_view data in
      let area = get_area data vcol in
      source#add_child_in_window ~child:area.frame ~which_window:`TEXT ~x:0 ~y:0;
      let buffer = source#source_buffer in
      let t = { data = data; vcol = vcol; area = area; source = source; buffer = buffer } in
      buffer#connect#changed (check_input t);
      (view t)#event#connect#button_release (finalize t);
      let connect = source#event#connect in
      connect#key_press (select_action t);
      connect#button_press (Popup.hide t);
      connect#scroll (Popup.hide t);
      t
    Cordialement,
    Cacophrène

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Tout d'abord un grand merci pour ta réponse qui m'a été d'une grande aide.

    J'ai réussi à faire marcher ton bout de code dans mon projet, en créant une frame constituée d'une scrolled_window et d'un GSourceView2 (c'était juste pour tester).
    Seulement par la suite j'ai modifier le contenue de la frame en remplacant la scrolled_window et le source_view par un GMenu.menu et un GMenu.menu_item afin de créer une liste de tout les mots trouvés par mon arbre_lexical pour l'autocomplétion, et là lors de l'exécution du programme la frame ne s'affiche plus et j'ai le droit a ce message d'erreur des que j'exécute le programme en tappant : lablgtk2 test.ml

    (ocaml:4633): Gtk-CRITICAL **: IA__gtk_text_view_add_child_in_window: assertion `child->parent == NULL' failed

    puis lorsque j'appui sur une touche l'erreur suivante apparait :

    (ocaml:4633): Gtk-CRITICAL **: IA__gtk_text_view_move_child: assertion `child->parent == (GtkWidget*) text_view' failed

    ce serait vraiment sympa de m'expliquer le pourquoi du comment :p
    voici le code de mon test.ml un peu, beaucoup, inspir" du tiens

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    open GMain
     
    type area = {
      frame : GObj.widget;                    (* Popup frame.         *)
      menu : GMenu.menu;
      menu_item : GMenu.menu_item
    }
     
    type t = { 
      area : area;
      source : GSourceView2.source_view;
      buffer : GSourceView2.source_buffer
    }
     
    (* Some getters to hide the implementation in the code below. *)
    let source t = t.source
    let buffer t = t.buffer
    let frame t = t.area.frame
    let menu t = t.area.menu
    let menu_item t= t.area.menu_item
     
    module Popup =
      struct
        (* Show popup *)
        let show =
          fun t (x, y) ->
            let child = frame t in
            (source t)#move_child ~child ~x ~y;
            child#misc#show ()
        (* Hide popup and clear contents.*) 
        let hide t _ =
            (frame t)#misc#hide (); 
          false
      end
     
    (* Try to determine the best popup coordinates. *)
    let best_coord t =
      let r1 = (source t)#get_iter_location ((buffer t)#get_iter `INSERT)
      and r2 = (source t)#visible_rect in
      if Gdk.Rectangle.width r2 > 300 && Gdk.Rectangle.height r2 > 100 then (
        let x = Gdk.Rectangle.x r1 - Gdk.Rectangle.x r2 
        and y = Gdk.Rectangle.y r1 - Gdk.Rectangle.y r2 + 14 in
        Some ((x - if x + 280 >= Gdk.Rectangle.width  r2 then 280 else 0),
        (y - if y + 100 >= Gdk.Rectangle.height r2 then 114 else 0))
      ) else None
     
    (* show popup. *)
     
    let check_input =
      fun t () ->
        let stop = (buffer t)#get_iter `INSERT in
        if stop#ends_word then (
          let start = stop#backward_word_start#backward_char in
          let str = (buffer t)#get_text ~start ~stop () in
             Gaux.may (Popup.show t) (best_coord t)
        ) else if (frame t)#misc#visible then ignore (Popup.hide t ())
     
    (* hide popup. *)
    let finalize t _ =
      let stop = (buffer t)#get_iter `INSERT in
      let start = stop#backward_word_start#backward_char in
      (buffer t)#delete ~start ~stop; 
      Popup.hide t ()
     
    (* Choose action when a key is pressed. *)
    let select_action t ev =
      if (frame t)#misc#visible then (
        match GdkEvent.Key.keyval ev with
          | 0xFF52 (* Up arrow *) -> print_endline "Up Arrow"; true
          | 0xFF54 (* Down arrow *) -> print_endline "Down Arrow"; true
          | 0xFF0D | 0xFF8D (* Entry *) -> not (finalize t ())
          | 0xFF1B | 0xFF08 | 0xFF9A | 0xFF9B | 0xFF95
          | 0xFF96 | 0xFF98 | 0xFF51 | 0xFF53 -> Popup.hide t ()
          | _ -> false
      ) else false
     
    let get_area _ =
        let menu = GMenu.menu ~show:false () in
        let menu_item = GMenu.menu_item ~label:"test for autocomplétion" ~packing:menu#append () in
        { frame = menu#coerce; menu = menu; menu_item = menu_item }
     
    (* Main function. *)
    let add (source : GSourceView2.source_view) =
      let area = get_area source in
      source#add_child_in_window ~child:area.frame ~which_window:`TEXT ~x:0 ~y:0;
      let buffer = source#source_buffer in
      let t = {area = area; source = source; buffer = buffer } in
      buffer#connect#changed (check_input t);
      (menu_item t)#event#connect#button_release (finalize t);
      let connect = source#event#connect in
      connect#key_press (select_action t);
      connect#button_press (Popup.hide t);
      connect#scroll (Popup.hide t);
      t
     
    let window = GWindow.window 
        ~width:800
        ~height:600 ()
     
    let text = GSourceView2.source_view
        ~packing:window#add () 
     
    let _ =
      add text;
      window#show ();
      window#connect#destroy ~callback:Main.quit;
      Main.main ()

  4. #4
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    L'erreur indique que le widget a déjà un parent. Le problème vient du type de widget à afficher. Pour une liste d'éléments, tu réussiras mieux avec un treeview (sous sa forme listview).

    Cordialement,
    Cacophrène

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Je tiens avant tout a te remercier car j'ai plus ou moin réussi a ce que je voulais faire avec le treeview, seulement mon autocomplétion ne marche que lorsque je double click sur le mot que je souhaite selectionné, mais lorsque je veux y acceder avec les touches du clavier j'ai deux erreurs :

    -la première est que je ne peux accedé uniquement aux 2 premiers éléments de mon tree_view :s

    -la seconde est que lorsque j'appui sur entré la fonction qui est sensé récupérer le contenu de ma string lache une exception dans la console :

    In callback for signal key_press_event, uncaught exception: Invalid_argument("GTree.model#get: bad column")

    voici mon code source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    open GMain
    open GtkTree
    open Gobject.Data
    open StdLabels
     
    (*let abrLex = new Arbre_lexical.abrLex *)
     
    let toplevel = ref [""]
     
    type data = {
      col_text : string GTree.column;     
      list_store : GTree.list_store;               (* List store.          *)
    }
     
    type area = {
      frame : GObj.widget;                    (* Popup frame.         *)
      scroll : GBin.scrolled_window;
      tree_view : GTree.view;
    }
     
    type t = { 
      data : data;
      area : area;
      vcol : GTree.view_column;
      source : GSourceView2.source_view;
      buffer : GSourceView2.source_buffer
    }
     
    (* Some getters to hide the implementation in the code below. *)
     
    let col_text t = t.data.col_text
    let source t = t.source
    let buffer t = t.buffer
    let frame t = t.area.frame
    let scroll t = t.area.scroll
    let tree_view t = t.area.tree_view
    let list_store t = t.data.list_store
    let view_col t = t.vcol
     
    module Popup =
      struct
        (* Show popup *)
        let show =
          fun t (x, y) ->
            let child = frame t in
            (source t)#move_child ~child ~x ~y;
            child#misc#show ()
        (* Hide popup and clear contents.*) 
        let hide t _ =
            (frame t)#misc#hide (); 
          false
      end
     
    let cols = new GTree.column_list
    let name = cols#add string
     
    let create_store () =
        let list_store = GTree.list_store cols in 
        List.iter !toplevel ~f:
        begin fun n ->
          let row = list_store#append () in
          list_store#set ~row ~column:name n;
       end;
      list_store
     
    let failure n fmt =
      Printf.ksprintf (fun msg ->
        Printf.eprintf "%s.\n%!" msg;
        exit n
      ) ("(Aurora) Error: " ^^ fmt)
     
    (* Get selected iter. *)
    let get_selected_iter t =
      match (tree_view t)#selection#get_selected_rows with
      | path :: _ -> (list_store t)#get_iter path
      | [] -> 
        match (list_store t)#get_iter_first with
        | Some iter -> iter
        | _ -> failure 8 "empty"
     
     
     
    let add_columns ~(view : GTree.view) =
      let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
      let vc =
        GTree.view_column ~renderer:(renderer, ["text", name]) ()
      in
      view#append_column vc
     
    (* Try to determine the best popup coordinates. *)
    let best_coord t =
      let r1 = (source t)#get_iter_location ((buffer t)#get_iter `INSERT)
      and r2 = (source t)#visible_rect in
      if Gdk.Rectangle.width r2 > 300 && Gdk.Rectangle.height r2 > 100 then (
        let x = Gdk.Rectangle.x r1 - Gdk.Rectangle.x r2 
        and y = Gdk.Rectangle.y r1 - Gdk.Rectangle.y r2 + 14 in
        Some ((x - if x + 280 >= Gdk.Rectangle.width  r2 then 280 else 0),
        (y - if y + 100 >= Gdk.Rectangle.height r2 then 114 else 0))
      ) else None
     
    (* show popup. *)
    let word = ref ""
    let replace = ref ""
     
     
    let check_input t= 
       let stop = (buffer t)#get_iter `INSERT in
        if stop#ends_word 
        then 
         (
          let start = stop#backward_word_start#backward_char in
          word := (buffer t)#get_text ~start ~stop ();
          (
           if((String.get !word 0) = ' ') 
           then word := String.sub !word 1 ((String.length !word)-1)
          );
          if((List.length !toplevel) <> 0) 
          then(Gaux.may (Popup.show t) (best_coord t))
         ) 
        else if (frame t)#misc#visible then ignore (Popup.hide t ())
     
    (* hide popup. *)
     
    let finalize t _ =
      let row = get_selected_iter t in
      let stop = (buffer t)#get_iter `INSERT in
      let start = stop#backward_word_start#backward_char in
      (buffer t)#delete ~start ~stop;
      replace := (list_store t)#get ~row ~column:(col_text t); 
      (* c'est sur la ligne précédente que j'ai un problème *)
      (buffer t)#insert (" "^(!replace));
      Popup.hide t ()
     
     
    let add_word word t=
          let row = (list_store t)#append () in
          (list_store t)#set ~row ~column:name word
     
    let addArbreLex t =
        (list_store t)#clear ();
        toplevel := ["test";"toto";"why this fucking row is unreachable ?"];
        List.iter (fun e -> add_word e t) !toplevel
     
    (*let on_row_activated t (view:GTree.view) path column =
      let model = view#model in
      let row = model#get_iter path in
      replace := model#get ~row ~column:name;
      print_endline !replace;
      let _ = (finalize t ()) in ()  
    *)
     
    (* Choose action when a key is pressed. *)
    let select_action t ev =
        addArbreLex t;
        if ((List.length !toplevel <> 0) && (frame t)#misc#visible) then (
        let here = (list_store t)#get_path (get_selected_iter t) in
        match GdkEvent.Key.keyval ev with
          | 0xFF52 (* Up arrow *) -> let _ = GTree.Path.prev here in
          let _ = (tree_view t)#set_cursor here (view_col t) in true
          | 0xFF54 (* Down arrow *) ->let _ = GTree.Path.next here in
          let _ = (tree_view t)#set_cursor here (view_col t) in 
          let _ = GTree.Path.next here in true
          | 0xFF0D | 0xFF8D (* Entry *) -> not (finalize t ())
          | 0xFF1B | 0xFF08 | 0xFF9A | 0xFF9B | 0xFF95
          | 0xFF96 | 0xFF98 | 0xFF51 | 0xFF53 -> Popup.hide t ()
          | _ -> false
      ) else false
     
      (* Tree view data. *)
    let get_data () =
      let cols = new GTree.column_list in
      let col_text = cols#add Gobject.Data.string in
      let store = create_store () in
      {col_text = col_text;  list_store = store }
     
    (* Tree view cell renderers and columns. *)
    let get_view data =
        let cell_text = GTree.cell_renderer_text [`XPAD 5] in
      let vcol = GTree.view_column () in
      vcol#pack cell_text;
      vcol#add_attribute cell_text "markup" data.col_text;
      vcol
     
    let get_area data vcol =
        let scroll = GBin.scrolled_window ~width:250 ~height:150 ~shadow_type:`ETCHED_IN ~hpolicy:`AUTOMATIC
          ~vpolicy:`AUTOMATIC ~show:false () in
         let view = GTree.view 
        ~model:data.list_store
        ~headers_visible:false
        ~rules_hint:true 
        ~packing:scroll#add () in
         let _ = view#append_column vcol in
         let _ = view#set_hover_selection true in
      { frame = scroll#coerce; scroll = scroll; tree_view = view }
     
     
    (* Main function. *)
    let add edit (source : GSourceView2.source_view) =
      let data = get_data () in
      let vcol = get_view data in
      let area = get_area data vcol in
      source#add_child_in_window ~child:area.frame ~which_window:`TEXT ~x:0 ~y:0;
      let buffer = source#source_buffer in
      let t = { data = data; vcol = vcol; area = area; source = source; buffer = buffer } in
     (* let _ = (tree_view t)#connect#row_activated ~callback:
          (on_row_activated t (tree_view t)) in*)
      let _ = buffer#connect#changed (fun () -> check_input t) in
      let _ = (tree_view t)#event#connect#button_release (finalize t) in
      let connect = source#event#connect in
      let _ = connect#key_press (select_action t) in
      let _ = connect#button_press (Popup.hide t) in
      let _ =connect#scroll (Popup.hide t) in
        t
     
    let mainWindow = GWindow.window
      ~width:800
      ~height:600
      ~position:`CENTER
      ~resizable:true
      ~title:"Aurora" ()
     
    let source_view = GSourceView2.source_view
        ~packing:mainWindow#add ()
     
    let  _ =
          GMain.init (); 
          mainWindow#show ();
          add false source_view;
          GMain.main ()
    Merci de l'attention portée a mon problème

  6. #6
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    De mon côté, j'ai réussi à faire marcher ton code avec quelques changements. D'abord, tu peux garder open StdLabels mais il faut supprimer toutes les autres et rajouter les noms complets là où c'est nécessaire. En pratique je crois qu'il n'y a que Gobject.Data.string à modifier. Ensuite, change ceci (en rouge ce qui est important) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let finalize t _ =
      let row = get_selected_iter t in
      let stop = (buffer t)#get_iter `INSERT in
      let start = stop#backward_word_start#backward_char in
      (buffer t)#delete ~start ~stop;
      replace := (list_store t)#get ~row ~column:name; 
      (* c'est sur la ligne précédente que j'ai un problème *)
      (buffer t)#insert (" "^(!replace));
      Popup.hide t ()
    Au cas où j'aurai oublié des trucs modifiés machinalement, voici le code complet dont le fonctionnement me semble satisfaisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
     
     
     
     
    open StdLabels
     
    (*let abrLex = new Arbre_lexical.abrLex *)
     
    let toplevel = ref [""]
     
    type data = {
      col_text : string GTree.column;     
      list_store : GTree.list_store;               (* List store.          *)
    }
     
    type area = {
      frame : GObj.widget;                    (* Popup frame.         *)
      scroll : GBin.scrolled_window;
      tree_view : GTree.view;
    }
     
    type t = { 
      data : data;
      area : area;
      vcol : GTree.view_column;
      source : GSourceView2.source_view;
      buffer : GSourceView2.source_buffer
    }
     
    (* Some getters to hide the implementation in the code below. *)
     
    let col_text t = t.data.col_text
    let source t = t.source
    let buffer t = t.buffer
    let frame t = t.area.frame
    let scroll t = t.area.scroll
    let tree_view t = t.area.tree_view
    let list_store t = t.data.list_store
    let view_col t = t.vcol
     
    module Popup =
      struct
        (* Show popup *)
        let show =
          fun t (x, y) ->
            let child = frame t in
            (source t)#move_child ~child ~x ~y;
            child#misc#show ()
        (* Hide popup and clear contents.*) 
        let hide t _ =
            (frame t)#misc#hide (); 
          false
      end
     
    let cols = new GTree.column_list
    let name = cols#add Gobject.Data.string
     
    let create_store () =
        let list_store = GTree.list_store cols in 
        List.iter !toplevel ~f:
        begin fun n ->
          let row = list_store#append () in
          list_store#set ~row ~column:name n;
       end;
      list_store
     
    let failure n fmt =
      Printf.ksprintf (fun msg ->
        Printf.eprintf "%s.\n%!" msg;
        exit n
      ) ("(Aurora) Error: " ^^ fmt)
     
    (* Get selected iter. *)
    let get_selected_iter t =
      match (tree_view t)#selection#get_selected_rows with
      | path :: _ -> (list_store t)#get_iter path
      | [] -> 
        match (list_store t)#get_iter_first with
        | Some iter -> iter
        | _ -> failure 8 "empty"
     
     
     
    let add_columns ~(view : GTree.view) =
      let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
      let vc =
        GTree.view_column ~renderer:(renderer, ["text", name]) ()
      in
      view#append_column vc
     
    (* Try to determine the best popup coordinates. *)
    let best_coord t =
      let r1 = (source t)#get_iter_location ((buffer t)#get_iter `INSERT)
      and r2 = (source t)#visible_rect in
      if Gdk.Rectangle.width r2 > 300 && Gdk.Rectangle.height r2 > 100 then (
        let x = Gdk.Rectangle.x r1 - Gdk.Rectangle.x r2 
        and y = Gdk.Rectangle.y r1 - Gdk.Rectangle.y r2 + 14 in
        Some ((x - if x + 280 >= Gdk.Rectangle.width  r2 then 280 else 0),
        (y - if y + 100 >= Gdk.Rectangle.height r2 then 114 else 0))
      ) else None
     
    (* show popup. *)
    let word = ref ""
    let replace = ref ""
     
     
    let check_input t= 
       let stop = (buffer t)#get_iter `INSERT in
        if stop#ends_word 
        then 
         (
          let start = stop#backward_word_start#backward_char in
          word := (buffer t)#get_text ~start ~stop ();
          (
           if((String.get !word 0) = ' ') 
           then word := String.sub !word 1 ((String.length !word)-1)
          );
          if((List.length !toplevel) <> 0) 
          then(Gaux.may (Popup.show t) (best_coord t))
         ) 
        else if (frame t)#misc#visible then ignore (Popup.hide t ())
     
    (* hide popup. *)
     
    let finalize t _ =
      let row = get_selected_iter t in
      let stop = (buffer t)#get_iter `INSERT in
      let start = stop#backward_word_start#backward_char in
      (buffer t)#delete ~start ~stop;
      replace := (list_store t)#get ~row ~column:name; 
      (* c'est sur la ligne précédente que j'ai un problème *)
      (buffer t)#insert (" "^(!replace));
      Popup.hide t ()
     
     
    let add_word word t=
          let row = (list_store t)#append () in
          (list_store t)#set ~row ~column:name word
     
    let addArbreLex t =
        (list_store t)#clear ();
        toplevel := ["test";"toto";"why this fucking row is unreachable ?"];
        List.iter (fun e -> add_word e t) !toplevel
     
    (*let on_row_activated t (view:GTree.view) path column =
      let model = view#model in
      let row = model#get_iter path in
      replace := model#get ~row ~column:name;
      print_endline !replace;
      let _ = (finalize t ()) in ()  
    *)
     
    (* Choose action when a key is pressed. *)
    let select_action t ev =
        addArbreLex t;
        if ((List.length !toplevel <> 0) && (frame t)#misc#visible) then (
        let here = (list_store t)#get_path (get_selected_iter t) in
        match GdkEvent.Key.keyval ev with
          | 0xFF52 (* Up arrow *) -> let _ = GTree.Path.prev here in
          let _ = (tree_view t)#set_cursor here (view_col t) in true
          | 0xFF54 (* Down arrow *) ->let _ = GTree.Path.next here in
          let _ = (tree_view t)#set_cursor here (view_col t) in 
          let _ = GTree.Path.next here in true
          | 0xFF0D | 0xFF8D (* Entry *) -> not (finalize t ())
          | 0xFF1B | 0xFF08 | 0xFF9A | 0xFF9B | 0xFF95
          | 0xFF96 | 0xFF98 | 0xFF51 | 0xFF53 -> Popup.hide t ()
          | _ -> false
      ) else false
     
      (* Tree view data. *)
    let get_data () =
      let cols = new GTree.column_list in
      let col_text = cols#add Gobject.Data.string in
      let store = create_store () in
      {col_text = col_text;  list_store = store }
     
    (* Tree view cell renderers and columns. *)
    let get_view data =
        let cell_text = GTree.cell_renderer_text [`XPAD 5] in
      let vcol = GTree.view_column () in
      vcol#pack cell_text;
      vcol#add_attribute cell_text "markup" data.col_text;
      vcol
     
    let get_area data vcol =
        let scroll = GBin.scrolled_window 
          ~width:250 ~height:150 
           ~shadow_type:`ETCHED_IN ~hpolicy:`AUTOMATIC
          ~vpolicy:`AUTOMATIC ~show:false () in
         let view = GTree.view 
          ~model:data.list_store
          ~headers_visible:false
          ~rules_hint:true 
          ~packing:scroll#add () in
         let _ = view#append_column vcol in
         let _ = view#set_hover_selection true in
        { frame = scroll#coerce; scroll = scroll; tree_view = view }
     
     
    (* Main function. *)
    let add edit (source : GSourceView2.source_view) =
      let data = get_data () in
      let vcol = get_view data in
      let area = get_area data vcol in
      source#add_child_in_window ~child:area.frame ~which_window:`TEXT ~x:0 ~y:0;
      let buffer = source#source_buffer in
      let t = { data = data; vcol = vcol; area = area; source = source; buffer = buffer } in
     (* let _ = (tree_view t)#connect#row_activated ~callback:
          (on_row_activated t (tree_view t)) in*)
      let _ = buffer#connect#changed (fun () -> check_input t) in
      let _ = (tree_view t)#event#connect#button_release (finalize t) in
      let connect = source#event#connect in
      let _ = connect#key_press (select_action t) in
      let _ = connect#button_press (Popup.hide t) in
      let _ =connect#scroll (Popup.hide t) in
        t
     
    let mainWindow = 
      let wnd = GWindow.window
        ~width:800 ~height:600
        ~position:`CENTER
        ~title:"Aurora" () in
      wnd#connect#destroy GMain.quit;
      wnd
     
    let source_view = GSourceView2.source_view
        ~packing:mainWindow#add ()
     
    let  _ =
          GMain.init (); 
          mainWindow#show ();
          add false source_view;
          GMain.main ()
    Un détail, j'ai également ajouté un appel à GMain.quit lorsque la fenêtre est détruite : bonne pratique pour fermer l'application !

    De façon générale, se méfier comme de la peste de la pollution de l'espace de noms par les commandes open. Depuis OCaml 3.12 on peut utiliser la syntaxe let open Foo in sans passer par camlp4, ou bien Foo.(bar barbar foobar) au lieu de Foo.bar Foo.barbar Foo.foobar. C'est pratique et surtout l'ouverture du module est locale.

    Ensuite, je ne sais pas ce que tu veux mettre dans ton autocomplétion, mais pour gérer les préfixes tu peux utiliser un trie ou "arbre des préfixes", une structure adaptée à ce problème. J'ai écrit un article sur le sujet sur dvp (cf ma signature "Implémentation d'un lexique avec OCaml") qui, peut-être, pourra t'être utile.

    Cordialement,
    Cacophrène

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Ah oaui effectivement je ne pensais pas que les open me feraient chier à ce point la.

    Pour ce qui est de mon autocomplétion, elle est gérée via un arbre léxical codé dans un autre fichier, celui ci est parfaitement fonctionnel, mais pour éviter de compliquer trop le code et ne pas vous abimer les yeux j'ai préférer créer une liste a la main avec 3 mots dedans

    J'arrive a compiler ce que tu m'as corrigé, et mieux tu as réussi a me faire comprendre mon erreur .
    Seulement le problème est que je ne peux pas parcourir ma liste de suggestion, car en effet, lorsque je créer la liste avec les 3 mots dedans

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    let addArbreLex t =
        (list_store t)#clear ();
        toplevel := ["test";"toto";"why this fucking row is unreachable ?"];
        List.iter (fun e -> add_word e t) !toplevel
    je ne peux accéder uniquement au deux premiers éléments via les fleches directionnelles
    et encore plus étrange, que je sois sur le premier ou le 2ème élément, si je selectionne en appuyant sur la touche entrée, c'est le premier élément qui est choisi pour l'autocomplétion, alors que la selection avec la souris marche niquelle...

    J'aimerais avoir un petit éclaircissement là dessus si possible, et bien entendu si quelqu'un arrive a comprendre pourquoi :s

  8. #8
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    Après un temps d'attente assez long, voici un bout de code qui peut te servir pour obtenir ce que tu veux.

    Compiler avec : ocamlopt -w s -I +lablgtk2 lablgtk.cmxa lablgtksourceview2.cmxa test.ml -o test

    Le principe : On définit une signature AUTOCOMPLETION_PARAMS qui définit le widget auquel on doit ajouter l'autocomplétion, et la fonction qui, étant donné un préfixe, détermine la liste des mots possibles. On crée ensuite un foncteur Make qui ajoute la fonctionnalité au widget en question... en l'état, ce code est donc assez général et utilisable clef en mains, ou presque... il reste quelques soucis que je te laisse chercher de ton côté. On en discute si tu rencontres des difficultés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    (* test.ml *)
     
    module type AUTOCOMPLETION_PARAMS =
     sig
      val view : GText.view
      val find : string -> string list
     end
     
    module Make (P : AUTOCOMPLETION_PARAMS) =
     struct
      let frame = 
        let frame = GBin.frame 
          ~shadow_type:`ETCHED_IN 
          ~width:250 ~height:80 
          ~show:false () in
        P.view#add_child_in_window 
          ~child:frame#coerce
          ~which_window:`WIDGET
          ~x:0 ~y:0;
        frame
      let cols = new GTree.column_list
      let choices = cols#add Gobject.Data.string
      let store = GTree.list_store cols
      let cell = GTree.cell_renderer_text []
      let vcol = GTree.view_column ~renderer:(cell, ["text", choices]) ()
      let view =
        let scroll = GBin.scrolled_window
          ~hpolicy:`ALWAYS ~vpolicy:`ALWAYS 
          ~border_width:2 
          ~packing:frame#add () in
        let view = GTree.view
          ~model:store 
          ~headers_visible:false
          ~rules_hint:true 
          ~packing:scroll#add () in
        view#append_column vcol;
        view#set_hover_selection true;
        view
     
      let hide_popup () =
        store#clear ();
        frame#misc#hide ()
     
      let insert =
        let insert _ =
          match view#selection#get_selected_rows with
          | [p] -> let row = store#get_iter p in 
            let word = store#get ~row ~column:choices in
            let stop = P.view#buffer#get_iter `INSERT in
            let start = stop#backward_word_start#backward_char in
            P.view#buffer#delete ~start ~stop;
            P.view#buffer#insert word;
            hide_popup (); true
          |  _  -> false
        in ignore (view#event#connect#button_press insert);
        insert
     
      let prefix () =
        let stop = P.view#buffer#get_iter `INSERT in
        let start = stop#backward_word_start#backward_char in
        P.view#buffer#get_text ~start ~stop ()
     
      let show_popup () =
        let here = P.view#get_iter_location (P.view#buffer#get_iter `INSERT) in
        let x = Gdk.Rectangle.x here + 25 and y = Gdk.Rectangle.y here + 12 in
        P.view#move_child ~child:frame#coerce ~x ~y;
        match P.find (prefix ()) with
        | [] -> hide_popup ()
        | t -> store#clear ();
          List.iter (fun word ->
            let row = store#append () in
            store#set ~row ~column:choices word; ()
          ) t;
          Gaux.may view#selection#select_iter store#get_iter_first;
        if not frame#misc#visible then frame#misc#show ()
     
      let move dir =
        match view#selection#get_selected_rows with
        | [ ] -> Gaux.may view#selection#select_iter store#get_iter_first
        | [p] -> GTree.Path.(if dir then ignore (prev p) else next p);
          view#selection#select_path p;
          view#scroll_to_cell p vcol;
        |  _  -> assert false 
     
      let check t =
        let k = GdkEvent.Key.keyval t in
        match k with
        | 65362 -> move true; true
        | 65364 -> move false; true
        | 65293 -> false
        | 65307 | 65361 | 65363 -> hide_popup (); false
        | _ -> show_popup (); false
     
      let _ = P.view#event#connect#key_press check
     end
     
    let window =
      GMain.init ();
      let window = GWindow.window
        ~width:640 ~height:480
        ~border_width:5
        ~resizable:false
        ~title:"Autocompletion demo"
        ~position:`CENTER () in
      window#connect#destroy GMain.quit;
      window
     
    let source =
      let scroll = GBin.scrolled_window
        ~hpolicy:`ALWAYS ~vpolicy:`ALWAYS
        ~shadow_type:`ETCHED_IN
        ~packing:window#add () in
      let source = GSourceView2.source_view
        ~show_line_numbers:true
        ~draw_spaces:[`SPACE; `NEWLINE]
        ~highlight_current_line:true
        ~insert_spaces_instead_of_tabs:true 
        ~packing:scroll#add () in
      source#misc#modify_font_by_name "Monospace 10";
      source
     
    module AutoComplete = Make (
     struct
      let view = (source :> GText.view)
      let words = ["avion"; "aviation"; "aviateur"; "aviaire"; "avance"]
      let find s =
        let n = String.length s in
        List.filter (fun w -> String.length w >= n && String.sub w 0 n = s) words
     end )
     
    let _ =
      window#show ();
      GMain.main ()
    Cordialement,
    Cacophrène

Discussions similaires

  1. Popup confirm personnalisé
    Par dev_web_junior dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 23/11/2013, 17h59
  2. [PowerShell] afficher popup personnalisé prochain demarrage
    Par T3rm1nat0r dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 08/04/2013, 09h58
  3. Popup personnalisé sur image
    Par soufian1364 dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 03/08/2010, 22h14
  4. Mettre un popup menu invisible ??
    Par Alberto dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/12/2002, 09h02
  5. Image popup d'une fiche à partir d'un TListImage
    Par FW-S dans le forum Composants VCL
    Réponses: 3
    Dernier message: 17/11/2002, 13h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo