mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 03:21:28 +01:00 
			
		
		
		
	Finishes the basic implementation of Android native menus
git-svn-id: trunk@36394 -
This commit is contained in:
		
							parent
							
								
									f3e22dc96a
								
							
						
					
					
						commit
						c1eb17e8e9
					
				| @ -160,8 +160,18 @@ public class LCLActivity extends Activity implements SensorEventListener, Locati | ||||
|       else | ||||
|       { | ||||
|         //Log.v("lclproject", "BackKey not going to home"); | ||||
|         return true; | ||||
|       } | ||||
| 
 | ||||
|       // Handling of the Menu hardware key | ||||
|       if (keyCode == KeyEvent.KEYCODE_MENU) | ||||
|       { | ||||
|         flagIsMenuOpen = false; // hard-coding now has a good result, we might change in the future if we ever start getting key events even while the menu is open | ||||
|         if (flagIsMenuOpen) closeOptionsMenu(); | ||||
|         else openOptionsMenu(); | ||||
|         flagIsMenuOpen = !flagIsMenuOpen; | ||||
|       } | ||||
| 
 | ||||
|       return true; | ||||
|     } | ||||
| 
 | ||||
|     @Override public boolean onTouchEvent (MotionEvent event) | ||||
| @ -248,14 +258,22 @@ public class LCLActivity extends Activity implements SensorEventListener, Locati | ||||
|     //Log.i("lclapp", "onConfigurationChanged finished"); | ||||
|   } | ||||
| 
 | ||||
|   @Override public boolean onCreateOptionsMenu(Menu menu) | ||||
|   { | ||||
|     Log.i("lclapp", "onCreateOptionsMenu"); | ||||
|     return super.onCreateOptionsMenu(menu); | ||||
|   } | ||||
| 
 | ||||
