View Issue Details

IDProjectCategoryView StatusLast Update
0037225LazarusWidgetsetpublic2020-06-26 23:57
ReporterCudaText man Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionreopened 
Product Version2.1 (SVN) 
Summary0037225: gtk3: AskUser() not implemented
DescriptionDemo shows some crap (tooltip??) but it must show msg-box.
TagsNo tags attached.
Fixed in Revisionr63424, r63441
LazTarget-
WidgetsetGTK 3
Attached Files

Activities

CudaText man

2020-06-18 17:08

reporter  

tst-askuser.zip (2,695 bytes)

CudaText man

2020-06-18 17:09

reporter   ~0123469

Anton Kavalenka

2020-06-19 08:03

reporter   ~0123471

I like one-line solutions
askuser.diff (621 bytes)   
Index: lcl/interfaces/gtk3/gtk3lclintf.inc
===================================================================
--- lcl/interfaces/gtk3/gtk3lclintf.inc	(revision 63387)
+++ lcl/interfaces/gtk3/gtk3lclintf.inc	(working copy)
@@ -1219,7 +1219,9 @@
             idButtonNoToAll  : CreateButton(Caption, GTK_RESPONSE_LCL_NOTOALL, BtnID);
             idButtonYesToAll : CreateButton(Caption, GTK_RESPONSE_LCL_YESTOALL, BtnID);
           end;
-        end;
+        end else
+           CreateButton(Caption, ModalResult);
+
     end;
   end;
   MainList := gtk_container_get_children(PGtkContainer(Dialog^.get_action_area));
askuser.diff (621 bytes)   

Anton Kavalenka

2020-06-19 09:25

reporter   ~0123473

Sorry, 1st trick is incomplete. Updated patch.
askuser-2.diff (5,819 bytes)   
Index: lcl/interfaces/gtk3/gtk3lclintf.inc
===================================================================
--- lcl/interfaces/gtk3/gtk3lclintf.inc	(revision 63387)
+++ lcl/interfaces/gtk3/gtk3lclintf.inc	(working copy)
@@ -1093,7 +1093,7 @@
   GtkDialogType: TGtkMessageType;
   Btns: TGtkButtonsType;
   BtnIdx: Integer;
-  DefaultID: Integer;
+  DefaultNdx: Integer;
   X: Integer;
   MainList,ChildList: PGList;
   Title: String;
@@ -1100,6 +1100,7 @@
   //ActiveWindow: HWND;
   BtnResult: LongInt;
   n: Integer;
+  dbtn:TDialogButton;
 
   procedure CreateButton(const ALabel : String; const AResponse: Integer;
       const AImageHint: Integer = -1);
@@ -1115,6 +1116,8 @@
     NewButton := gtk_dialog_add_button(Dialog,
       PgChar({Ampersands2Underscore}(ALabel)), AResponse);
     gtk_button_set_use_underline(PGtkButton(NewButton), True);
+    g_object_set_data(PGObject(NewButton), 'modal_result',
+          {%H-}Pointer(PtrInt(AResponse)));
     (*
     if AImageHint >= 0 then
     begin
@@ -1175,11 +1178,11 @@
   end;
 
   Btns := GTK_BUTTONS_NONE;
-  DefaultId := 0;
+  DefaultNdx := 0;
   for X := 0 to Buttons.Count - 1 do
   begin
     if Buttons[X].Default then
-      DefaultID := X;
+      DefaultNdx := X;
 
     if (ADialogResult = mrNone) and
       (Buttons[X].ModalResult in [mrCancel, mrAbort, mrIgnore,
@@ -1201,25 +1204,27 @@
     // gtk2 have reverted buttons eg. No, Yes
     for BtnIdx := Buttons.Count - 1 downto 0 do
     begin
-      with Buttons[BtnIdx] do
-        if (ModalResult >= Low(ButtonResults)) and (ModalResult <= High(ButtonResults)) then
-        begin
-          BtnID := ButtonResults[ModalResult];
-          case BtnID of
-            idButtonOK       : CreateButton(Caption, GTK_RESPONSE_OK, BtnID);
-            idButtonCancel   : CreateButton(Caption, GTK_RESPONSE_CANCEL, BtnID);
-            idButtonHelp     : CreateButton(Caption, GTK_RESPONSE_HELP, BtnID);
-            idButtonYes      : CreateButton(Caption, GTK_RESPONSE_YES, BtnID);
-            idButtonNo       : CreateButton(Caption, GTK_RESPONSE_NO, BtnID);
-            idButtonClose    : CreateButton(Caption, GTK_RESPONSE_CLOSE, BtnID);
-            idButtonAbort    : CreateButton(Caption, GTK_RESPONSE_REJECT, BtnID);
-            idButtonRetry    : CreateButton(Caption, GTK_RESPONSE_LCL_RETRY, BtnID);
-            idButtonIgnore   : CreateButton(Caption, GTK_RESPONSE_LCL_IGNORE, BtnID);
-            idButtonAll      : CreateButton(Caption, GTK_RESPONSE_LCL_ALL, BtnID);
-            idButtonNoToAll  : CreateButton(Caption, GTK_RESPONSE_LCL_NOTOALL, BtnID);
-            idButtonYesToAll : CreateButton(Caption, GTK_RESPONSE_LCL_YESTOALL, BtnID);
-          end;
+      dbtn:=Buttons[BtnIdx];
+      if (dbtn.ModalResult >= Low(ButtonResults)) and (dbtn.ModalResult <= High(ButtonResults)) then
+      begin
+        BtnID := ButtonResults[dbtn.ModalResult];
+        case BtnID of
+          idButtonOK       : CreateButton(dbtn.Caption, GTK_RESPONSE_OK, BtnID);
+          idButtonCancel   : CreateButton(dbtn.Caption, GTK_RESPONSE_CANCEL, BtnID);
+          idButtonHelp     : CreateButton(dbtn.Caption, GTK_RESPONSE_HELP, BtnID);
+          idButtonYes      : CreateButton(dbtn.Caption, GTK_RESPONSE_YES, BtnID);
+          idButtonNo       : CreateButton(dbtn.Caption, GTK_RESPONSE_NO, BtnID);
+          idButtonClose    : CreateButton(dbtn.Caption, GTK_RESPONSE_CLOSE, BtnID);
+          idButtonAbort    : CreateButton(dbtn.Caption, GTK_RESPONSE_REJECT, BtnID);
+          idButtonRetry    : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_RETRY, BtnID);
+          idButtonIgnore   : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_IGNORE, BtnID);
+          idButtonAll      : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_ALL, BtnID);
+          idButtonNoToAll  : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_NOTOALL, BtnID);
+          idButtonYesToAll : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_YESTOALL, BtnID);
         end;
