diff --git a/bindings/android-sdk/android_bindings_generator.lpi b/bindings/android-sdk/android_bindings_generator.lpi
index f9273fd10..d781dcf58 100644
--- a/bindings/android-sdk/android_bindings_generator.lpi
+++ b/bindings/android-sdk/android_bindings_generator.lpi
@@ -39,7 +39,7 @@
-
+
@@ -48,7 +48,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
@@ -71,7 +71,7 @@
-
+
@@ -79,7 +79,7 @@
-
+
@@ -87,7 +87,7 @@
-
+
@@ -95,7 +95,7 @@
-
+
@@ -103,14 +103,14 @@
-
+
-
+
@@ -119,9 +119,9 @@
-
-
-
+
+
+
@@ -130,7 +130,7 @@
-
+
@@ -138,14 +138,14 @@
-
+
-
+
@@ -153,7 +153,7 @@
-
+
@@ -162,7 +162,7 @@
-
+
@@ -170,7 +170,7 @@
-
+
@@ -178,7 +178,7 @@
-
+
@@ -186,23 +186,23 @@
-
+
-
+
-
-
-
+
+
+
@@ -212,14 +212,14 @@
-
+
-
+
@@ -229,7 +229,7 @@
-
+
@@ -237,7 +237,7 @@
-
+
@@ -246,9 +246,9 @@
-
-
-
+
+
+
@@ -258,7 +258,7 @@
-
+
@@ -267,7 +267,7 @@
-
+
@@ -276,7 +276,7 @@
-
+
@@ -286,7 +286,7 @@
-
+
@@ -296,7 +296,7 @@
-
+
@@ -306,7 +306,7 @@
-
+
@@ -316,7 +316,7 @@
-
+
@@ -326,131 +326,141 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bindings/android-sdk/android_sdk_bindings_gen.pas b/bindings/android-sdk/android_sdk_bindings_gen.pas
index 7d2b82243..637e849d1 100644
--- a/bindings/android-sdk/android_sdk_bindings_gen.pas
+++ b/bindings/android-sdk/android_sdk_bindings_gen.pas
@@ -22,6 +22,18 @@ type
FClassNum, FMethodNum: Integer;
FIsGlobalObject: Boolean;
FGlobalObject: string;
+ //
+ // ProcessMethodReturnValue
+ FMethodReturnPas, FDeclarationBase: string;
+ FDeclarationIsFunction: Boolean;
+ // ProcessMethodName
+ FMethodName: string;
+ // ProcessMethodParameters
+ FPascalParams, FJavaParams: string;
+ FHasStringParam: Boolean;
+ FPasOutputImplCurLine: Integer;
+ FCallbackTypePas: string;
+ //
procedure GeneratePascalFile(ASourceFile: string; ADest: TStringList);
procedure GenerateJavaFile(ASourceFile: string; ADest: TStringList);
procedure ProcessModelFile(ASourceFile, APasOutputFile, AJavaOutputFile: string);
@@ -30,7 +42,13 @@ type
procedure ProcessModelMethod(ASourceLine: string; AIsField: Boolean);
procedure ProcessModelConstructor(ASourceLine: string);
procedure ProcessModelConst(ASourceLine: string);
- procedure ProcessModelCallbackSetterCaller(ASourceLine: string);
+ procedure ProcessModelCallbackSetter(ASourceLine: string);
+ procedure ProcessModelType(ASourceLine: string);
+ //
+ procedure ProcessMethodReturnValue(ASourceLine: string; var lReaderPos: Integer);
+ procedure ProcessMethodName(ASourceLine: string; var lReaderPos: Integer);
+ procedure ProcessMethodParameters(ASourceLine: string; var lReaderPos: Integer; AAddParamRead: Boolean = True);
+ //
function GetNextWord(ALine: string; var AStartPos: Integer): string;
function GetPascalTypeName(ABaseName: string): string;
function PassByReference(ABaseName: string): Boolean;
@@ -314,9 +332,9 @@ begin
end;
// Callbacks
- if lCurWord = 'callbacksettercaller' then
+ if lCurWord = 'callbacksetter' then
begin
- ProcessModelCallbackSetterCaller(ASourceLine);
+ ProcessModelCallbackSetter(ASourceLine);
Exit;
end;
@@ -326,6 +344,13 @@ begin
ProcessModelMethod(ASourceLine, True);
Exit;
end;
+
+ // Types
+ if lCurWord = 'type' then
+ begin
+ ProcessModelType(ASourceLine);
+ Exit;
+ end;
end;
procedure TAndroidSDKBindingsGen.ProcessModelClass(ASourceLine: string; AIsInterface: Boolean);
@@ -401,7 +426,6 @@ var
lMethodReturn, lMethodReturnPas, lMethodName, lParamType, lParamTypePas, lParamName, lParamPrefix: string;
lMethodReturnJavaIdentifier: string;
DeclarationBase, TmpStr, lIDString: string;
- FPasOutputImplCurLine: Integer;
lJavaParamVar, lJavaParams, lJavaParamSelf: string;
// For adding the var for string params
HasStringParam: Boolean = False;
@@ -571,7 +595,6 @@ var
lMethodName, lParamType, lParamTypePas, lParamName: string;
lConstructorPasParams, lConstructorJavaParams, lParamPrefix, lJavaParamVar: string;
DeclarationBase, lIDString: string;
- FPasOutputImplCurLine: Integer;
HasActivityParam: Boolean = False;
begin
if ASourceLine = '' then Exit;
@@ -667,31 +690,34 @@ begin
lConstName := GetNextWord(ASourceLine, lReaderPos);
lConstName := GetNextWord(ASourceLine, lReaderPos);
lConstValue := GetNextWord(ASourceLine, lReaderPos);
- lConstValue := GetNextWord(ASourceLine, lReaderPos);
// Method type and name
FPasOutputConsts.Add(Format(' %s = %s;', [lConstName, lConstValue]));
end;
-// callbacksettercaller setOnClickListener callOnClickListener OnClickCallback = procedure (v: TView) of object;
-procedure TAndroidSDKBindingsGen.ProcessModelCallbackSetterCaller(ASourceLine: string);
+// old declaration: callbacksettercaller setOnClickListener callOnClickListener OnClickCallback = procedure (v: TView) of object;
+// new declaration: callbacksetter void setOnClickListener($View.OnClickListener l)
+procedure TAndroidSDKBindingsGen.ProcessModelCallbackSetter(ASourceLine: string);
var
lReaderPos: Integer = 1;
lCurWord: string;
lSetterName, lCallerName, lCallbackName, lCallbackDeclaration: string;
lIDSetter, lIDStart, lIDFinished: String;
lJavaParamSelf: string;
+ lStr: String;
begin
if ASourceLine = '' then Exit;
- lSetterName := GetNextWord(ASourceLine, lReaderPos);
- lSetterName := GetNextWord(ASourceLine, lReaderPos);
- lCallerName := GetNextWord(ASourceLine, lReaderPos);
- lCallbackDeclaration := Copy(ASourceLine, lReaderPos, Length(ASourceLine));
- lCallbackDeclaration := Trim(lCallbackDeclaration);
- lCallbackName := GetNextWord(ASourceLine, lReaderPos);
+ lStr := GetNextWord(ASourceLine, lReaderPos);
+ ProcessMethodReturnValue(ASourceLine, lReaderPos);
+ ProcessMethodName(ASourceLine, lReaderPos);
+ ProcessMethodParameters(ASourceLine, lReaderPos);
+
+ lSetterName := FMethodName;
lIDSetter := GetIDString(lSetterName);
+ lCallbackName := Copy(lSetterName, 4, Length(lSetterName)); // remove the "set" from the setter name
+ lCallerName := 'call' + lCallbackName;
AddOutputIDs(lIDSetter);
Inc(FMethodNum);
lIDStart := GetIDString(lCallbackName + '_Start');
@@ -701,28 +727,26 @@ begin
AddOutputIDs(lIDFinished);
Inc(FMethodNum);
- FPasOutputTypes.Add(' T' + lCallbackDeclaration);
+ FPasOutputClasses.Add( ' public');
+ FPasOutputClasses.Add(Format(' %s: %s;', [lCallbackName, FCallbackTypePas]));
+ FPasOutputClasses.Add(Format(' procedure %s(ACallback: %s);', [lSetterName, FCallbackTypePas]));
+ FPasOutputClasses.Add(Format(' procedure %s();', [lCallerName]));
+ FPasOutputClasses.Add( ' public');
- FPasOutputClasses.Add(' public');
- FPasOutputClasses.Add(' ' + lCallbackName + ': T' + lCallbackName + ';');
- FPasOutputClasses.Add(' procedure ' + lSetterName + '(ACallback: T' + lCallbackName + ');');
- FPasOutputClasses.Add(' procedure ' + lCallerName + '();');
- FPasOutputClasses.Add(' public');
-
- FPasOutputImpl.Add('procedure ' + FClassNamePas + '.' + lSetterName + '(ACallback: T' + lCallbackName + ');');
- FPasOutputImpl.Add('begin');
- FPasOutputImpl.Add(' OnClickListener := ACallback;');
- FPasOutputImpl.Add(' vAndroidPipesComm.SendByte(ShortInt(amkUICommand));');
- FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(' + lIDSetter + ');');
- FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Index); // Self, Java Index');
- FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(PtrInt(Self)); // Self, Pascal pointer');
- FPasOutputImpl.Add(' vAndroidPipesComm.WaitForReturn();');
- FPasOutputImpl.Add('end;');
- FPasOutputImpl.Add('');
- FPasOutputImpl.Add('procedure ' + FClassNamePas + '.' + lCallerName + '();');
- FPasOutputImpl.Add('begin');
- FPasOutputImpl.Add(' if Assigned(OnClickListener) then OnClickListener(Self);');
- FPasOutputImpl.Add('end;');
+ FPasOutputImpl.Add(Format('procedure %s.%s(ACallback: %s);', [FClassNamePas, lSetterName, FCallbackTypePas]));
+ FPasOutputImpl.Add( 'begin');
+ FPasOutputImpl.Add( ' OnClickListener := ACallback;');
+ FPasOutputImpl.Add( ' vAndroidPipesComm.SendByte(ShortInt(amkUICommand));');
+ FPasOutputImpl.Add( ' vAndroidPipesComm.SendInt(' + lIDSetter + ');');
+ FPasOutputImpl.Add( ' vAndroidPipesComm.SendInt(Index); // Self, Java Index');
+ FPasOutputImpl.Add( ' vAndroidPipesComm.SendInt(PtrInt(Self)); // Self, Pascal pointer');
+ FPasOutputImpl.Add( ' vAndroidPipesComm.WaitForReturn();');
+ FPasOutputImpl.Add( 'end;');
+ FPasOutputImpl.Add( '');
+ FPasOutputImpl.Add(Format('procedure %s.%s();', [FClassNamePas, lCallerName]));
+ FPasOutputImpl.Add( 'begin');
+ FPasOutputImpl.Add( ' if Assigned(OnClickListener) then OnClickListener(Self);');
+ FPasOutputImpl.Add( 'end;');
// Method type and name
FPasOutputMessages.Add(' ' + lIDStart + ':');
@@ -803,12 +827,148 @@ begin
break;*)
end;
+// type View.OnClickListener = void onClick(View v)
+procedure TAndroidSDKBindingsGen.ProcessModelType(ASourceLine: string);
+var
+ lReaderPos: Integer = 1;
+ lCurWord: string;
+ lStr, lCallbackDeclaration, lPascalType: String;
+begin
+ if ASourceLine = '' then Exit;
+
+ lStr := GetNextWord(ASourceLine, lReaderPos);
+
+ lStr := GetNextWord(ASourceLine, lReaderPos);
+ lPascalType := GetPascalTypeName(lStr);
+
+ ProcessMethodReturnValue(ASourceLine, lReaderPos);
+ ProcessMethodName(ASourceLine, lReaderPos);
+ ProcessMethodParameters(ASourceLine, lReaderPos, False);
+
+ if FDeclarationIsFunction then
+ FPasOutputTypes.Add(Format(' %s = %s (%s): %s of object;', [lPascalType, FDeclarationBase, FPascalParams, FMethodReturnPas]))
+ else
+ FPasOutputTypes.Add(Format(' %s = %s (%s) of object;', [lPascalType, FDeclarationBase, FPascalParams]));
+end;
+
+procedure TAndroidSDKBindingsGen.ProcessMethodReturnValue(ASourceLine: string;
+ var lReaderPos: Integer);
+var
+ lMethodReturn: String;
+begin
+ // Method type and name
+ lMethodReturn := GetNextWord(ASourceLine, lReaderPos);
+ FMethodReturnPas := GetPascalTypeName(lMethodReturn);
+
+ if lMethodReturn = 'void' then
+ begin
+ FDeclarationBase := 'procedure';
+ FDeclarationIsFunction := False;
+ end
+ else
+ begin
+ FDeclarationBase := 'function';
+ FDeclarationIsFunction := True;
+ end;
+end;
+
+procedure TAndroidSDKBindingsGen.ProcessMethodName(ASourceLine: string;
+ var lReaderPos: Integer);
+begin
+ FMethodName := GetNextWord(ASourceLine, lReaderPos);
+end;
+
+// callbacksetter void setOnClickListener($View.OnClickListener l)
+// $ indicates that this parameter should be skipped
+procedure TAndroidSDKBindingsGen.ProcessMethodParameters(ASourceLine: string;
+ var lReaderPos: Integer; AAddParamRead: Boolean);
+var
+ lParamNum: Integer = 1;
+ TmpStr: String;
+ lParamType, lPascalMethodModifiers: String;
+ lParamTypePas, lParamName, lParamPrefix: String;
+ lJavaParams, lJavaParamVar: String;
+ StringParamCount: Integer = 0;
+begin
+ // Add all parameters
+ TmpStr := '';
+ lJavaParams := '';
+ FHasStringParam := False;
+ FCallbackTypePas := '';
+
+ repeat
+ lParamType := GetNextWord(ASourceLine, lReaderPos);
+
+ if lParamType = '' then Break;
+
+ // Method modifiers
+ if (lParamType = 'virtual') or (lParamType = 'override') then Continue;
+ if (lParamType = 'overload') then
+ begin
+ lPascalMethodModifiers := ' overload;';
+ Continue;
+ end;
+
+ // Parameter to skip because it is a callback name, just write $,
+ if lParamType[1] = '$' then
+ begin
+ TmpStr := TmpStr + '$, ';
+ FCallbackTypePas := GetPascalTypeName(lParamType);
+ FCallbackTypePas := StringReplace(FCallbackTypePas, '$', '', [rfReplaceAll]);
+ lParamType := GetNextWord(ASourceLine, lReaderPos);
+ Continue;
+ end;
+
+ lParamTypePas := GetPascalTypeName(lParamType);
+ lParamName := GetNextWord(ASourceLine, lReaderPos);
+ if PassByReference(lParamType) then lParamPrefix := 'var '
+ else lParamPrefix := '';
+
+ if lParamName = '' then Break;
+
+ TmpStr := TmpStr + lParamPrefix + lParamName + ': ' + lParamTypePas + '; ';
+
+ if AAddParamRead then
+ begin
+ // Pascal parameter sending
+ if lParamTypePas = 'string' then
+ begin
+ FHasStringParam := True;
+ Inc(StringParamCount);
+ FPasOutputImpl.Insert(FPasOutputImplCurLine+1, Format(' lString_%d := TString.Create(%s);', [StringParamCount, lParamName]));
+ FPasOutputImpl.Add(Format(' vAndroidPipesComm.SendInt(lString_%d.Index); // text', [StringParamCount]));
+ end
+ else if IsBasicJavaType(lParamType) then
+ FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Integer(' + lParamName + '));')
+ else // for objects
+ FPasOutputImpl.Add(' vAndroidPipesComm.SendInt(Integer(' + lParamName + '.Index));');
+
+ // Java parameter reading
+ lJavaParamVar := Format('l%s_%d', [ConvertPointToUnderline(lParamType), lParamNum]);
+ FJavaOutputMethods.Add(Format(' %s = MyAndroidPipesComm.%s();',
+ [GetJavaTypeLocalVar(lParamType), GetJavaTypeReader(lParamType)]));
+ FJavaOutputMethods.Add(Format(' %s = %s;',
+ [lJavaParamVar, GetJavaTypeConverter(lParamType)]));
+ lJavaParams := lJavaParams + lJavaParamVar + ', ';
+
+ Inc(lParamNum);
+ end;
+ until lParamName = '';
+
+ // Remove the last ; for the parameters, if necessary
+ if (Length(TmpStr) > 0) and (TmpStr[Length(TmpStr)-1] = ';') then
+ TmpStr := System.Copy(TmpStr, 0, Length(TmpStr)-2);
+ FPascalParams := TmpStr;
+ // And for Java params too
+ FJavaParams := System.Copy(lJavaParams, 0, Length(lJavaParams)-2);
+end;
+
{ Reads one word in a string, starting at AStartPos (1-based index)
and going up to a space or comma or ( or ) or another separator }
function TAndroidSDKBindingsGen.GetNextWord(ALine: string;
var AStartPos: Integer): string;
const
- WordSeparators = [' ','(',')','[',']','{','}','%',',',';',':',#9{TAB}];
+ WordSeparators = [' ','(',')','[',']','{','}','%',',',';',':','=',#9{TAB}];
var
lState: Integer = 0;
begin
diff --git a/bindings/android-sdk/sdk_level_7/android_all.txt b/bindings/android-sdk/sdk_level_7/android_all.txt
index 3e661b31e..3400ad3ed 100644
--- a/bindings/android-sdk/sdk_level_7/android_all.txt
+++ b/bindings/android-sdk/sdk_level_7/android_all.txt
@@ -30,6 +30,12 @@ field int widthPixels
field float xdpi
field float ydpi
+#
+# android.content.*
+#
+{DialogInterface}
+type DialogInterface.OnClickListener = void onClick(DialogInterface dialog, int which)
+
#
# android.app.*
#
@@ -73,6 +79,7 @@ method AlertDialog.Builder setMessage (CharSequence message)
#public AlertDialog.Builder setOnKeyListener (DialogInterface.OnKeyListener onKeyListener)
#public AlertDialog.Builder setPositiveButton (int textId, DialogInterface.OnClickListener listener)
#public AlertDialog.Builder setPositiveButton (CharSequence text, DialogInterface.OnClickListener listener)
+# callbacksetter AlertDialog.Builder setPositiveButton (CharSequence text, DialogInterface.OnClickListener $listener)
#public AlertDialog.Builder setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener)
#public AlertDialog.Builder setSingleChoiceItems (ListAdapter adapter, int checkedItem, DialogInterface.OnClickListener listener)
#public AlertDialog.Builder setSingleChoiceItems (int itemsId, int checkedItem, DialogInterface.OnClickListener listener)
@@ -104,6 +111,7 @@ method void addView(View child, ViewGroup.LayoutParams params); overload;
method void addView(View child, int aindex); overload;
method void addView(View child); overload;
method void addView(View child, int width, int height); overload;
+type View.OnClickListener = void onClick(View v)
[LinearLayout] ViewGroup
constructor Create(Activity);
@@ -120,7 +128,7 @@ constructor Create(int param_width, int param_height, int param_x, int param_y);
[TextView] View
constructor Create(Activity); virtual;
method void setText(CharSequence AText); virtual;
-callbacksettercaller setOnClickListener callOnClickListener OnClickListener = procedure (v: TView) of object;
+callbacksetter void setOnClickListener($View.OnClickListener l)
method void setTextSize(int unit_; float size);
method CharSequence getText()