|   @Override public boolean onPrepareOptionsMenu (Menu menu) | ||||
|   { | ||||
|     Log.i("lclapp", "onPrepareOptionsMenu"); | ||||
| 
 | ||||
|     super.onPrepareOptionsMenu(menu); | ||||
| 
 | ||||
|     int i; | ||||
| 
 | ||||
|     // First clear the captions list | ||||
|     for (i = 0; i<6; i++) | ||||
|     for (i = 0; i < lclmenu_captions.length; i++) | ||||
|       lclmenu_captions[i] = ""; | ||||
| 
 | ||||
|     // Now ask the LCL to fill it | ||||
| @ -263,15 +281,17 @@ public class LCLActivity extends Activity implements SensorEventListener, Locati | ||||
| 
 | ||||
|     // And fill the menus with it | ||||
|     menu.clear(); | ||||
|     for (i = 0; i<6; i++) | ||||
|     for (i = 0; i< lclmenu_captions.length; i++) | ||||
|     { | ||||
|       if (lclmenu_captions[i] != "") | ||||
|       { | ||||
|         Log.i("lclapp", "onPrepareOptionsMenu item=" + lclmenu_captions[i]); | ||||
|         MenuItem lMenuItem = menu.add(0, i, 0, lclmenu_captions[i]); | ||||
|         lMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() | ||||
|         { | ||||
|           public boolean onMenuItemClick(MenuItem item) | ||||
|           { | ||||
|             flagIsMenuOpen = false; | ||||
|             LCLOnMenuAction(1, item.getItemId()); | ||||
|             return true; | ||||
|           } | ||||
| @ -666,6 +686,7 @@ public class LCLActivity extends Activity implements SensorEventListener, Locati | ||||
|   public int lclkind; | ||||
|   // for the menus | ||||
|   public String[] lclmenu_captions = new String[6]; | ||||
|   public boolean flagIsMenuOpen = false; | ||||
| 
 | ||||
|   static | ||||
|   { | ||||
|  | ||||
| @ -4,8 +4,9 @@ object Form1: TForm1 | ||||
|   Top = 137 | ||||
|   Width = 220 | ||||
|   Caption = 'Form1' | ||||
|   ClientHeight = 257 | ||||
|   ClientHeight = 230 | ||||
|   ClientWidth = 220 | ||||
|   Menu = MainMenu1 | ||||
|   OnClick = FormClick | ||||
|   OnCreate = FormCreate | ||||
|   OnKeyDown = Button1KeyDown | ||||
| @ -101,4 +102,12 @@ object Form1: TForm1 | ||||
|     TabOrder = 7 | ||||
|     Text = 'ComboBox1' | ||||
|   end | ||||
|   object MainMenu1: TMainMenu | ||||
|     left = 23 | ||||
|     top = 60 | ||||
|     object MenuItem1: TMenuItem | ||||
|       Caption = 'New Item1' | ||||
|       OnClick = MenuItem1Click | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -22,6 +22,8 @@ type | ||||
|     CheckBox1: TCheckBox; | ||||
|     ComboBox1: TComboBox; | ||||
|     Label1: TLabel; | ||||
|     MainMenu1: TMainMenu; | ||||
|     MenuItem1: TMenuItem; | ||||
|     ProgressBar1: TProgressBar; | ||||
|     TrackBar1: TTrackBar; | ||||
|     procedure Arrow1Click(Sender: TObject); | ||||
| @ -44,6 +46,7 @@ type | ||||
|     procedure FormCreate(Sender: TObject); | ||||
|     procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); | ||||
|     procedure FormPaint(Sender: TObject); | ||||
|     procedure MenuItem1Click(Sender: TObject); | ||||
|   private | ||||
|     { private declarations } | ||||
|   public | ||||
| @ -234,6 +237,11 @@ begin | ||||
|   Canvas.Rectangle(200, 200, 300, 300);} | ||||
| end; | ||||
| 
 | ||||
| procedure TForm1.MenuItem1Click(Sender: TObject); | ||||
| begin | ||||
|   DebugLn('[TForm1.MenuItem1Click]'); | ||||
| end; | ||||
| 
 | ||||
| procedure TForm1.HandleMessageDialogFinished(Sender: TObject; AResult: Integer); | ||||
| begin | ||||
|   DebugLn(Format('[TForm1.HandleMessageDialogFinished] AResult=%d', [AResult])); | ||||
|  | ||||
| @ -131,7 +131,7 @@ begin | ||||
|   //DebugLn('TMenuItem.CreateHandle ',dbgsName(Self),' ',dbgs(Self));
 | ||||
|   //DebugLn('TMenuItem.CreateHandle START ',Name,':',ClassName);
 | ||||
|   if not FVisible then RaiseGDBException(''); | ||||
|   Handle := TWSMenuItemClass(WidgetSetClass).CreateHandle(Self); | ||||
|   FHandle := TWSMenuItemClass(WidgetSetClass).CreateHandle(Self); | ||||
|   CheckChildrenHandles; | ||||
| 
 | ||||
|   if Parent <> nil then | ||||
|  | ||||
| @ -320,7 +320,7 @@ function Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged( | ||||
| function Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged( | ||||
|     env:PJNIEnv; this:jobject; ASensorKind: jint; AValues: JDoubleArray): jint; cdecl; | ||||
| function Java_com_pascal_lclproject_LCLActivity_LCLOnMenuAction( | ||||
|   env:PJNIEnv; this:jobject; kind: jint; itemIndex: jint): jint; cdecl; | ||||
|   env:PJNIEnv; this:jobject; kind, itemIndex: jint): jint; cdecl; | ||||
| function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl; | ||||
| procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); cdecl; | ||||
| 
 | ||||
| @ -332,10 +332,11 @@ var | ||||
| 
 | ||||
|   // Other classes and objects | ||||
|   javaAndroidAppActivityClass: JClass = nil; | ||||
|   javaJavaLandSystemClass: JClass = nil; | ||||
|   javaJavaLangSystemClass: JClass = nil; | ||||
|   javaAndroidOSBuildClass: JClass = nil; | ||||
|   javaAndroidOSVibratorClass: JClass = nil; | ||||
|   javaAndroidContentContextClass: JClass = nil; | ||||
|   javaJavaLangStringClass: JClass = nil; | ||||
| 
 | ||||
|   // Fields of our Activity | ||||
|   // Strings | ||||
|  | ||||
| @ -335,36 +335,79 @@ begin | ||||
| end; | ||||
| 
 | ||||
| function Java_com_pascal_lclproject_LCLActivity_LCLOnMenuAction( | ||||
|   env:PJNIEnv; this:jobject; kind: jint; itemIndex: jint): jint; cdecl; | ||||
|   env:PJNIEnv; this:jobject; kind, itemIndex: jint): jint; cdecl; | ||||
| var | ||||
|   javaField_lclmenu_captions: jfieldid; | ||||
|   javaObject_lclmenu_captions: jobject; | ||||
|   javaObject_lclmenu_captions: jobjectarray; | ||||
|   lJavaString: jstring; | ||||
|   lCurrentForm: TCDNonNativeForm; | ||||
|   lMenu: TMainMenu; | ||||
|   StrPas: string; | ||||
|   Str: PChar; | ||||
|   lMenuItem: TMenuItem; | ||||
|   i, CurIndex: Integer; | ||||
|   i, CurIndex, NumMenuItems: Integer; | ||||
| begin | ||||
|   Result := 0; | ||||
|   //{$ifdef VerboseCDEvents}
 | ||||
|   __android_log_write(ANDROID_LOG_INFO,'lclapp',PChar( | ||||
|     Format('LCLOnMenuAction called kind=%d itemIndex=%d', [kind, itemIndex]))); | ||||
|   DebugLn(Format('LCLOnMenuAction called kind=%d itemIndex=%d', [kind, itemIndex])); | ||||
|   //{$endif}
 | ||||
| 
 | ||||
|   if (javaEnvRef = nil) then Exit; | ||||
| 
 | ||||
|   lCurrentForm := GetCurrentForm(); | ||||
|   if lCurrentForm = nil then Exit; | ||||
|   lMenu := lCurrentForm.LCLForm.Menu; | ||||
|   if lMenu = nil then Exit; | ||||
| 
 | ||||
|   // kind=0 means that we should create the menu items list
 | ||||
|   if kind = 0 then | ||||
|   begin | ||||
|     lCurrentForm := GetCurrentForm(); | ||||
|     if lCurrentForm = nil then Exit; | ||||
|     lMenu := lCurrentForm.LCLForm.Menu; | ||||
|     if lMenu = nil then Exit; | ||||
|     // First calculate the number of menu items
 | ||||
|     NumMenuItems := 0; | ||||
|     for i := 0 to lMenu.Items.Count-1 do | ||||
|     begin | ||||
|       lMenuItem := lMenu.Items[i]; | ||||
|       // Various things might make a menu item invalid and therefore not part of the list
 | ||||
|       if not lMenuItem.Visible then Continue; | ||||
|       if lMenuItem.Caption = '-' then Continue; | ||||
|       Inc(NumMenuItems); | ||||
|     end; | ||||
| 
 | ||||
|     // Now fill the items
 | ||||
|     javaField_lclmenu_captions := javaEnvRef^^.GetFieldID(javaEnvRef, javaActivityClass, 'lclmenu_captions', '[Ljava/lang/String;'); | ||||
|     javaObject_lclmenu_captions := javaEnvRef^^.GetObjectField(javaEnvRef, javaActivityClass, javaField_lclmenu_captions); | ||||
| //    javaObject_lclmenu_captions := javaEnvRef^^.GetObjectField(javaEnvRef, javaActivityClass, javaField_lclmenu_captions);
 | ||||
|     javaObject_lclmenu_captions := javaEnvRef^^.NewObjectArray(javaEnvRef, NumMenuItems, | ||||
|       javaJavaLangStringClass, javaEnvRef^^.NewStringUTF(javaEnvRef, '')); | ||||
| //     DebugLn(Format('LCLOnMenuAction lclmenu_captions field=%x object=%x', [PtrUInt(javaField_lclmenu_captions), PtrUInt(javaObject_lclmenu_captions)]));
 | ||||
| 
 | ||||
|     CurIndex := 0; | ||||
|     StrPas := ''; | ||||
|     for i := 0 to lMenu.Items.Count-1 do | ||||
|     begin | ||||
|       DebugLn(Format('LCLOnMenuAction item=%d', [i])); | ||||
|       lMenuItem := lMenu.Items[i]; | ||||
|       // Various things might make a menu item invalid and therefore not part of the list
 | ||||
|       if not lMenuItem.Visible then Continue; | ||||
|       if lMenuItem.Caption = '-' then Continue; | ||||
| 
 | ||||
|       StrPas := lMenuItem.Caption; | ||||
|       Str := PChar(StrPas); | ||||
|       lJavaString := javaEnvRef^^.NewStringUTF(javaEnvRef, Str); | ||||
|       DebugLn(Format('LCLOnMenuAction lJavaString=%x Str=%s', [PtrUInt(lJavaString), StrPas])); | ||||
|       javaEnvRef^^.SetObjectArrayElement(javaEnvRef, javaObject_lclmenu_captions, CurIndex, lJavaString); | ||||
|       javaEnvRef^^.DeleteLocalRef(javaEnvRef, str); | ||||
| 
 | ||||
|       Inc(CurIndex); | ||||
| 
 | ||||
|       if CurIndex >= NumMenuItems then Break; | ||||
|     end; | ||||
| 
 | ||||
|     javaEnvRef^^.SetObjectField(javaEnvRef, javaActivityObject, javaField_lclmenu_captions, javaObject_lclmenu_captions); | ||||
|   end | ||||
|   // kind=1 means a button click event
 | ||||
|   else | ||||
|   begin | ||||
|     // Searched for the clicked item
 | ||||
|     CurIndex := 0; | ||||
|     for i := 0 to lMenu.Items.Count-1 do | ||||
|     begin | ||||
| @ -373,23 +416,17 @@ begin | ||||
|       if not lMenuItem.Visible then Continue; | ||||
|       if lMenuItem.Caption = '-' then Continue; | ||||
| 
 | ||||
|       Str := PChar(lMenuItem.Caption); | ||||
|       lJavaString :=javaEnvRef^^.NewStringUTF(javaEnvRef, Str); | ||||
|       javaEnvRef^^.SetObjectArrayElement(javaEnvRef, javaObject_lclmenu_captions, CurIndex, lJavaString); | ||||
|       if itemIndex = CurIndex then Break; | ||||
| 
 | ||||
|       Inc(CurIndex); | ||||
| 
 | ||||
|       if CurIndex >= 6 then Break; | ||||
|     end; | ||||
|   end | ||||
|   // kind=1 means a button click event
 | ||||
|   else | ||||
|   begin | ||||
| 
 | ||||
|     lMenuItem.Click(); | ||||
|   end; | ||||
| 
 | ||||
|   // This sends messages like Invalidate requests
 | ||||
|   Result := eventResult; | ||||
|   DebugLn('Fim'); | ||||
| end; | ||||
| 
 | ||||
| const NativeMethods: array[0..8] of JNINativeMethod= | ||||
| @ -451,10 +488,11 @@ begin | ||||
|   end; | ||||
|   // Now other classes
 | ||||
|   javaAndroidAppActivityClass := javaEnvRef^^.FindClass(javaEnvRef,'android/app/Activity'); | ||||
|   javaJavaLandSystemClass := javaEnvRef^^.FindClass(javaEnvRef,'java/lang/System'); | ||||
|   javaJavaLangSystemClass := javaEnvRef^^.FindClass(javaEnvRef,'java/lang/System'); | ||||
|   javaAndroidOSBuildClass := javaEnvRef^^.FindClass(javaEnvRef,'android/os/Build'); | ||||
|   javaAndroidOSVibratorClass := javaEnvRef^^.FindClass(javaEnvRef,'android/os/Vibrator'); | ||||
|   javaAndroidContentContextClass := javaEnvRef^^.FindClass(javaEnvRef,'android/content/Context'); | ||||
|   javaJavaLangStringClass := javaEnvRef^^.FindClass(javaEnvRef,'java/lang/String'); | ||||
| 
 | ||||
|   // Register Pascal exported calls
 | ||||
|   if javaEnvRef^^.RegisterNatives(javaEnvRef, javaActivityClass, @NativeMethods[0],length(NativeMethods))<0 then | ||||
| @ -522,7 +560,7 @@ begin | ||||
|   // Methods from android.app.Activity
 | ||||
|   javaMethod_Activity_finish := javaEnvRef^^.GetMethodID(javaEnvRef, javaAndroidAppActivityClass, 'finish', '()V'); | ||||
|   // Methods from java.lang.System
 | ||||
|   javaMethod_System_exit := javaEnvRef^^.GetStaticMethodID(javaEnvRef, javaJavaLandSystemClass, 'exit', '(I)V'); | ||||
|   javaMethod_System_exit := javaEnvRef^^.GetStaticMethodID(javaEnvRef, javaJavaLangSystemClass, 'exit', '(I)V'); | ||||
|   // Generic methods from Context
 | ||||
|   javaMethod_getSystemService := javaEnvRef^^.GetMethodID(javaEnvRef, javaAndroidContentContextClass, 'getSystemService', '(Ljava/lang/String;)Ljava/lang/Object;'); | ||||
| 
 | ||||
| @ -1038,7 +1076,7 @@ begin | ||||
| 
 | ||||
|   // Call the method
 | ||||
|   lParams[0].i := 0; | ||||
|   javaEnvRef^^.CallStaticVoidMethodA(javaEnvRef, javaJavaLandSystemClass, javaMethod_System_exit, @lParams[0]); | ||||
|   javaEnvRef^^.CallStaticVoidMethodA(javaEnvRef, javaJavaLangSystemClass, javaMethod_System_exit, @lParams[0]); | ||||
| 
 | ||||
|   DebugLn('[TCDWidgetSet.AppTerminate] End'); | ||||
| end; | ||||
|  | ||||
| @ -111,8 +111,8 @@ uses | ||||
| { WinCEWSDialogs,} | ||||
|  CustomDrawnWSExtCtrls, | ||||
|  CustomDrawnWSForms, | ||||
| { WinCEWSImgList, | ||||
|  WinCEWSMenus,} | ||||
| // WinCEWSImgList, | ||||
|  CustomDrawnWSMenus, | ||||
|  CustomDrawnWSSpin, | ||||
|  CustomDrawnWSStdCtrls, | ||||
|  CustomDrawnWSLazDeviceAPIs{, | ||||
| @ -513,14 +513,14 @@ end; | ||||
| // Menus | ||||
| function RegisterMenuItem: Boolean; alias : 'WSRegisterMenuItem'; | ||||
| begin | ||||
| //  RegisterWSComponent(TMenuItem, TWinCEWSMenuItem); | ||||
|   Result := False; | ||||
|   RegisterWSComponent(TMenuItem, TCDWSMenuItem); | ||||
|   Result := True; | ||||
| end; | ||||
| 
 | ||||
| function RegisterMenu: Boolean; alias : 'WSRegisterMenu'; | ||||
| begin | ||||
| //  RegisterWSComponent(TMenu, TWinCEWSMenu); | ||||
|   Result := False; | ||||
|   RegisterWSComponent(TMenu, TCDWSMenu); | ||||
|   Result := True; | ||||
| end; | ||||
| 
 | ||||
| function RegisterMainMenu: Boolean; alias : 'WSRegisterMainMenu'; | ||||
| @ -530,7 +530,7 @@ end; | ||||
| 
 | ||||
| function RegisterPopupMenu: Boolean; alias : 'WSRegisterPopupMenu'; | ||||
| begin | ||||
| //  RegisterWSComponent(TPopupMenu, TWinCEWSPopupMenu); | ||||
| //  RegisterWSComponent(TPopupMenu, TCDWSPopupMenu); | ||||
|   Result := False; | ||||
| end; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 sekelsenmat
						sekelsenmat