+      end else
+         CreateButton(dbtn.Caption, dbtn.ModalResult, 0);
+
     end;
   end;
   MainList := gtk_container_get_children(PGtkContainer(Dialog^.get_action_area));
@@ -1231,38 +1236,35 @@
     if (ChildList^.Data <> nil) then
     begin
       if g_type_check_instance_is_a(ChildList^.Data, gtk_button_get_type) then
-      // if GTK_IS_BUTTON(ChildList^.Data) then
       begin
         Btn := PGtkButton(ChildList^.Data);
 
         BtnID := -1;
-        BtnResult:=Buttons[BtnIdx].ModalResult;
+        dbtn:=Buttons[BtnIdx];
+        BtnResult:=dbtn.ModalResult;
         if (BtnResult>=Low(ButtonResults)) and (BtnResult<=High(ButtonResults)) then
-          BtnID := ButtonResults[Buttons[BtnIdx].ModalResult];
+          BtnID := ButtonResults[dbtn.ModalResult]
+        else
+          BtnID := dbtn.ModalResult;
+
         if BtnID = idButtonCancel then
           g_object_set_data(PGObject(Dialog), 'modal_result', Pointer(idButtonCancel));
 
-        X := Buttons[BtnIdx].ModalResult;
-        g_object_set_data(PGObject(Btn), 'modal_result',
-          {%H-}Pointer(PtrInt(X)));
-
         g_signal_connect_data(Btn, 'clicked',
           TGCallback(@PromptUserButtonClicked), @ADialogResult, nil, 0);
 
-        if DefaultID = BtnIdx then
+        if DefaultNdx = BtnIdx then
         begin
           gtk_dialog_set_default_response(Dialog, ResponseID(BtnID));
-          X := Buttons[BtnIdx].ModalResult;
           g_object_set_data(PGObject(Dialog), 'modal_result',
-            {%H-}Pointer(PtrInt(X)));
+            {%H-}Pointer(PtrInt(BtnID)));
         end;
 
         inc(BtnIdx);
       end;
     end;
-    // ChildList := g_list_next(ChildList);
     inc(n);
-    ChildList := g_list_nth(ChildList, n);
+    ChildList := g_list_nth(MainList, n);
   end;
   if MainList <> nil then
     g_list_free(MainList);
askuser-2.diff (5,819 bytes)   

Juha Manninen

2020-06-23 13:25

developer   ~0123528

Applied, thanks.

CudaText man

2020-06-24 01:08

reporter   ~0123540

Can you please support defaultButton in gtk3? Now if I press Enter after dlg shown, I get result of last button (max index).
Can you please make it normal dialog, not "tooltip style"?

Anton Kavalenka

2020-06-24 16:35

reporter   ~0123575

Default button fixed.
The dialog look is what GTK3 function creates:
Dialog := gtk_message_dialog_new(nil, GTK_DIALOG_MODAL, GtkDialogType, Btns, nil , []);

How it looks is mostly defined by your current theme.
gtk3lclintf.diff (2,029 bytes)   
Index: lcl/interfaces/gtk3/gtk3lclintf.inc
===================================================================
--- lcl/interfaces/gtk3/gtk3lclintf.inc	(revision 63438)
+++ lcl/interfaces/gtk3/gtk3lclintf.inc	(working copy)
@@ -1086,7 +1086,7 @@
     idButtonYesToAll);
 
 var
-  Btn: PGtkButton;
+  Btn,btn_def: PGtkButton;
   BtnId: Longint;
   Dialog: PGtkMessageDialog;
   ADialogResult: Integer;
@@ -1162,6 +1162,8 @@
       idButtonAll      : Result := GTK_RESPONSE_LCL_ALL;
       idButtonNoToAll  : Result := GTK_RESPONSE_LCL_NOTOALL;
       idButtonYesToAll : Result := GTK_RESPONSE_LCL_YESTOALL;
+    else
+      Result:=AnID;
     end;
   end;
 begin
@@ -1228,10 +1230,10 @@
     end;
   end;
   MainList := gtk_container_get_children(PGtkContainer(Dialog^.get_action_area));
-  ChildList := MainList;
-  BtnIdx := 0;
-  n := 0;
-  while ChildList <> nil do
+  ChildList:=g_list_last(MainList);
+  BtnIdx:=0;
+  btn_def:=nil;
+  while Assigned(ChildList) do
   begin
     if (ChildList^.Data <> nil) then
     begin
@@ -1238,7 +1240,7 @@
       if g_type_check_instance_is_a(ChildList^.Data, gtk_button_get_type) then
       begin
         Btn := PGtkButton(ChildList^.Data);
-
+       // writeln('btn[',BtnIdx,'] ',Btn^.get_label);
         BtnID := -1;
         dbtn:=Buttons[BtnIdx];
         BtnResult:=dbtn.ModalResult;
@@ -1256,6 +1258,11 @@
         if DefaultNdx = BtnIdx then
         begin
           gtk_dialog_set_default_response(Dialog, ResponseID(BtnID));
+          btn_def:=btn;
+          gtk_widget_grab_default(btn);
+          gtk_widget_grab_focus(btn);
+          gtk_widget_set_can_default(btn_def,TRUE);
+          gtk_window_set_default(dialog, btn_def);
           g_object_set_data(PGObject(Dialog), 'modal_result',
             {%H-}Pointer(PtrInt(BtnID)));
         end;
@@ -1263,8 +1270,7 @@
         inc(BtnIdx);
       end;
     end;
-    inc(n);
-    ChildList := g_list_nth(MainList, n);
+    ChildList:=ChildList^.prev;
   end;
   if MainList <> nil then
     g_list_free(MainList);
gtk3lclintf.diff (2,029 bytes)   

CudaText man

2020-06-26 18:09

reporter   ~0123603

Anton, please help
https://bugs.freepascal.org/view.php?id=37269

Juha Manninen

2020-06-26 23:57

developer   ~0123606

I applied the last patch. Thanks.

Issue History

Date Modified Username Field Change
2020-06-18 17:08 CudaText man New Issue
2020-06-18 17:08 CudaText man File Added: tst-askuser.zip
2020-06-18 17:09 CudaText man Note Added: 0123469
2020-06-18 17:09 CudaText man File Added: Screenshot from 2020-06-18 18-07-15.png
2020-06-19 08:03 Anton Kavalenka Note Added: 0123471
2020-06-19 08:03 Anton Kavalenka File Added: askuser.diff
2020-06-19 08:03 Anton Kavalenka File Added: Здымак экрана, 2020-06-19 09-00-36.png
2020-06-19 09:25 Anton Kavalenka Note Added: 0123473
2020-06-19 09:25 Anton Kavalenka File Added: askuser-2.diff
2020-06-23 13:24 Juha Manninen Assigned To => Juha Manninen
2020-06-23 13:24 Juha Manninen Status new => assigned
2020-06-23 13:25 Juha Manninen Status assigned => resolved
2020-06-23 13:25 Juha Manninen Resolution open => fixed
2020-06-23 13:25 Juha Manninen Fixed in Revision => r63424
2020-06-23 13:25 Juha Manninen LazTarget => -
2020-06-23 13:25 Juha Manninen Widgetset GTK 3 => GTK 3
2020-06-23 13:25 Juha Manninen Note Added: 0123528
2020-06-24 01:08 CudaText man Status resolved => assigned
2020-06-24 01:08 CudaText man Resolution fixed => reopened
2020-06-24 01:08 CudaText man Note Added: 0123540
2020-06-24 16:35 Anton Kavalenka Note Added: 0123575
2020-06-24 16:35 Anton Kavalenka File Added: gtk3lclintf.diff
2020-06-26 18:09 CudaText man Note Added: 0123603
2020-06-26 23:57 Juha Manninen Status assigned => resolved
2020-06-26 23:57 Juha Manninen Fixed in Revision r63424 => r63424, r63441
2020-06-26 23:57 Juha Manninen Widgetset GTK 3 => GTK 3
2020-06-26 23:57 Juha Manninen Note Added: 0123606