From 6ce47d9b51f6f540a8d3b6aece32ec0efdf2a37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 27 Jun 2016 10:32:14 +0200 Subject: Improve parallax mirroring algorithm Replaces the iterative approach currently used by an equivalent direct computation. Also fixes infinite looping that happens when the mirroring value is negative. --- scene/2d/parallax_layer.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index e9378b1d02..05136de5d6 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -123,26 +123,15 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2& p_offset,float p_sca Point2 new_ofs = ((orig_offset+p_offset)*motion_scale)*p_scale+motion_offset; if (mirroring.x) { - - while( new_ofs.x>=0) { - new_ofs.x -= mirroring.x*p_scale; - } - while(new_ofs.x < -mirroring.x*p_scale) { - new_ofs.x += mirroring.x*p_scale; - } + double den = mirroring.x*p_scale; + new_ofs.x -= den*ceil(new_ofs.x/den); } if (mirroring.y) { - - while( new_ofs.y>=0) { - new_ofs.y -= mirroring.y*p_scale; - } - while(new_ofs.y < -mirroring.y*p_scale) { - new_ofs.y += mirroring.y*p_scale; - } + double den = mirroring.y*p_scale; + new_ofs.y -= den*ceil(new_ofs.y/den); } - set_pos(new_ofs); set_scale(Vector2(1,1)*p_scale); -- cgit v1.2.3 From 96eb97cbbf8acd38a44ecb914e12aeda322d0bd4 Mon Sep 17 00:00:00 2001 From: Pawel Kowal Date: Sat, 2 Jul 2016 19:03:35 +0200 Subject: Array has(var value) function --- core/array.cpp | 4 ++++ core/array.h | 1 + core/variant_call.cpp | 2 ++ 3 files changed, 7 insertions(+) diff --git a/core/array.cpp b/core/array.cpp index bb8e527304..23792f90fc 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -200,6 +200,10 @@ int Array::count(const Variant& p_value) const { return amount; } +bool Array::has(const Variant& p_value) const { + return _p->array.find(p_value, 0) != -1; +} + void Array::remove(int p_pos) { _p->array.remove(p_pos); diff --git a/core/array.h b/core/array.h index 096660653e..dfc902525c 100644 --- a/core/array.h +++ b/core/array.h @@ -75,6 +75,7 @@ public: int rfind(const Variant& p_value, int p_from=-1) const; int find_last(const Variant& p_value) const; int count(const Variant& p_value) const; + bool has(const Variant& p_value) const; void erase(const Variant& p_value); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index a5927bb6f8..a56627970b 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -474,6 +474,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM2R(Array,rfind); VCALL_LOCALMEM1R(Array,find_last); VCALL_LOCALMEM1R(Array,count); + VCALL_LOCALMEM1R(Array,has); VCALL_LOCALMEM1(Array,erase); VCALL_LOCALMEM0(Array,sort); VCALL_LOCALMEM2(Array,sort_custom); @@ -1516,6 +1517,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC2(ARRAY,INT,Array,rfind,NIL,"what",INT,"from",varray(-1)); ADDFUNC1(ARRAY,INT,Array,find_last,NIL,"value",varray()); ADDFUNC1(ARRAY,INT,Array,count,NIL,"value",varray()); + ADDFUNC1(ARRAY,BOOL,Array,has,NIL,"value",varray()); ADDFUNC0(ARRAY,NIL,Array,pop_back,varray()); ADDFUNC0(ARRAY,NIL,Array,pop_front,varray()); ADDFUNC0(ARRAY,NIL,Array,sort,varray()); -- cgit v1.2.3 From 3698332f6be935a918a9afbba62abd1a7952f509 Mon Sep 17 00:00:00 2001 From: Ovnuniarchos Date: Sun, 17 Jul 2016 01:58:28 +0200 Subject: Exposed mode, access, filters, and show hidden files to the editor. Also, two functions to get/set the filter list. --- scene/gui/file_dialog.cpp | 19 ++++++++++++++++++- scene/gui/file_dialog.h | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index d335399caa..6b43425edc 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -475,7 +475,7 @@ void FileDialog::update_filters() { String flt=filters[i].get_slice(";",0).strip_edges(); String desc=filters[i].get_slice(";",1).strip_edges(); if (desc.length()) - filter->add_item(desc+" ( "+flt+" )"); + filter->add_item(String(XL_MESSAGE(desc))+" ( "+flt+" )"); else filter->add_item("( "+flt+" )"); } @@ -498,6 +498,16 @@ void FileDialog::add_filter(const String& p_filter) { } +void FileDialog::set_filters(const Vector& p_filters){ + filters=p_filters; + update_filters(); + invalidate(); +} + +Vector FileDialog::get_filters() const{ + return filters; +} + String FileDialog::get_current_dir() const { return dir->get_text(); @@ -686,6 +696,8 @@ void FileDialog::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_filters"),&FileDialog::clear_filters); ObjectTypeDB::bind_method(_MD("add_filter","filter"),&FileDialog::add_filter); + ObjectTypeDB::bind_method(_MD("set_filters","filters"),&FileDialog::set_filters); + ObjectTypeDB::bind_method(_MD("get_filters"),&FileDialog::get_filters); ObjectTypeDB::bind_method(_MD("get_current_dir"),&FileDialog::get_current_dir); ObjectTypeDB::bind_method(_MD("get_current_file"),&FileDialog::get_current_file); ObjectTypeDB::bind_method(_MD("get_current_path"),&FileDialog::get_current_path); @@ -722,6 +734,11 @@ void FileDialog::_bind_methods() { BIND_CONSTANT( ACCESS_USERDATA ); BIND_CONSTANT( ACCESS_FILESYSTEM ); + ADD_PROPERTY( PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"),_SCS("set_mode"),_SCS("get_mode") ); + ADD_PROPERTY( PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"),_SCS("set_access"),_SCS("get_access") ); + ADD_PROPERTY( PropertyInfo(Variant::STRING_ARRAY, "filters"),_SCS("set_filters"),_SCS("get_filters") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "show_hidden_files"),_SCS("set_show_hidden_files"),_SCS("is_showing_hidden_files") ); + } diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 1fcf8387ce..150b24cb3f 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -131,6 +131,8 @@ public: void clear_filters(); void add_filter(const String& p_filter); + void set_filters(const Vector& p_filters); + Vector get_filters() const; void set_enable_multiple_selection(bool p_enable); Vector get_selected_files() const; -- cgit v1.2.3 From f26f181ba964d4fa4903ab936c26a27c65a1e525 Mon Sep 17 00:00:00 2001 From: volzhs Date: Sun, 26 Jun 2016 02:37:50 +0900 Subject: Fix can't get all info if user purchases many items and not consumed --- .../godot/payments/PaymentsManager.java | 80 ++++++++++------------ 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index eb33b37ecc..35676e333e 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -144,57 +144,49 @@ public class PaymentsManager { } }.consumeItAll(); } - - public void requestPurchased(){ - try{ + + public void requestPurchased() { + try { PaymentsCache pc = new PaymentsCache(Godot.getInstance()); -// Log.d("godot", "requestPurchased for " + activity.getPackageName()); - Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp",null); + String continueToken = null; -/* - for (String key : bundle.keySet()) { - Object value = bundle.get(key); - Log.d("godot", String.format("%s %s (%s)", key, value.toString(), value.getClass().getName())); - } -*/ - - if (bundle.getInt("RESPONSE_CODE") == 0){ + do { + Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp", continueToken); - final ArrayList myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST"); - final ArrayList mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST"); - + if (bundle.getInt("RESPONSE_CODE") == 0) { - if (myPurchases == null || myPurchases.size() == 0){ -// Log.d("godot", "No purchases!"); - godotPaymentV3.callbackPurchased("", "", ""); - return; - } - -// Log.d("godot", "# products are purchased:" + myPurchases.size()); - for (int i=0;i myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST"); + final ArrayList mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST"); + + if (myPurchases == null || myPurchases.size() == 0) { + godotPaymentV3.callbackPurchased("", "", ""); + return; } - } - } - }catch(Exception e){ + for (int i = 0; i < myPurchases.size(); i++) { + + try { + String receipt = myPurchases.get(i); + JSONObject inappPurchaseData = new JSONObject(receipt); + String sku = inappPurchaseData.getString("productId"); + String token = inappPurchaseData.getString("purchaseToken"); + String signature = mySignatures.get(i); + + pc.setConsumableValue("ticket_signautre", sku, signature); + pc.setConsumableValue("ticket", sku, receipt); + pc.setConsumableFlag("block", sku, true); + pc.setConsumableValue("token", sku, token); + + godotPaymentV3.callbackPurchased(receipt, signature, sku); + } catch (JSONException e) { + } + } + } + continueToken = bundle.getString("INAPP_CONTINUATION_TOKEN"); + Log.d("godot", "continue token = " + continueToken); + } while (!TextUtils.isEmpty(continueToken)); + } catch (Exception e) { Log.d("godot", "Error requesting purchased products:" + e.getClass().getName() + ":" + e.getMessage()); } } -- cgit v1.2.3 From 79cb91dc842eded0fcbb562f127996759abeddc7 Mon Sep 17 00:00:00 2001 From: volzhs Date: Sun, 26 Jun 2016 02:46:40 +0900 Subject: Add querying details of IAP items for android --- .../src/org/godotengine/godot/GodotPaymentV3.java | 172 ++++++++------ .../godot/payments/PaymentsManager.java | 255 ++++++++++++++------- 2 files changed, 279 insertions(+), 148 deletions(-) diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index fde752acc9..b7de31ada3 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -28,99 +28,94 @@ /*************************************************************************/ package org.godotengine.godot; -import org.godotengine.godot.Dictionary; import android.app.Activity; import android.util.Log; +import org.godotengine.godot.payments.PaymentsManager; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class GodotPaymentV3 extends Godot.SingletonBase { private Godot activity; - private Integer purchaseCallbackId = 0; - private String accessToken; - private String purchaseValidationUrlPrefix; - private String transactionId; + private PaymentsManager mPaymentManager; + private Dictionary mSkuDetails = new Dictionary(); - public void purchase( String _sku, String _transactionId) { - final String sku = _sku; - final String transactionId = _transactionId; - activity.getPaymentsManager().setBaseSingleton(this); + public void purchase(final String sku, final String transactionId) { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().requestPurchase(sku, transactionId); + mPaymentManager.requestPurchase(sku, transactionId); } }); } - -/* public string requestPurchasedTicket(){ - activity.getPaymentsManager() - } -*/ - static public Godot.SingletonBase initialize(Activity p_activity) { + static public Godot.SingletonBase initialize(Activity p_activity) { - return new GodotPaymentV3(p_activity); - } + return new GodotPaymentV3(p_activity); + } - public GodotPaymentV3(Activity p_activity) { - registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume"}); - activity=(Godot) p_activity; + registerClass("GodotPayments", new String[]{"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails"}); + activity = (Godot) p_activity; + mPaymentManager = activity.getPaymentsManager(); + mPaymentManager.setBaseSingleton(this); } - public void consumeUnconsumedPurchases(){ - activity.getPaymentsManager().setBaseSingleton(this); + public void consumeUnconsumedPurchases() { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().consumeUnconsumedPurchases(); + mPaymentManager.consumeUnconsumedPurchases(); } }); } private String signature; - public String getSignature(){ - return this.signature; + + public String getSignature() { + return this.signature; } - - - public void callbackSuccess(String ticket, String signature, String sku){ -// Log.d(this.getClass().getName(), "PRE-Send callback to purchase success"); + + public void callbackSuccess(String ticket, String signature, String sku) { GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku}); -// Log.d(this.getClass().getName(), "POST-Send callback to purchase success"); -} + } + + public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) { + Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > " + ticket + "," + signature + "," + sku); + GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku}); + } - public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku){ -// Log.d(this.getClass().getName(), "PRE-Send callback to consume success"); - Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > "+ticket+","+signature+","+sku); - GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku}); -// Log.d(this.getClass().getName(), "POST-Send callback to consume success"); + public void callbackSuccessNoUnconsumedPurchases() { + GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[]{}); } - public void callbackSuccessNoUnconsumedPurchases(){ - GodotLib.calldeferred(purchaseCallbackId, "no_validation_required", new Object[]{}); + public void callbackFailConsume() { + GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[]{}); } - - public void callbackFail(){ + + public void callbackFail() { GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{}); -// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{}); } - - public void callbackCancel(){ + + public void callbackCancel() { GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[]{}); -// GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{}); } - - public void callbackAlreadyOwned(String sku){ + + public void callbackAlreadyOwned(String sku) { GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[]{sku}); } - + public int getPurchaseCallbackId() { return purchaseCallbackId; } @@ -129,11 +124,11 @@ public class GodotPaymentV3 extends Godot.SingletonBase { this.purchaseCallbackId = purchaseCallbackId; } - public String getPurchaseValidationUrlPrefix(){ - return this.purchaseValidationUrlPrefix ; + public String getPurchaseValidationUrlPrefix() { + return this.purchaseValidationUrlPrefix; } - public void setPurchaseValidationUrlPrefix(String url){ + public void setPurchaseValidationUrlPrefix(String url) { this.purchaseValidationUrlPrefix = url; } @@ -144,39 +139,80 @@ public class GodotPaymentV3 extends Godot.SingletonBase { public void setAccessToken(String accessToken) { this.accessToken = accessToken; } - - public void setTransactionId(String transactionId){ + + public void setTransactionId(String transactionId) { this.transactionId = transactionId; } - - public String getTransactionId(){ + + public String getTransactionId() { return this.transactionId; } - + // request purchased items are not consumed - public void requestPurchased(){ - activity.getPaymentsManager().setBaseSingleton(this); + public void requestPurchased() { activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().requestPurchased(); + mPaymentManager.requestPurchased(); } }); } - + // callback for requestPurchased() - public void callbackPurchased(String receipt, String signature, String sku){ + public void callbackPurchased(String receipt, String signature, String sku) { GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[]{receipt, signature, sku}); } - + // consume item automatically after purchase. default is true. - public void setAutoConsume(boolean autoConsume){ - activity.getPaymentsManager().setAutoConsume(autoConsume); + public void setAutoConsume(boolean autoConsume) { + mPaymentManager.setAutoConsume(autoConsume); } - + // consume a specific item - public void consume(String sku){ - activity.getPaymentsManager().consume(sku); + public void consume(String sku) { + mPaymentManager.consume(sku); + } + + // query in app item detail info + public void querySkuDetails(String[] list) { + List nKeys = Arrays.asList(list); + List cKeys = Arrays.asList(mSkuDetails.get_keys()); + ArrayList fKeys = new ArrayList(); + for (String key : nKeys) { + if (!cKeys.contains(key)) { + fKeys.add(key); + } + } + if (fKeys.size() > 0) { + mPaymentManager.querySkuDetails(fKeys.toArray(new String[0])); + } else { + completeSkuDetail(); + } + } + + public void addSkuDetail(String itemJson) { + JSONObject o = null; + try { + o = new JSONObject(itemJson); + Dictionary item = new Dictionary(); + item.put("type", o.optString("type")); + item.put("product_id", o.optString("productId")); + item.put("title", o.optString("title")); + item.put("description", o.optString("description")); + item.put("price", o.optString("price")); + item.put("price_currency_code", o.optString("price_currency_code")); + item.put("price_amount", 0.000001d * o.optLong("price_amount_micros")); + mSkuDetails.put(item.get("product_id").toString(), item); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void completeSkuDetail() { + GodotLib.calldeferred(purchaseCallbackId, "sku_details_complete", new Object[]{mSkuDetails}); + } + + public void errorSkuDetail(String errorMessage) { + GodotLib.calldeferred(purchaseCallbackId, "sku_details_error", new Object[]{errorMessage}); } } - diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index 35676e333e..753c0a6f93 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -28,119 +28,120 @@ /*************************************************************************/ package org.godotengine.godot.payments; -import java.util.ArrayList; -import java.util.List; - -import android.os.RemoteException; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteException; +import android.text.TextUtils; import android.util.Log; -import android.os.Bundle; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONStringer; +import com.android.vending.billing.IInAppBillingService; -import org.godotengine.godot.Dictionary; import org.godotengine.godot.Godot; import org.godotengine.godot.GodotPaymentV3; -import com.android.vending.billing.IInAppBillingService; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Arrays; public class PaymentsManager { public static final int BILLING_RESPONSE_RESULT_OK = 0; public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001; private static boolean auto_consume = true; - + private Activity activity; IInAppBillingService mService; - public void setActivity(Activity activity){ + public void setActivity(Activity activity) { this.activity = activity; } - public static PaymentsManager createManager(Activity activity){ + public static PaymentsManager createManager(Activity activity) { PaymentsManager manager = new PaymentsManager(activity); return manager; } - - private PaymentsManager(Activity activity){ + + private PaymentsManager(Activity activity) { this.activity = activity; } - - public PaymentsManager initService(){ + + public PaymentsManager initService() { Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); intent.setPackage("com.android.vending"); activity.bindService( - intent, - mServiceConn, + intent, + mServiceConn, Context.BIND_AUTO_CREATE); return this; } - public void destroy(){ + public void destroy() { if (mService != null) { - activity.unbindService(mServiceConn); - } + activity.unbindService(mServiceConn); + } } - + ServiceConnection mServiceConn = new ServiceConnection() { - @Override - public void onServiceDisconnected(ComponentName name) { - mService = null; - } + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } - @Override - public void onServiceConnected(ComponentName name, IBinder service) { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { mService = IInAppBillingService.Stub.asInterface(service); - } + } }; - - public void requestPurchase(final String sku, String transactionId){ + + public void requestPurchase(final String sku, String transactionId) { new PurchaseTask(mService, Godot.getInstance()) { - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - + } - + @Override protected void canceled() { godotPaymentV3.callbackCancel(); } - + @Override protected void alreadyOwned() { godotPaymentV3.callbackAlreadyOwned(sku); } - + }.purchase(sku, transactionId); } - public void consumeUnconsumedPurchases(){ + public void consumeUnconsumedPurchases() { new ReleaseAllConsumablesTask(mService, activity) { - + @Override protected void success(String sku, String receipt, String signature, String token) { godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku); } - + @Override protected void error(String message) { - godotPaymentV3.callbackFail(); - + Log.d("godot", "consumeUnconsumedPurchases :" + message); + godotPaymentV3.callbackFailConsume(); + } @Override protected void notRequired() { + Log.d("godot", "callbackSuccessNoUnconsumedPurchases :"); godotPaymentV3.callbackSuccessNoUnconsumedPurchases(); - + } }.consumeItAll(); } @@ -190,113 +191,207 @@ public class PaymentsManager { Log.d("godot", "Error requesting purchased products:" + e.getClass().getName() + ":" + e.getMessage()); } } - + public void processPurchaseResponse(int resultCode, Intent data) { - new HandlePurchaseTask(activity){ + new HandlePurchaseTask(activity) { @Override protected void success(final String sku, final String signature, final String ticket) { godotPaymentV3.callbackSuccess(ticket, signature, sku); - if (auto_consume){ + if (auto_consume) { new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { -// godotPaymentV3.callbackSuccess(""); } - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - + } }.consume(sku); } - -// godotPaymentV3.callbackSuccess(new PaymentsCache(activity).getConsumableValue("ticket", sku),signature); -// godotPaymentV3.callbackSuccess(ticket); - //validatePurchase(purchaseToken, sku); } @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } @Override protected void canceled() { godotPaymentV3.callbackCancel(); - } }.handlePurchaseRequest(resultCode, data); } - - public void validatePurchase(String purchaseToken, final String sku){ - - new ValidateTask(activity, godotPaymentV3){ + + public void validatePurchase(String purchaseToken, final String sku) { + + new ValidateTask(activity, godotPaymentV3) { @Override protected void success() { - + new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { godotPaymentV3.callbackSuccess(ticket, null, sku); - } - + @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } }.consume(sku); - + } @Override protected void error(String message) { godotPaymentV3.callbackFail(); - } @Override protected void canceled() { godotPaymentV3.callbackCancel(); - } }.validatePurchase(sku); } - - public void setAutoConsume(boolean autoConsume){ + + public void setAutoConsume(boolean autoConsume) { auto_consume = autoConsume; } - - public void consume(final String sku){ + + public void consume(final String sku) { new ConsumeTask(mService, activity) { - + @Override protected void success(String ticket) { godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku); - } - + @Override protected void error(String message) { - godotPaymentV3.callbackFail(); - + godotPaymentV3.callbackFailConsume(); } }.consume(sku); } - + + // Workaround to bug where sometimes response codes come as Long instead of Integer + int getResponseCodeFromBundle(Bundle b) { + Object o = b.get("RESPONSE_CODE"); + if (o == null) { + //logDebug("Bundle with null response code, assuming OK (known issue)"); + return BILLING_RESPONSE_RESULT_OK; + } else if (o instanceof Integer) return ((Integer) o).intValue(); + else if (o instanceof Long) return (int) ((Long) o).longValue(); + else { + //logError("Unexpected type for bundle response code."); + //logError(o.getClass().getName()); + throw new RuntimeException("Unexpected type for bundle response code: " + o.getClass().getName()); + } + } + + /** + * Returns a human-readable description for the given response code. + * + * @param code The response code + * @return A human-readable string explaining the result code. + * It also includes the result code numerically. + */ + public static String getResponseDesc(int code) { + String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" + + "3:Billing Unavailable/4:Item unavailable/" + + "5:Developer Error/6:Error/7:Item Already Owned/" + + "8:Item not owned").split("/"); + String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" + + "-1002:Bad response received/" + + "-1003:Purchase signature verification failed/" + + "-1004:Send intent failed/" + + "-1005:User cancelled/" + + "-1006:Unknown purchase response/" + + "-1007:Missing token/" + + "-1008:Unknown error/" + + "-1009:Subscriptions not available/" + + "-1010:Invalid consumption attempt").split("/"); + + if (code <= -1000) { + int index = -1000 - code; + if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index]; + else return String.valueOf(code) + ":Unknown IAB Helper Error"; + } else if (code < 0 || code >= iab_msgs.length) + return String.valueOf(code) + ":Unknown"; + else + return iab_msgs[code]; + } + + public void querySkuDetails(final String[] list) { + (new Thread(new Runnable() { + @Override + public void run() { + ArrayList skuList = new ArrayList(Arrays.asList(list)); + if (skuList.size() == 0) { + return; + } + // Split the sku list in blocks of no more than 20 elements. + ArrayList> packs = new ArrayList>(); + ArrayList tempList; + int n = skuList.size() / 20; + int mod = skuList.size() % 20; + for (int i = 0; i < n; i++) { + tempList = new ArrayList(); + for (String s : skuList.subList(i * 20, i * 20 + 20)) { + tempList.add(s); + } + packs.add(tempList); + } + if (mod != 0) { + tempList = new ArrayList(); + for (String s : skuList.subList(n * 20, n * 20 + mod)) { + tempList.add(s); + } + packs.add(tempList); + + for (ArrayList skuPartList : packs) { + Bundle querySkus = new Bundle(); + querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList); + Bundle skuDetails = null; + try { + skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus); + if (!skuDetails.containsKey("DETAILS_LIST")) { + int response = getResponseCodeFromBundle(skuDetails); + if (response != BILLING_RESPONSE_RESULT_OK) { + godotPaymentV3.errorSkuDetail(getResponseDesc(response)); + } else { + godotPaymentV3.errorSkuDetail("No error but no detail list."); + } + return; + } + + ArrayList responseList = skuDetails.getStringArrayList("DETAILS_LIST"); + + for (String thisResponse : responseList) { + Log.d("godot", "response = "+thisResponse); + godotPaymentV3.addSkuDetail(thisResponse); + } + } catch (RemoteException e) { + e.printStackTrace(); + godotPaymentV3.errorSkuDetail("RemoteException error!"); + } + } + godotPaymentV3.completeSkuDetail(); + } + } + })).start(); + } + private GodotPaymentV3 godotPaymentV3; - + public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) { this.godotPaymentV3 = godotPaymentV3; } } - -- cgit v1.2.3 From 1e7b9c509f02dd641f10fe50d24bb19c165078d7 Mon Sep 17 00:00:00 2001 From: Jaroslaw Filiochowski Date: Mon, 18 Jul 2016 22:14:57 +0200 Subject: Don't start a new tooltip timer for the same tooltip --- scene/main/viewport.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index bb6e6e289b..9d2b0cfccf 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2007,8 +2007,16 @@ void Viewport::_gui_input_event(InputEvent p_event) { } + bool is_tooltip_shown = false; - if (can_tooltip) { + if (can_tooltip && gui.tooltip_popup) { + String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos)); + + if (gui.tooltip_popup && tooltip == gui.tooltip_label->get_text()) + is_tooltip_shown = true; + } + + if (can_tooltip && !is_tooltip_shown) { gui.tooltip=over; gui.tooltip_pos=mpos;//(parent_xform * get_transform()).affine_inverse().xform(pos); -- cgit v1.2.3 From be560a750c363355ad077331bf6bdbc62c6b2762 Mon Sep 17 00:00:00 2001 From: Jaroslaw Filiochowski Date: Tue, 19 Jul 2016 06:27:12 +0200 Subject: Hide tooltip if new mouse position's tooltip is empty --- scene/main/viewport.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 9d2b0cfccf..cf84f8f425 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2009,11 +2009,17 @@ void Viewport::_gui_input_event(InputEvent p_event) { bool is_tooltip_shown = false; - if (can_tooltip && gui.tooltip_popup) { - String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos)); - - if (gui.tooltip_popup && tooltip == gui.tooltip_label->get_text()) - is_tooltip_shown = true; + if (gui.tooltip_popup) { + if (can_tooltip) { + String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos)); + + if (tooltip.length() == 0) + _gui_cancel_tooltip(); + else if (tooltip == gui.tooltip_label->get_text()) + is_tooltip_shown = true; + } + else + _gui_cancel_tooltip(); } if (can_tooltip && !is_tooltip_shown) { -- cgit v1.2.3 From 2b608846594bc69a20f8945c6f61bdb9319b2fdb Mon Sep 17 00:00:00 2001 From: Algrin6 Date: Thu, 21 Jul 2016 02:14:58 +0300 Subject: Fix curve bug --- scene/resources/curve.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 88ff09e961..29460790ff 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -644,7 +644,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset,bool p_cubic) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { @@ -1117,7 +1117,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset,bool p_cubic) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { @@ -1161,7 +1161,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const{ if (p_offset>=baked_max_ofs) return r[bpc-1]; - int idx = Math::floor(p_offset/bake_interval); + int idx = Math::floor((double)p_offset/(double)bake_interval); float frac = Math::fmod(p_offset,bake_interval); if (idx>=bpc-1) { -- cgit v1.2.3 From fc16954fa2d87707fa69293b7507dd43b028a96f Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Thu, 21 Jul 2016 03:40:08 +0200 Subject: TextEdit: Center search results --- scene/gui/text_edit.cpp | 28 ++++++++++++++++++++++++++++ scene/gui/text_edit.h | 2 ++ tools/editor/code_editor.cpp | 5 +++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a680d5d873..98e6ee366e 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2984,6 +2984,34 @@ void TextEdit::adjust_viewport_to_cursor() { } +void TextEdit::center_viewport_to_cursor() { + + if (cursor.line_ofs>cursor.line) + cursor.line_ofs=cursor.line; + + int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w-cache.breakpoint_gutter_width; + if (v_scroll->is_visible()) + visible_width-=v_scroll->get_combined_minimum_size().width; + visible_width-=20; // give it a little more space + + int visible_rows = get_visible_rows(); + if (h_scroll->is_visible()) + visible_rows-=((h_scroll->get_combined_minimum_size().height-1)/get_row_height()); + + int max_ofs = text.size()-(scroll_past_end_of_file_enabled?1:visible_rows); + cursor.line_ofs=CLAMP(cursor.line-(visible_rows/2),0,max_ofs); + + int cursor_x = get_column_x_offset( cursor.column, text[cursor.line] ); + + if (cursor_x>(cursor.x_ofs+visible_width)) + cursor.x_ofs=cursor_x-visible_width+1; + + if (cursor_x < cursor.x_ofs) + cursor.x_ofs=cursor_x; + + update(); +} + void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) { if (p_col<0) diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 270a1723b1..d67b3c998b 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -394,6 +394,8 @@ public: } void set_auto_indent(bool p_auto_indent); + void center_viewport_to_cursor(); + void cursor_set_column(int p_col, bool p_adjust_viewport=true); void cursor_set_line(int p_row, bool p_adjust_viewport=true); diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index 71ae171dfe..6c8d25aa01 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -133,8 +133,9 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) if (found) { if (!preserve_cursor) { - text_edit->cursor_set_line(line); - text_edit->cursor_set_column(col+text.length()); + text_edit->cursor_set_line(line, false); + text_edit->cursor_set_column(col+text.length(), false); + text_edit->center_viewport_to_cursor(); } text_edit->set_search_text(text); -- cgit v1.2.3 From 53beeb774b36b7af391e61fffeceb9f7ed3e299e Mon Sep 17 00:00:00 2001 From: Franklin Sobrinho Date: Wed, 20 Jul 2016 14:09:03 -0300 Subject: "FileSystem" dock now instance all selected scenes in one action --- tools/editor/editor_node.cpp | 10 +++++++--- tools/editor/editor_node.h | 3 ++- tools/editor/filesystem_dock.cpp | 10 ++++++++-- tools/editor/scene_tree_dock.cpp | 25 ++++++++++++++++++++++--- tools/editor/scene_tree_dock.h | 4 +++- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 3f93c05919..42c81c68f5 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3822,6 +3822,11 @@ void EditorNode::request_instance_scene(const String &p_path) { } +void EditorNode::request_instance_scenes(const Vector& p_files) { + + scene_tree_dock->instance_scenes(p_files); +} + FileSystemDock *EditorNode::get_scenes_dock() { return scenes_dock; @@ -3831,10 +3836,9 @@ SceneTreeDock *EditorNode::get_scene_tree_dock() { return scene_tree_dock; } -void EditorNode::_instance_request(const String& p_path){ - +void EditorNode::_instance_request(const Vector& p_files) { - request_instance_scene(p_path); + request_instance_scenes(p_files); } void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value,bool p_advance) { diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 9a227d3644..793c148671 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -452,7 +452,7 @@ private: void _save_scene(String p_file, int idx = -1); - void _instance_request(const String& p_path); + void _instance_request(const Vector& p_files); void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); @@ -666,6 +666,7 @@ public: static VSplitContainer *get_top_split() { return singleton->top_split; } void request_instance_scene(const String &p_path); + void request_instance_scenes(const Vector& p_files); FileSystemDock *get_scenes_dock(); SceneTreeDock *get_scene_tree_dock(); static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } diff --git a/tools/editor/filesystem_dock.cpp b/tools/editor/filesystem_dock.cpp index 3be122cc7d..378edd6667 100644 --- a/tools/editor/filesystem_dock.cpp +++ b/tools/editor/filesystem_dock.cpp @@ -950,14 +950,20 @@ void FileSystemDock::_file_option(int p_option) { } break; case FILE_INSTANCE: { + Vector paths; + for (int i = 0; iget_item_count(); i++) { if (!files->is_selected(i)) continue; String path =files->get_item_metadata(i); if (EditorFileSystem::get_singleton()->get_file_type(path)=="PackedScene") { - emit_signal("instance",path); + paths.push_back(path); } } + + if (!paths.empty()) { + emit_signal("instance", paths); + } } break; case FILE_DEPENDENCIES: { @@ -1596,7 +1602,7 @@ void FileSystemDock::_bind_methods() { ObjectTypeDB::bind_method(_MD("_preview_invalidated"),&FileSystemDock::_preview_invalidated); - ADD_SIGNAL(MethodInfo("instance")); + ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("open")); } diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index e4dfcc0f62..a3dec57882 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -106,11 +106,30 @@ void SceneTreeDock::instance(const String& p_file) { Vector scenes; scenes.push_back(p_file); - instance_scenes(scenes,parent,-1); + _perform_instance_scenes(scenes,parent,-1); } -void SceneTreeDock::instance_scenes(const Vector& p_files,Node* parent,int p_pos) { +void SceneTreeDock::instance_scenes(const Vector& p_files, Node *p_parent) { + + Node *parent = p_parent; + + if (!parent) { + parent = scene_tree->get_selected(); + } + + if (!parent || !edited_scene) { + + accept->get_ok()->set_text(TTR("OK")); + accept->set_text(TTR("No parent to instance the scenes at.")); + accept->popup_centered_minsize(); + return; + }; + + _perform_instance_scenes(p_files, parent, -1); +} + +void SceneTreeDock::_perform_instance_scenes(const Vector& p_files,Node* parent,int p_pos) { @@ -1677,7 +1696,7 @@ void SceneTreeDock::_files_dropped(Vector p_files,NodePath p_to,int p_ty int to_pos=-1; _normalize_drop(node,to_pos,p_type); - instance_scenes(p_files,node,to_pos); + _perform_instance_scenes(p_files,node,to_pos); } void SceneTreeDock::_nodes_dragged(Array p_nodes,NodePath p_to,int p_type) { diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 51041a235b..04ed16967f 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -148,6 +148,8 @@ class SceneTreeDock : public VBoxContainer { void _filter_changed(const String& p_filter); + void _perform_instance_scenes(const Vector& p_files,Node* parent,int p_pos); + protected: void _notification(int p_what); @@ -160,7 +162,7 @@ public: void import_subscene(); void set_edited_scene(Node* p_scene); void instance(const String& p_path); - void instance_scenes(const Vector& p_files,Node* parent,int p_pos); + void instance_scenes(const Vector& p_files, Node *p_parent=NULL); void set_selected(Node *p_node, bool p_emit_selected=false); void fill_path_renames(Node* p_node, Node *p_new_parent, List > *p_renames); void perform_node_renames(Node* p_base,List > *p_renames, Map, Set > *r_rem_anims=NULL); -- cgit v1.2.3 From f46f5306260f9a3e0bb04a99bd1b575580441149 Mon Sep 17 00:00:00 2001 From: Alex Piola Date: Fri, 22 Jul 2016 14:27:03 +0200 Subject: Fix #5854 Fix for #5854 --- servers/physics/body_pair_sw.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index 3202e52abb..06c728ea49 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -323,14 +323,14 @@ bool BodyPairSW::setup(float p_step) { #endif if (A->can_report_contacts()) { - Vector3 crB = A->get_angular_velocity().cross( c.rA ) + A->get_linear_velocity(); - A->add_contact(global_A,-c.normal,depth,shape_A,global_B,shape_B,B->get_instance_id(),B->get_self(),crB); - } - - if (B->can_report_contacts()) { - Vector3 crA = A->get_angular_velocity().cross( c.rB ) + A->get_linear_velocity(); - B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crA); - } + Vector3 crA = A->get_angular_velocity().cross( c.rA ) + A->get_linear_velocity(); + A->add_contact(global_A,-c.normal,depth,shape_A,global_B,shape_B,B->get_instance_id(),B->get_self(),crA); + } + + if (B->can_report_contacts()) { + Vector3 crB = B->get_angular_velocity().cross( c.rB ) + B->get_linear_velocity(); + B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crB); + } if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) { c.active=false; -- cgit v1.2.3 From 5d52146ff783e8966562b1feb144ef1fee03a6f5 Mon Sep 17 00:00:00 2001 From: Johan Manuel Date: Sat, 23 Jul 2016 14:47:49 +0200 Subject: Fix warnings in core/variant_op.cpp Adds default cases in switches where needed, and replaces '0;' with ';;' in macro expansions (as suggested by @vnen in #5587). --- core/variant_op.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 9182dcde1a..c537ed230f 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -600,6 +600,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& case REAL: { _RETURN( *reinterpret_cast(p_a._data._mem) * p_b._data._real); } break; + default: {} }; r_valid=false; return; @@ -618,6 +619,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& _RETURN( *p_a._data._matrix3 * *p_b._data._matrix3 ); }; + default: {} } ; r_valid=false; return; @@ -635,6 +637,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& _RETURN( *p_a._data._transform * *p_b._data._transform ); }; + default: {} } ; r_valid=false; return; @@ -999,7 +1002,7 @@ Variant Variant::get_named(const StringName& p_index, bool *r_valid) const { DEFAULT_OP_ARRAY_CMD(m_name, DVector, if(skip_cond) return;, arr->set(index, p_value);return) #define DEFAULT_OP_DVECTOR_GET(m_name, dv_type)\ - DEFAULT_OP_ARRAY_CMD(m_name, const DVector, 0, return arr->get(index)) + DEFAULT_OP_ARRAY_CMD(m_name, const DVector, ;, return arr->get(index)) void Variant::set(const Variant& p_index, const Variant& p_value, bool *r_valid) { @@ -2417,7 +2420,7 @@ Variant Variant::get(const Variant& p_index, bool *r_valid) const { return *res; } } break; // 20 - DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, 0, return (*arr)[index]) + DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index]) DEFAULT_OP_DVECTOR_GET(RAW_ARRAY, uint8_t) DEFAULT_OP_DVECTOR_GET(INT_ARRAY, int) DEFAULT_OP_DVECTOR_GET(REAL_ARRAY, real_t) @@ -2994,6 +2997,7 @@ bool Variant::iter_init(Variant& r_iter,bool &valid) const { return true; } break; + default: {} } @@ -3137,6 +3141,7 @@ bool Variant::iter_next(Variant& r_iter,bool &valid) const { r_iter=idx; return true; } break; + default: {} } @@ -3279,6 +3284,7 @@ Variant Variant::iter_get(const Variant& r_iter,bool &r_valid) const { #endif return arr->get(idx); } break; + default: {} } -- cgit v1.2.3 From 761193ecd9ac0240fc8bf945f0601acb82bf8e98 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Sat, 23 Jul 2016 21:37:25 +0200 Subject: Project Manager: Added project list scrolling with keyboard --- tools/editor/project_manager.cpp | 134 +++++++++++++++++++++++++++++++++++++++ tools/editor/project_manager.h | 1 + 2 files changed, 135 insertions(+) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index b7d3abfd5b..caf116523a 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -31,6 +31,7 @@ #include "os/os.h" #include "os/dir_access.h" #include "os/file_access.h" +#include "os/keyboard.h" #include "editor_settings.h" #include "scene/gui/separator.h" #include "scene/gui/tool_button.h" @@ -491,6 +492,10 @@ void ProjectManager::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { get_tree()->set_editor_hint(true); + + } else if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + set_process_unhandled_input(is_visible()); } } @@ -576,6 +581,134 @@ void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { } } +void ProjectManager::_unhandled_input(const InputEvent& p_ev) { + + if (p_ev.type==InputEvent::KEY) { + + const InputEventKey &k = p_ev.key; + + if (!k.pressed) + return; + + bool scancode_handled = true; + + switch (k.scancode) { + + case KEY_HOME: { + + for (int i=0; iget_child_count(); i++) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to(); + if (hb) { + selected_list.clear(); + selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + scroll->set_v_scroll(0); + break; + } + } + + } break; + case KEY_END: { + + for (int i=scroll_childs->get_child_count()-1; i>=0; i--) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to(); + if (hb) { + selected_list.clear(); + selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + scroll->set_v_scroll(scroll_childs->get_size().y); + break; + } + } + + } break; + case KEY_UP: { + + if (k.mod.shift) + break; + + if (selected_list.size()) { + + bool found = false; + + for (int i=scroll_childs->get_child_count()-1; i>=0; i--) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to(); + if (!hb) continue; + + String current = hb->get_meta("name"); + + if (found) { + selected_list.clear(); + selected_list.insert(current, hb->get_meta("main_scene")); + + int offset_diff = scroll->get_v_scroll() - hb->get_pos().y; + + if (offset_diff > 0) + scroll->set_v_scroll(scroll->get_v_scroll() - offset_diff); + + break; + + } else if (current==selected_list.back()->key()) { + + found = true; + } + } + + break; + } + // else fallthrough to key_down + } + case KEY_DOWN: { + + if (k.mod.shift) + break; + + bool found = selected_list.empty(); + + for (int i=0; iget_child_count(); i++) { + + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to(); + if (!hb) continue; + + String current = hb->get_meta("name"); + + if (found) { + selected_list.clear(); + selected_list.insert(current, hb->get_meta("main_scene")); + + int last_y_visible = scroll->get_v_scroll() + scroll->get_size().y; + int offset_diff = (hb->get_pos().y + hb->get_size().y) - last_y_visible; + + if (offset_diff > 0) + scroll->set_v_scroll(scroll->get_v_scroll() + offset_diff); + + break; + + } else if (current==selected_list.back()->key()) { + + found = true; + } + } + + } break; + default: { + scancode_handled = false; + } break; + } + + if (scancode_handled) { + accept_event(); + + for(int i=0;iget_child_count();i++) { + CanvasItem *item = scroll_childs->get_child(i)->cast_to(); + if (item) + item->update(); + } + } + } +} + void ProjectManager::_favorite_pressed(Node *p_hb) { String clicked = p_hb->get_meta("name"); @@ -964,6 +1097,7 @@ void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_load_recent_projects",&ProjectManager::_load_recent_projects); ObjectTypeDB::bind_method("_panel_draw",&ProjectManager::_panel_draw); ObjectTypeDB::bind_method("_panel_input",&ProjectManager::_panel_input); + ObjectTypeDB::bind_method("_unhandled_input",&ProjectManager::_unhandled_input); ObjectTypeDB::bind_method("_favorite_pressed",&ProjectManager::_favorite_pressed); ObjectTypeDB::bind_method("_install_project",&ProjectManager::_install_project); diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index 69467f50e7..74d1d3693c 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -92,6 +92,7 @@ class ProjectManager : public Control { void _panel_draw(Node *p_hb); void _panel_input(const InputEvent& p_ev,Node *p_hb); + void _unhandled_input(const InputEvent& p_ev); void _favorite_pressed(Node *p_hb); protected: -- cgit v1.2.3 From 308d405c31f83ce538fea76d6e88931718afc012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 24 Jul 2016 00:02:19 +0200 Subject: Turn some prints to error logs, remove others Fixes #5876 in passing. --- core/io/image_loader.cpp | 3 +-- core/math/geometry.cpp | 14 +++++++------- core/object_type_db.cpp | 2 +- tools/editor/editor_file_system.cpp | 2 +- tools/editor/io_plugins/editor_mesh_import_plugin.cpp | 1 - 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 05bad97e90..ac6c00dc61 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -51,7 +51,7 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom Error err; f=FileAccess::open(p_file,FileAccess::READ,&err); if (!f) { - print_line("ERROR OPENING FILE: "+p_file); + ERR_PRINTS("Error opening file: "+p_file); return err; } } @@ -76,7 +76,6 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom } - print_line("NO LOADER?"); if (!p_custom) memdelete(f); diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 5b767212f5..790903eff5 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -629,7 +629,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // create and initialize cells to zero - print_line("Wrapper: Initializing Cells"); + //print_line("Wrapper: Initializing Cells"); uint8_t ***cell_status=memnew_arr(uint8_t**,div_x); for(int i=0;i Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } // plot faces into cells - print_line("Wrapper (1/6): Plotting Faces"); + //print_line("Wrapper (1/6): Plotting Faces"); for (int i=0;i Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking - print_line("Wrapper (2/6) Flood Filling"); + //print_line("Wrapper (2/6): Flood Filling"); for (int i=0;i Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro // build faces for the inside-outside cell divisors - print_line("Wrapper (3/6): Building Faces"); + //print_line("Wrapper (3/6): Building Faces"); DVector wrapped_faces; @@ -709,7 +709,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } } - print_line("Wrapper (4/6): Transforming Back Vertices"); + //print_line("Wrapper (4/6): Transforming Back Vertices"); // transform face vertices to global coords @@ -728,7 +728,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro } // clean up grid - print_line("Wrapper (5/6): Grid Cleanup"); + //print_line("Wrapper (5/6): Grid Cleanup"); for(int i=0;i Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro if (p_error) *p_error=voxelsize.length(); - print_line("Wrapper (6/6): Finished."); + //print_line("Wrapper (6/6): Finished."); return wrapped_faces; } diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index 5f97df39a6..4998263961 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -828,7 +828,7 @@ MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , c TypeInfo *type=types.getptr(instance_type); if (!type) { - print_line("couldn't bind method "+mdname+" for instance: "+instance_type); + ERR_PRINTS("Couldn't bind method '"+mdname+"' for instance: "+instance_type); memdelete(p_bind); ERR_FAIL_COND_V(!type,NULL); } diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index cb7cefea26..582b9e2490 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -657,7 +657,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess da->change_dir(".."); } } else { - ERR_PRINTS(TTR("Cannot go into subdir:")+" "+E->get()); + ERR_PRINTS("Cannot go into subdir: "+E->get()); } p_progress.update(idx,total); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 2c3ed2afd6..da608292c1 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -496,7 +496,6 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref Date: Sat, 23 Jul 2016 23:59:24 +0200 Subject: Fix crash when GraphNode wasn't a child of a Control --- scene/gui/graph_node.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 94001b2ac1..3705541865 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -559,7 +559,12 @@ Color GraphNode::get_connection_output_color(int p_idx) { void GraphNode::_input_event(const InputEvent& p_ev) { if (p_ev.type==InputEvent::MOUSE_BUTTON) { + + ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node."); + ERR_FAIL_COND(get_parent_control() == NULL); + get_parent_control()->grab_focus(); + if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); -- cgit v1.2.3 From ffdd9f16dd6a765c34f3a5d454419479fd431af6 Mon Sep 17 00:00:00 2001 From: Alex Piola Date: Sun, 24 Jul 2016 12:53:07 +0200 Subject: Fix for incorrect velocity report due to a typo. Closes #5854 --- servers/physics/body_pair_sw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index 3202e52abb..43e52f26e8 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -323,13 +323,13 @@ bool BodyPairSW::setup(float p_step) { #endif if (A->can_report_contacts()) { - Vector3 crB = A->get_angular_velocity().cross( c.rA ) + A->get_linear_velocity(); - A->add_contact(global_A,-c.normal,depth,shape_A,global_B,shape_B,B->get_instance_id(),B->get_self(),crB); + Vector3 crA = A->get_angular_velocity().cross( c.rA ) + A->get_linear_velocity(); + A->add_contact(global_A,-c.normal,depth,shape_A,global_B,shape_B,B->get_instance_id(),B->get_self(),crA); } if (B->can_report_contacts()) { - Vector3 crA = A->get_angular_velocity().cross( c.rB ) + A->get_linear_velocity(); - B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crA); + Vector3 crB = B->get_angular_velocity().cross( c.rB ) + B->get_linear_velocity(); + B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crB); } if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) { -- cgit v1.2.3 From 67640c84eb60238be7e75d1b0d9d937518f885fb Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Sat, 23 Jul 2016 21:25:00 +0200 Subject: Viewport: Replace obsolete "windows" group calls - Fixes neighbour focusing event propagation not being stopped --- scene/main/viewport.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index bdb2754e5e..8faee0c549 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1782,7 +1782,6 @@ void Viewport::_gui_input_event(InputEvent p_event) { if (top->data.modal_exclusive || top->data.modal_frame==OS::get_singleton()->get_frames_drawn()) { //cancel event, sorry, modal exclusive EATS UP ALL //alternative, you can't pop out a window the same frame it was made modal (fixes many issues) - //get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); get_tree()->set_input_as_handled(); return; // no one gets the event if exclusive NO ONE } @@ -2062,7 +2061,6 @@ void Viewport::_gui_input_event(InputEvent p_event) { - //get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); get_tree()->set_input_as_handled(); @@ -2102,7 +2100,7 @@ void Viewport::_gui_input_event(InputEvent p_event) { if (gui.key_event_accepted) { - get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); + get_tree()->set_input_as_handled(); break; } } @@ -2162,7 +2160,7 @@ void Viewport::_gui_input_event(InputEvent p_event) { if (next) { next->grab_focus(); - get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID); + get_tree()->set_input_as_handled(); } } @@ -2355,8 +2353,7 @@ void Viewport::_gui_control_grab_focus(Control* p_control) { if (gui.key_focus && gui.key_focus==p_control) return; - _gui_remove_focus(); - get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_gui_remove_focus"); + get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"_viewports","_gui_remove_focus"); gui.key_focus=p_control; p_control->notification(Control::NOTIFICATION_FOCUS_ENTER); p_control->update(); @@ -2664,6 +2661,7 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_input_disabled"), &Viewport::is_input_disabled); ObjectTypeDB::bind_method(_MD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip); + ObjectTypeDB::bind_method(_MD("_gui_remove_focus"), &Viewport::_gui_remove_focus); ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") ); -- cgit v1.2.3 From 7be70c5a3c4645e50f2287fcdc777a282153b3c0 Mon Sep 17 00:00:00 2001 From: George Marques Date: Sun, 24 Jul 2016 12:07:59 -0300 Subject: Avoid changing position when the window is fullscreen --- platform/windows/os_windows.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6aee0d2399..a3858fe641 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1476,6 +1476,7 @@ Point2 OS_Windows::get_window_position() const{ } void OS_Windows::set_window_position(const Point2& p_position){ + if (video_mode.fullscreen) return; RECT r; GetWindowRect(hWnd,&r); MoveWindow(hWnd,p_position.x,p_position.y,r.right-r.left,r.bottom-r.top,TRUE); -- cgit v1.2.3 From 60d937354790ac025ba0caef17a3ca7c81244492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 24 Jul 2016 17:11:32 +0200 Subject: Fix non-visible col number in text editor The issue itself cannot be fully fixed due to the changes in 864c0e8, but this solution makes the bug less likely to happen (it would only happen with > 5 digits for line or column, and/or a much bigger font. Could be further refined by taking the configured font into account... Fixed #5890. --- tools/editor/code_editor.cpp | 40 ++++++++++++++++++++++++++++++---------- tools/editor/code_editor.h | 3 ++- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index 6c8d25aa01..ed7a46d70d 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -1032,8 +1032,8 @@ void CodeTextEditor::_reset_zoom() { void CodeTextEditor::_line_col_changed() { - String text = String()+TTR("Line:")+" "+itos(text_editor->cursor_get_line()+1)+", "+TTR("Col:")+" "+itos(text_editor->cursor_get_column()); - line_col->set_text(text); + line_nb->set_text(itos(text_editor->cursor_get_line() + 1)); + col_nb->set_text(itos(text_editor->cursor_get_column())); } void CodeTextEditor::_text_changed() { @@ -1191,6 +1191,7 @@ CodeTextEditor::CodeTextEditor() { HBoxContainer *status_bar = memnew( HBoxContainer ); status_mc->add_child(status_bar); status_bar->set_h_size_flags(SIZE_EXPAND_FILL); + status_bar->add_child( memnew( Label ) ); //to keep the height if the other labels are not visible idle = memnew( Timer ); add_child(idle); @@ -1212,14 +1213,33 @@ CodeTextEditor::CodeTextEditor() { status_bar->add_spacer(); - line_col = memnew( Label ); - status_bar->add_child(line_col); - line_col->set_valign(Label::VALIGN_CENTER); - line_col->set_autowrap(true); - line_col->set_v_size_flags(SIZE_FILL); - line_col->set_custom_minimum_size(Size2(100,1)*EDSCALE); - status_bar->add_child( memnew( Label ) ); //to keep the height if the other labels are not visible - + Label *line_txt = memnew( Label ); + status_bar->add_child(line_txt); + line_txt->set_align(Label::ALIGN_RIGHT); + line_txt->set_valign(Label::VALIGN_CENTER); + line_txt->set_v_size_flags(SIZE_FILL); + line_txt->set_text(TTR("Line:")); + + line_nb = memnew( Label ); + status_bar->add_child(line_nb); + line_nb->set_valign(Label::VALIGN_CENTER); + line_nb->set_v_size_flags(SIZE_FILL); + line_nb->set_autowrap(true); // workaround to prevent resizing the label on each change + line_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); + + Label *col_txt = memnew( Label ); + status_bar->add_child(col_txt); + col_txt->set_align(Label::ALIGN_RIGHT); + col_txt->set_valign(Label::VALIGN_CENTER); + col_txt->set_v_size_flags(SIZE_FILL); + col_txt->set_text(TTR("Col:")); + + col_nb = memnew( Label ); + status_bar->add_child(col_nb); + col_nb->set_valign(Label::VALIGN_CENTER); + col_nb->set_v_size_flags(SIZE_FILL); + col_nb->set_autowrap(true); // workaround to prevent resizing the label on each change + col_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); text_editor->connect("input_event", this,"_text_editor_input_event"); text_editor->connect("cursor_changed", this,"_line_col_changed"); diff --git a/tools/editor/code_editor.h b/tools/editor/code_editor.h index 7983c46f7a..88d882bd33 100644 --- a/tools/editor/code_editor.h +++ b/tools/editor/code_editor.h @@ -196,7 +196,8 @@ class CodeTextEditor : public VBoxContainer { TextEdit *text_editor; FindReplaceBar *find_replace_bar; - Label *line_col; + Label *line_nb; + Label *col_nb; Label *info; Timer *idle; Timer *code_complete_timer; -- cgit v1.2.3 From 991d9394d7a3ff03b412e80c8579523b3b4d47fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 24 Jul 2016 18:17:20 +0200 Subject: Bump version to 2.1-rc1 --- version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.py b/version.py index dd80ca1b19..19ff05f715 100644 --- a/version.py +++ b/version.py @@ -2,4 +2,4 @@ short_name="godot" name="Godot Engine" major=2 minor=1 -status="beta" +status="rc1" -- cgit v1.2.3 From 85f365bbffc0735a82d29ddce4e7991814ae1a5b Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 24 Jul 2016 14:37:26 -0300 Subject: shows progress (bytes) on download even if getting chunked content --- tools/editor/asset_library_editor_plugin.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/editor/asset_library_editor_plugin.cpp b/tools/editor/asset_library_editor_plugin.cpp index 4f685badfb..b6040b8928 100644 --- a/tools/editor/asset_library_editor_plugin.cpp +++ b/tools/editor/asset_library_editor_plugin.cpp @@ -325,6 +325,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int String error_text; + print_line("COMPLETED: "+itos(p_status)+" code: "+itos(p_code)+" data size: "+itos(p_data.size())); switch(p_status) { @@ -383,7 +384,9 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int print_line("max: "+itos(download->get_body_size())+" bytes: "+itos(download->get_downloaded_bytes())); install->set_disabled(false); - status->set_text("Success!"); + progress->set_val(download->get_downloaded_bytes()); + + status->set_text("Success! ("+String::humanize_size(download->get_downloaded_bytes())+")"); set_process(false); } @@ -411,6 +414,10 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { progress->set_val(download->get_downloaded_bytes()); int cstatus = download->get_http_client_status(); + + if (cstatus==HTTPClient::STATUS_BODY) + status->set_text("Fetching: "+String::humanize_size(download->get_downloaded_bytes())); + if (cstatus!=prev_status) { switch(cstatus) { @@ -423,9 +430,6 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) { case HTTPClient::STATUS_REQUESTING: { status->set_text("Requesting.."); } break; - case HTTPClient::STATUS_BODY: { - status->set_text("Downloading.."); - } break; default: {} } prev_status=cstatus; -- cgit v1.2.3 From ab93fd1af9db397f54cc0103867aa9953572fb84 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 24 Jul 2016 16:09:43 -0300 Subject: Add thread support to HTTPRequest, changed assetlib to use it. --- scene/main/http_request.cpp | 108 +++++++++++++++++++++------ scene/main/http_request.h | 13 +++- tools/editor/asset_library_editor_plugin.cpp | 7 +- 3 files changed, 102 insertions(+), 26 deletions(-) diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 040d509286..9b79af32bf 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -105,6 +105,9 @@ Error HTTPRequest::request(const String& p_url, const Vector& p_custom_h } Error err = _parse_url(p_url); + if (err) + return err; + validate_ssl=p_ssl_validate_domain; bool has_user_agent=false; @@ -127,19 +130,52 @@ Error HTTPRequest::request(const String& p_url, const Vector& p_custom_h headers.push_back("Accept: */*"); } + requesting=true; + + if (use_threads) { - err = _request(); + thread_done=false; + thread_request_quit=false; + client->set_blocking_mode(true); + thread=Thread::create(_thread_func,this); + } else { + client->set_blocking_mode(false); + err = _request(); + if (err!=OK) { + call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); + return ERR_CANT_CONNECT; + } - if (err==OK) { set_process(true); - requesting=true; + } - return err; + return OK; } +void HTTPRequest::_thread_func(void *p_userdata) { + + HTTPRequest *hr = (HTTPRequest*)p_userdata; + + Error err = hr->_request(); + + if (err!=OK) { + hr->call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); + } else { + while(!hr->thread_request_quit) { + + bool exit = hr->_update_connection(); + if (exit) + break; + OS::get_singleton()->delay_usec(1); + } + } + + hr->thread_done=true; +} + void HTTPRequest::cancel_request() { if (!requesting) @@ -147,6 +183,11 @@ void HTTPRequest::cancel_request() { if (!use_threads) { set_process(false); + } else { + thread_request_quit=true; + Thread::wait_to_finish(thread); + memdelete(thread); + thread=NULL; } if (file) { @@ -167,7 +208,7 @@ void HTTPRequest::cancel_request() { bool HTTPRequest::_handle_response(bool *ret_value) { if (!client->has_response()) { - call_deferred("emit_signal","request_completed",RESULT_NO_RESPONSE,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_NO_RESPONSE,0,StringArray(),ByteArray()); *ret_value=true; return true; } @@ -187,7 +228,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { //redirect if (max_redirects>=0 && redirections>=max_redirects) { - call_deferred("emit_signal","request_completed",RESULT_REDIRECT_LIMIT_REACHED,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_REDIRECT_LIMIT_REACHED,response_code,response_headers,ByteArray()); *ret_value=true; return true; } @@ -239,7 +280,8 @@ bool HTTPRequest::_update_connection() { switch( client->get_status() ) { case HTTPClient::STATUS_DISCONNECTED: { - return true; //end it, since it's doing something + call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); + return true; //end it, since it's doing something } break; case HTTPClient::STATUS_RESOLVING: { client->poll(); @@ -247,7 +289,7 @@ bool HTTPRequest::_update_connection() { return false; } break; case HTTPClient::STATUS_CANT_RESOLVE: { - call_deferred("emit_signal","request_completed",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_CANT_RESOLVE,0,StringArray(),ByteArray()); return true; } break; @@ -258,7 +300,7 @@ bool HTTPRequest::_update_connection() { } break; //connecting to ip case HTTPClient::STATUS_CANT_CONNECT: { - call_deferred("emit_signal","request_completed",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_CANT_CONNECT,0,StringArray(),ByteArray()); return true; } break; @@ -276,17 +318,17 @@ bool HTTPRequest::_update_connection() { return ret_value; - call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,ByteArray()); return true; } if (got_response && body_len<0) { //chunked transfer is done - call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body); + call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,body); return true; } - call_deferred("emit_signal","request_completed",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_CHUNKED_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); return true; //request migh have been done } else { @@ -294,7 +336,7 @@ bool HTTPRequest::_update_connection() { Error err = client->request(HTTPClient::METHOD_GET,request_string,headers); if (err!=OK) { - call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); return true; } @@ -320,7 +362,7 @@ bool HTTPRequest::_update_connection() { if (!client->is_response_chunked() && client->get_response_body_length()==0) { - call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,ByteArray()); return true; } @@ -331,7 +373,7 @@ bool HTTPRequest::_update_connection() { body_len=client->get_response_body_length(); if (body_size_limit>=0 && body_len>body_size_limit) { - call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); return true; } } @@ -340,7 +382,8 @@ bool HTTPRequest::_update_connection() { file=FileAccess::open(download_to_file,FileAccess::WRITE); if (!file) { - call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_DOWNLOAD_FILE_CANT_OPEN,response_code,response_headers,ByteArray()); + return true; } } } @@ -356,7 +399,7 @@ bool HTTPRequest::_update_connection() { ByteArray::Read r=chunk.read(); file->store_buffer(r.ptr(),chunk.size()); if (file->get_error()!=OK) { - call_deferred("emit_signal","request_completed",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_DOWNLOAD_FILE_WRITE_ERROR,response_code,response_headers,ByteArray()); return true; } } else { @@ -364,18 +407,18 @@ bool HTTPRequest::_update_connection() { } if (body_size_limit>=0 && downloaded>body_size_limit) { - call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_BODY_SIZE_LIMIT_EXCEEDED,response_code,response_headers,ByteArray()); return true; } if (body_len>=0) { if (downloaded==body_len) { - call_deferred("emit_signal","request_completed",RESULT_SUCCESS,response_code,response_headers,body); + call_deferred("_request_done",RESULT_SUCCESS,response_code,response_headers,body); return true; } /*if (body.size()>=body_len) { - call_deferred("emit_signal","request_completed",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); + call_deferred("_request_done",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); return true; }*/ } @@ -384,11 +427,11 @@ bool HTTPRequest::_update_connection() { } break; // request resulted in body: { } break which must be read case HTTPClient::STATUS_CONNECTION_ERROR: { - call_deferred("emit_signal","request_completed",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_CONNECTION_ERROR,0,StringArray(),ByteArray()); return true; } break; case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: { - call_deferred("emit_signal","request_completed",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray()); + call_deferred("_request_done",RESULT_SSL_HANDSHAKE_ERROR,0,StringArray(),ByteArray()); return true; } break; @@ -397,17 +440,35 @@ bool HTTPRequest::_update_connection() { ERR_FAIL_V(false); } + +void HTTPRequest::_request_done(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) { + + + cancel_request(); + emit_signal("request_completed",p_status,p_code,headers,p_data); +} + + void HTTPRequest::_notification(int p_what) { if (p_what==NOTIFICATION_PROCESS) { + if (use_threads) + return; bool done = _update_connection(); if (done) { set_process(false); + //cancel_request(); called from _request done now + } + } + + if (p_what==NOTIFICATION_EXIT_TREE) { + if (requesting) { cancel_request(); } } + } void HTTPRequest::set_use_threads(bool p_use) { @@ -491,6 +552,7 @@ void HTTPRequest::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_body_size"),&HTTPRequest::get_body_size); ObjectTypeDB::bind_method(_MD("_redirect_request"),&HTTPRequest::_redirect_request); + ObjectTypeDB::bind_method(_MD("_request_done"),&HTTPRequest::_request_done); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"use_threads"),_SCS("set_use_threads"),_SCS("is_using_threads")); ADD_PROPERTY(PropertyInfo(Variant::INT,"body_size_limit",PROPERTY_HINT_RANGE,"-1,2000000000"),_SCS("set_body_size_limit"),_SCS("get_body_size_limit")); @@ -517,6 +579,7 @@ void HTTPRequest::_bind_methods() { HTTPRequest::HTTPRequest() { + thread=NULL; port=80; redirections=0; @@ -530,6 +593,7 @@ HTTPRequest::HTTPRequest() requesting=false; client.instance(); use_threads=false; + thread_done=false; body_size_limit=-1; file=NULL; status=HTTPClient::STATUS_DISCONNECTED; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 7c3ccb2eb9..8dd433982b 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -32,6 +32,7 @@ #include "node.h" #include "io/http_client.h" #include "os/file_access.h" +#include "os/thread.h" class HTTPRequest : public Node { @@ -69,7 +70,7 @@ private: bool request_sent; Ref client; ByteArray body; - bool use_threads; + volatile bool use_threads; bool got_response; int response_code; @@ -80,7 +81,7 @@ private: FileAccess *file; int body_len; - int downloaded; + volatile int downloaded; int body_size_limit; int redirections; @@ -93,11 +94,19 @@ private: void _redirect_request(const String& p_new_url); + bool _handle_response(bool *ret_value); Error _parse_url(const String& p_url); Error _request(); + volatile bool thread_done; + volatile bool thread_request_quit; + + Thread *thread; + + void _request_done(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data); + static void _thread_func(void *p_userdata); protected: diff --git a/tools/editor/asset_library_editor_plugin.cpp b/tools/editor/asset_library_editor_plugin.cpp index b6040b8928..3fd5d2b5d1 100644 --- a/tools/editor/asset_library_editor_plugin.cpp +++ b/tools/editor/asset_library_editor_plugin.cpp @@ -134,13 +134,13 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() { category = memnew( LinkButton ); category->set_text("Editor Tools"); category->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); - title->connect("pressed",this,"_category_clicked"); + category->connect("pressed",this,"_category_clicked"); vb->add_child(category); author = memnew( LinkButton ); author->set_text("Johny Tolengo"); author->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); - title->connect("pressed",this,"_author_clicked"); + author->connect("pressed",this,"_author_clicked"); vb->add_child(author); HBoxContainer *rating_hb = memnew( HBoxContainer ); @@ -461,6 +461,7 @@ void EditorAssetLibraryItemDownload::_install() { void EditorAssetLibraryItemDownload::_make_request() { download->cancel_request(); download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_"+itos(asset_id))+".zip"); + Error err = download->request(host); if(err!=OK) { status->set_text("Error making request"); @@ -1011,6 +1012,7 @@ void EditorAssetLibrary::_api_request(const String& p_request, RequestType p_req if (requesting!=REQUESTING_NONE) { request->cancel_request(); } + requesting=p_request_type; error_hb->hide(); @@ -1469,6 +1471,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { request = memnew( HTTPRequest ); add_child(request); + request->set_use_threads(EDITOR_DEF("asset_library/use_threads",true)); request->connect("request_completed",this,"_http_request_completed"); last_queue_id=0; -- cgit v1.2.3 From ed094d52a9a281fc0735f633b02adc7f2cf11cf8 Mon Sep 17 00:00:00 2001 From: MarianoGNU Date: Sun, 24 Jul 2016 16:16:02 -0300 Subject: expose bottom panel button to EditorPlugin scripts --- tools/editor/editor_plugin.cpp | 4 ++-- tools/editor/editor_plugin.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp index 01e6b613c0..2bdd4caebe 100644 --- a/tools/editor/editor_plugin.cpp +++ b/tools/editor/editor_plugin.cpp @@ -44,9 +44,9 @@ void EditorPlugin::remove_custom_type(const String& p_type){ } -void EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) { +ToolButton * EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) { - EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control); + return EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control); } void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) { diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h index b93b6624d0..b960a7d5af 100644 --- a/tools/editor/editor_plugin.h +++ b/tools/editor/editor_plugin.h @@ -29,6 +29,7 @@ #ifndef EDITOR_PLUGIN_H #define EDITOR_PLUGIN_H +#include "scene/gui/tool_button.h" #include "scene/main/node.h" #include "scene/resources/texture.h" #include "undo_redo.h" @@ -92,7 +93,7 @@ public: //TODO: send a resoucre for editing to the editor node? void add_control_to_container(CustomControlContainer p_location, Control *p_control); - void add_control_to_bottom_panel(Control *p_control, const String &p_title); + ToolButton *add_control_to_bottom_panel(Control *p_control, const String &p_title); void add_control_to_dock(DockSlot p_slot,Control *p_control); void remove_control_from_docks(Control *p_control); void remove_control_from_bottom_panel(Control *p_control); -- cgit v1.2.3 From 23a20791d1f0c0760c0e22d51c0450b58b0e05f1 Mon Sep 17 00:00:00 2001 From: MarianoGNU Date: Sun, 24 Jul 2016 18:05:05 -0300 Subject: Update documentation. --- doc/base/classes.xml | 2 +- tools/editor/editor_plugin.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 4c2a0fe7ba..d70b11b5ae 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -11281,7 +11281,7 @@ - Add a control to the bottom panel (together with Output, Debug, Animation, etc). If your plugin is being removed, also make sure to remove your control by calling [method remove_control_from_bottom_panel]. + Add a control to the bottom panel (together with Output, Debug, Animation, etc). Returns a reference to the button added. It's up to you to hide/show the button when needed. If your plugin is being removed, also make sure to remove your control by calling [method remove_control_from_bottom_panel]. diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp index 2bdd4caebe..0d162cbe56 100644 --- a/tools/editor/editor_plugin.cpp +++ b/tools/editor/editor_plugin.cpp @@ -284,7 +284,7 @@ Control *EditorPlugin::get_base_control() { void EditorPlugin::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container); - ObjectTypeDB::bind_method(_MD("add_control_to_bottom_panel","control:Control","title"),&EditorPlugin::add_control_to_bottom_panel); + ObjectTypeDB::bind_method(_MD("add_control_to_bottom_panel:ToolButton","control:Control","title"),&EditorPlugin::add_control_to_bottom_panel); ObjectTypeDB::bind_method(_MD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock); ObjectTypeDB::bind_method(_MD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks); ObjectTypeDB::bind_method(_MD("remove_control_from_bottom_panel","control:Control"),&EditorPlugin::remove_control_from_bottom_panel); -- cgit v1.2.3 From 7dbdfe8dbd761631850db2e3476b74ae082fbe14 Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Mon, 25 Jul 2016 12:07:02 +0300 Subject: Fix default ranges of the inspector Probably closes #3091 (Should apply to Variant::REAL and Variant::INT) --- tools/editor/property_editor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 54d197f10d..26a49e92f0 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -3039,10 +3039,10 @@ void PropertyEditor::update_tree() { } else { if (p.type == Variant::REAL) { - item->set_range_config(1, -65536, 65535, 0.001); + item->set_range_config(1, -16777216, 16777216, 0.001); } else { - item->set_range_config(1, -65536, 65535, 1); + item->set_range_config(1, -2147483647, 2147483647, 1); } }; -- cgit v1.2.3 From a2b8ef6d5108f1822f323e23e8546878e3ec8fe3 Mon Sep 17 00:00:00 2001 From: Johan Manuel Date: Mon, 25 Jul 2016 15:31:57 +0200 Subject: Fix some warnings --- servers/audio/audio_mixer_sw.h | 3 +-- servers/audio_server.h | 3 ++- tools/editor/editor_node.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/servers/audio/audio_mixer_sw.h b/servers/audio/audio_mixer_sw.h index 950ed19af6..e924b518cc 100644 --- a/servers/audio/audio_mixer_sw.h +++ b/servers/audio/audio_mixer_sw.h @@ -69,8 +69,7 @@ private: MIX_VOLRAMP_FRAC_MASK=MIX_VOLRAMP_FRAC_LEN-1, MIX_FILTER_FRAC_BITS=16, MIX_FILTER_RAMP_FRAC_BITS=8, - MIX_VOL_MOVE_TO_24=4, - MAX_REVERBS=4 + MIX_VOL_MOVE_TO_24=4 }; diff --git a/servers/audio_server.h b/servers/audio_server.h index 50194af4a5..9e21e6b183 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -65,7 +65,8 @@ public: REVERB_SMALL, REVERB_MEDIUM, REVERB_LARGE, - REVERB_HALL + REVERB_HALL, + MAX_REVERBS }; virtual ChannelID channel_alloc(RID p_sample)=0; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 30b89cacc5..2839708f8d 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -1213,7 +1213,7 @@ void EditorNode::_dialog_action(String p_file) { case FILE_SAVE_SCENE: case FILE_SAVE_AS_SCENE: { - if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { + if (file->get_mode()==EditorFileDialog::MODE_SAVE_FILE) { //_save_scene(p_file); _save_scene_with_preview(p_file); @@ -1223,7 +1223,7 @@ void EditorNode::_dialog_action(String p_file) { } break; case FILE_SAVE_AND_RUN: { - if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { + if (file->get_mode()==EditorFileDialog::MODE_SAVE_FILE) { //_save_scene(p_file); _save_scene_with_preview(p_file); @@ -1448,7 +1448,7 @@ void EditorNode::_dialog_action(String p_file) { } break; default: { //save scene? - if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { + if (file->get_mode()==EditorFileDialog::MODE_SAVE_FILE) { //_save_scene(p_file); _save_scene_with_preview(p_file); -- cgit v1.2.3 From 2f8910185ea42a4b401a98b04f869562c87ffed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20L=C3=B3pez=20=C3=9Abeda?= Date: Mon, 25 Jul 2016 21:15:27 +0200 Subject: Update Tween class documentation --- doc/base/classes.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index d70b11b5ae..d741dbbb65 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -12264,7 +12264,7 @@ file.open("user://save_game.dat", file.WRITE) file.store_string(content) file.close() - + func load(): var file = File.new() file.open("user://save_game.dat", file.READ) @@ -15692,7 +15692,7 @@ - ImmediateGeometry is a node used for displaying simple geometry created from code, very similar to how glBegin() and glEnd() worked in old versions of OpenGL (1.x). + ImmediateGeometry is a node used for displaying simple geometry created from code, very similar to how glBegin() and glEnd() worked in old versions of OpenGL (1.x). Simply call [method begin()], and add vertices. For custom vertex colors, uvs, normal, etc. call one of the set_ functions below before adding each vertex. When done, call [method end] Calls to begin/end are accumulative and all geometry is added together. To clear all the geometry, call [method clear]. If a material override is set, and this material contains a texture, it's possible to override the texture used in this material for every begin/end set of calls. @@ -42401,7 +42401,7 @@ Because it is easy to get it wrong, here is a quick usage example: [codeblock] var tween = get_node("Tween") - tween.interpolate_property(get_node("Node2D_to_move"), "transform/pos", Vector2(0,0), Vector2(100,100), Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) + tween.interpolate_property(get_node("Node2D_to_move"), "transform/pos", Vector2(0,0), Vector2(100,100), 1, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) tween.start() [/codeblock] Some of the methods of this class require a property name. You can get the property name by hovering over the property in the inspector of the editor. -- cgit v1.2.3 From a155342eca0bf4417838e9d4f081450014f47e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 25 Jul 2016 23:08:46 +0200 Subject: GLES2: Check for GPU capabilities to display an error The engine will still segfault, but the error message should be displayed by the OS in a blocking manner, so that it will only crash once users have acknowledged the error dialog. Closes #1162. --- drivers/gles2/rasterizer_gles2.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 4cd97a7f6a..ba93a26a2d 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -10788,8 +10788,17 @@ void RasterizerGLES2::init() { if (OS::get_singleton()->is_stdout_verbose()) { print_line(String("GLES2: Using GLEW ") + (const char*) glewGetString(GLEW_VERSION)); } -#endif + // Check for GL 2.1 compatibility, if not bail out + if (!glewIsSupported("GL_VERSION_2_1")) { + ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / GLES 2.0, sorry :(\n" + "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); + OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / GLES 2.0, sorry :(\n" + "Godot Engine will self-destruct as soon as you acknowledge this error message.", + "Fatal error: Insufficient OpenGL / GLES drivers"); + // TODO: If it's even possible, we should stop the execution without segfault and memory leaks :) + } +#endif -- cgit v1.2.3 From 213a57ccafdf2f4fcc472801c60332d40cfe6464 Mon Sep 17 00:00:00 2001 From: "Daniel J. Ramirez" Date: Mon, 25 Jul 2016 21:45:20 -0500 Subject: Stop baking process if there is no geometry in the BakedLightInstance. moved missing baked light warning to BakedLightInstance configuration warning --- scene/3d/baked_light_instance.cpp | 10 ++++++++++ scene/3d/baked_light_instance.h | 2 ++ tools/editor/plugins/baked_light_baker.cpp | 4 ++++ tools/editor/plugins/baked_light_editor_plugin.cpp | 6 ++++-- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp index fafa62866f..ca3a309568 100644 --- a/scene/3d/baked_light_instance.cpp +++ b/scene/3d/baked_light_instance.cpp @@ -60,6 +60,8 @@ void BakedLightInstance::set_baked_light(const Ref& p_baked_light) { // VS::get_singleton()->instance_geometry_set_baked_light(E->get()->get_instance(),baked_light.is_valid()?get_instance():RID()); // } } + + update_configuration_warning(); } Ref BakedLightInstance::get_baked_light() const{ @@ -77,6 +79,14 @@ DVector BakedLightInstance::get_faces(uint32_t p_usage_flags) const { } +String BakedLightInstance::get_configuration_warning() const { + if (get_baked_light().is_null()) { + return TTR("BakedLightInstance does not contain a BakedLight resource."); + } + return String(); +} + + void BakedLightInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_baked_light","baked_light"),&BakedLightInstance::set_baked_light); diff --git a/scene/3d/baked_light_instance.h b/scene/3d/baked_light_instance.h index 92c2d50986..002e55df1d 100644 --- a/scene/3d/baked_light_instance.h +++ b/scene/3d/baked_light_instance.h @@ -55,6 +55,8 @@ public: virtual AABB get_aabb() const; virtual DVector get_faces(uint32_t p_usage_flags) const; + String get_configuration_warning() const; + BakedLightInstance(); }; diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp index 6a88ba4cbe..a2e94e8855 100644 --- a/tools/editor/plugins/baked_light_baker.cpp +++ b/tools/editor/plugins/baked_light_baker.cpp @@ -1772,6 +1772,10 @@ void BakedLightBaker::bake(const Ref &p_light, Node* p_node) { mat_map.clear(); tex_map.clear(); print_line("\ttotal triangles: "+itos(triangles.size())); + // no geometry + if (triangles.size() == 0) { + return; + } ep.step(TTR("Fixing Lights"),1); _fix_lights(); ep.step(TTR("Making BVH"),2); diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp index df76f28ae0..a58a0c25e2 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/tools/editor/plugins/baked_light_editor_plugin.cpp @@ -206,8 +206,9 @@ void BakedLightEditor::_menu_option(int p_option) { void BakedLightEditor::_bake_pressed() { ERR_FAIL_COND(!node); - if (node->get_baked_light().is_null()) { - err_dialog->set_text(TTR("BakedLightInstance does not contain a BakedLight resource.")); + const String conf_warning = node->get_configuration_warning(); + if (!conf_warning.empty()) { + err_dialog->set_text(conf_warning); err_dialog->popup_centered_minsize(); button_bake->set_pressed(false); return; @@ -236,6 +237,7 @@ void BakedLightEditor::_bake_pressed() { update_timeout=0; last_rays_time=0; + button_bake->set_pressed(false); set_process(true); } -- cgit v1.2.3 From ccf6b3151d1445f3e1bc351056a64b8f0094bc63 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Tue, 26 Jul 2016 11:54:59 +0200 Subject: Add gamepad mapping for the steam controller userspace driver. --- main/input_default.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/main/input_default.cpp b/main/input_default.cpp index 5e66a8b585..618d0d4f7d 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -588,6 +588,7 @@ static const char *s_ControllerMappings [] = "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", + "030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,", "030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", -- cgit v1.2.3 From fd659e869b86bc72d1e22ee601ba46d145b8dbaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 26 Jul 2016 15:16:45 +0200 Subject: Windows: Make alert message box use MB_TASKMODAL This flag pauses the current running thread, allowing for the user to see the alert and acknowledge it before the thread continues (and e.g. crashes :)). Thanks to @SuperUserNameMan for finding it. Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx --- platform/windows/os_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a3858fe641..571277f91e 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1343,7 +1343,7 @@ void OS_Windows::vprint(const char* p_format, va_list p_list, bool p_stderr) { void OS_Windows::alert(const String& p_alert,const String& p_title) { if (!is_no_window_mode_enabled()) - MessageBoxW(NULL,p_alert.c_str(),p_title.c_str(),MB_OK|MB_ICONEXCLAMATION); + MessageBoxW(NULL, p_alert.c_str(), p_title.c_str(), MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); else print_line("ALERT: "+p_alert); } -- cgit v1.2.3 From 9151eb591dcab408d3a7e4d9e3b3874c2e281acf Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 26 Jul 2016 17:24:34 -0300 Subject: Changed the way the step decimals are computed to a safer way, fixes many issues. --- bin/tests/test_math.cpp | 1 + core/math/math_funcs.cpp | 36 ++++++++++++++++++++---------------- core/math/math_funcs.h | 2 +- modules/gdscript/gd_functions.cpp | 2 +- scene/gui/spin_box.cpp | 2 +- scene/gui/tree.cpp | 8 ++++---- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/bin/tests/test_math.cpp b/bin/tests/test_math.cpp index 8e08969fa4..4b686e8af8 100644 --- a/bin/tests/test_math.cpp +++ b/bin/tests/test_math.cpp @@ -113,6 +113,7 @@ uint32_t ihash3( uint32_t a) MainLoop* test() { + print_line(itos(Math::step_decimals( 0.0001 ))); return NULL; { diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 0fbd031214..64615fe6b4 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -206,25 +206,29 @@ double Math::ceil(double p_x) { return ::ceil(p_x); } -int Math::decimals(double p_step) { - - int max=4; - double llimit = Math::pow(0.1,max); - double ulimit = 1.0-llimit; - int i=0; - while( max) { - - float d = absf(p_step) - Math::floor(absf(p_step)); +int Math::step_decimals(double p_step) { + + static const int maxn=9; + static const double sd[maxn]={ + 0.9999, // somehow compensate for floating point error + 0.09999, + 0.009999, + 0.0009999, + 0.00009999, + 0.000009999, + 0.0000009999, + 0.00000009999, + 0.000000009999 + }; - if (dulimit) - break; - p_step*=10.0; - max--; - i++; + double as=absf(p_step); + for(int i=0;i=sd[i]) { + return i; + } } - return i; - + return maxn; } double Math::ease(double p_x, double p_c) { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 2e1b9c989e..fc76d96b2e 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -66,7 +66,7 @@ public: static double floor(double p_x); static double ceil(double p_x); static double ease(double p_x, double p_c); - static int decimals(double p_step); + static int step_decimals(double p_step); static double stepify(double p_value,double p_step); static void seed(uint32_t x=0); static void randomize(); diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index b9815a5efd..a565e866d0 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -304,7 +304,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va case MATH_DECIMALS: { VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); - r_ret=Math::decimals(*p_args[0]); + r_ret=Math::step_decimals(*p_args[0]); } break; case MATH_STEPIFY: { VALIDATE_ARG_COUNT(2); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 2b64d36a81..98e1a32aef 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -39,7 +39,7 @@ Size2 SpinBox::get_minimum_size() const { void SpinBox::_value_changed(double) { - String value = String::num(get_val(),Math::decimals(get_step())); + String value = String::num(get_val(),Math::step_decimals(get_step())); if (prefix!="") value=prefix+" "+value; if (suffix!="") diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 82459ba0ab..487f62ed44 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1179,8 +1179,8 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Ref updown = cache.updown; - //String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) ); - String valtext = rtos( p_item->cells[i].val ); + String valtext = String::num( p_item->cells[i].val, Math::step_decimals( p_item->cells[i].step ) ); + //String valtext = rtos( p_item->cells[i].val ); font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width()); if (!p_item->cells[i].editable) @@ -1746,7 +1746,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } else { - editor_text=String::num( p_item->cells[col].val, Math::decimals( p_item->cells[col].step ) ); + editor_text=String::num( p_item->cells[col].val, Math::step_decimals( p_item->cells[col].step ) ); if (select_mode==SELECT_MULTI && get_tree()->get_last_event_id() == focus_in_id) bring_up_editor=false; @@ -2521,7 +2521,7 @@ bool Tree::edit_selected() { text_editor->set_pos( textedpos ); text_editor->set_size( rect.size); text_editor->clear(); - text_editor->set_text( c.mode==TreeItem::CELL_MODE_STRING?c.text:rtos(c.val) ); + text_editor->set_text( c.mode==TreeItem::CELL_MODE_STRING?c.text:String::num( c.val, Math::step_decimals( c.step ) ) ); text_editor->select_all(); if (c.mode==TreeItem::CELL_MODE_RANGE || c.mode==TreeItem::CELL_MODE_RANGE_EXPRESSION ) { -- cgit v1.2.3 From 60e19f77519caee64842319443cd19e20c699d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 26 Jul 2016 23:19:41 +0200 Subject: Fix GraphEdit dragging issues at scales != 1 Works around the issue originally described in #5907 (that was then hijacked to describe the broader issue it exposes). --- scene/gui/graph_edit.cpp | 5 ++++- scene/gui/graph_edit.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 06b1c42690..9ad621b7aa 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -548,7 +548,9 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { just_selected=true; - drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); + // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats + //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); + drag_accum = get_local_mouse_pos() - drag_origin; for(int i=get_child_count()-1;i>=0;i--) { GraphNode *gn=get_child(i)->cast_to(); if (gn && gn->is_selected()) @@ -665,6 +667,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { dragging = true; drag_accum = Vector2(); + drag_origin = get_local_mouse_pos(); just_selected = !gn->is_selected(); if(!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index ac4e71ba49..ed6838ac1d 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -92,6 +92,7 @@ private: bool dragging; bool just_selected; Vector2 drag_accum; + Point2 drag_origin; // Workaround for GH-5907 float zoom; -- cgit v1.2.3 From 759e20aac69eca8beeca95a0f321c6a3f41f435f Mon Sep 17 00:00:00 2001 From: Dima Granetchi Date: Tue, 26 Jul 2016 22:17:41 +0300 Subject: Command-F focus filter input field in project manager --- tools/editor/project_manager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index caf116523a..dd634e51ee 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -692,6 +692,10 @@ void ProjectManager::_unhandled_input(const InputEvent& p_ev) { } } break; + case KEY_F: { + if (k.mod.command) this->project_filter->search_box->grab_focus(); + else scancode_handled = false; + } break; default: { scancode_handled = false; } break; -- cgit v1.2.3 From 535a6f9faf21f1f8cbd0f4580de47cfc231a625d Mon Sep 17 00:00:00 2001 From: Pawel Kowal Date: Wed, 27 Jul 2016 15:49:15 +0200 Subject: Array has() documentation --- doc/base/classes.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/base/classes.xml b/doc/base/classes.xml index d741dbbb65..dc24231dd0 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -4546,6 +4546,15 @@ Searches the array in reverse order for a value and returns its index or -1 if not found. + + + + + + + Return true if the array contains given value. [code][ "inside", 7 ].has("inside") == true, [ "inside", 7 ].has("outside") == false, [ "inside", 7 ].has(7) == true, [ "inside", 7 ].has("7") == false[/code] + + -- cgit v1.2.3 From 2150855fafd76f881bf5b1389d7740216981aaf0 Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Wed, 27 Jul 2016 17:59:42 +0300 Subject: Fix reading of empty StringArray-s in .tscn Closes #5912 --- core/variant_parser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index dce873a306..023605a952 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1233,7 +1233,9 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in } get_token(p_stream,token,line,r_err_str); - if (token.type!=TK_STRING) { + if (token.type==TK_PARENTHESIS_CLOSE) { + break; + } else if (token.type!=TK_STRING) { r_err_str="Expected string"; return ERR_PARSE_ERROR; } -- cgit v1.2.3 From eefca1ada97a6bc5db38936d23da323a78b2044d Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Tue, 26 Jul 2016 17:19:49 +0200 Subject: Prettier str() for some math types --- core/math/math_2d.cpp | 2 +- core/math/math_2d.h | 8 ++++---- core/math/matrix3.cpp | 13 ++++++++++--- core/math/quat.cpp | 2 +- core/math/vector3.cpp | 2 +- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 0e2060008c..cf01e972a4 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -658,5 +658,5 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons Matrix32::operator String() const { - return String(String()+elements[0]+", "+elements[1]+", "+elements[2]); + return "("+String(String()+elements[0]+", "+elements[1]+", "+elements[2])+")"; } diff --git a/core/math/math_2d.h b/core/math/math_2d.h index ad4655b8f7..5f511c933e 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -157,7 +157,7 @@ struct Vector2 { float get_aspect() const { return width/height; } - operator String() const { return String::num(x)+","+String::num(y); } + operator String() const { return "("+String::num(x)+", "+String::num(y)+")"; } _FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; } _FORCE_INLINE_ Vector2() { x=0; y=0; } @@ -356,7 +356,7 @@ struct Rect2 { } - operator String() const { return String(pos)+","+String(size); } + operator String() const { return "("+String(pos)+", "+String(size)+")"; } Rect2() {} Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); } @@ -409,7 +409,7 @@ struct Point2i { float get_aspect() const { return width/(float)height; } - operator String() const { return String::num(x)+","+String::num(y); } + operator String() const { return "("+String::num(x)+", "+String::num(y)+")"; } operator Vector2() const { return Vector2(x,y); } inline Point2i(const Vector2& p_vec2) { x=(int)p_vec2.x; y=(int)p_vec2.y; } @@ -540,7 +540,7 @@ struct Rect2i { } - operator String() const { return String(pos)+","+String(size); } + operator String() const { return "("+String(pos)+", "+String(size)+")"; } operator Rect2() const { return Rect2(pos,size); } Rect2i(const Rect2& p_r2) { pos=p_r2.pos; size=p_r2.size; } diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 71e6b62212..7b811c245c 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -233,19 +233,26 @@ bool Matrix3::operator!=(const Matrix3& p_matrix) const { Matrix3::operator String() const { - String mtx; + String mtx("("); for (int i=0;i<3;i++) { + if (i!=0) + mtx+=", "; + + mtx+="("; + for (int j=0;j<3;j++) { - if (i!=0 || j!=0) + if (j!=0) mtx+=", "; mtx+=rtos( elements[i][j] ); } + + mtx+=")"; } - return mtx; + return mtx+")"; } Matrix3::operator Quat() const { diff --git a/core/math/quat.cpp b/core/math/quat.cpp index c6c12129b3..5457638ada 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const Quat::operator String() const { - return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w); + return "("+String::num(x)+", "+String::num(y)+", "+ String::num(z)+", "+ String::num(w)+")"; } Quat::Quat(const Vector3& axis, const real_t& angle) { diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 8afd73f482..8a0a6e963d 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -182,5 +182,5 @@ Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, co # endif Vector3::operator String() const { - return (rtos(x)+", "+rtos(y)+", "+rtos(z)); + return "("+(rtos(x)+", "+rtos(y)+", "+rtos(z))+")"; } -- cgit v1.2.3 From 9df192d8ec2a332f62f2dae2634828abcd9015c4 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Wed, 27 Jul 2016 17:29:51 +0200 Subject: Project Settings: Use containers for the Input Map tab content --- tools/editor/project_settings.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp index 6be1abf52f..e8d22143ee 100644 --- a/tools/editor/project_settings.cpp +++ b/tools/editor/project_settings.cpp @@ -1375,34 +1375,35 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { input_base->set_area_as_parent_rect();; tab_container->add_child(input_base); + VBoxContainer *vbc = memnew( VBoxContainer ); + input_base->add_child(vbc); + vbc->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN, 5 ); + vbc->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 5 ); + vbc->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 ); + vbc->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 ); + l = memnew( Label ); - input_base->add_child(l); + vbc->add_child(l); l->set_pos(Point2(6,5)); l->set_text(TTR("Action:")); + hbc = memnew( HBoxContainer ); + vbc->add_child(hbc); + action_name = memnew( LineEdit ); - action_name->set_anchor(MARGIN_RIGHT,ANCHOR_RATIO); - action_name->set_begin( Point2(5,25) ); - action_name->set_end( Point2(0.85,26) ); - input_base->add_child(action_name); + action_name->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(action_name); action_name->connect("text_entered",this,"_action_adds"); add = memnew( Button ); - input_base->add_child(add); - add->set_anchor(MARGIN_LEFT,ANCHOR_RATIO); - add->set_begin( Point2(0.86,25) ); - add->set_anchor(MARGIN_RIGHT,ANCHOR_END); - add->set_end( Point2(5,26) ); + hbc->add_child(add); + add->set_custom_minimum_size(Size2(150, 0)); add->set_text(TTR("Add")); add->connect("pressed",this,"_action_add"); input_editor = memnew( Tree ); - input_base->add_child(input_editor); - input_editor->set_area_as_parent_rect(); - input_editor->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN, 55 ); - input_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 ); - input_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 ); - input_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 ); + vbc->add_child(input_editor); + input_editor->set_v_size_flags(SIZE_EXPAND_FILL); input_editor->connect("item_edited",this,"_action_edited"); input_editor->connect("cell_selected",this,"_action_selected"); input_editor->connect("button_pressed",this,"_action_button_pressed"); -- cgit v1.2.3 From b48fd16add3669219ad38c27f7db7fc2d5e32130 Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 27 Jul 2016 12:34:29 -0300 Subject: Improve Windows application details --- platform/windows/godot_res.rc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index 5f1e951e0f..c1754afa8c 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -3,12 +3,18 @@ #define _STR(m_x) #m_x #define _MKSTR(m_x) _STR(m_x) #endif +#ifndef VERSION_PATCH +#define VERSION_PATCH 0 +#define PATCH_STRING +#else +#define PATCH_STRING "." _MKSTR(VERSION_PATCH) +#endif GODOT_ICON ICON platform/windows/godot.ico 1 VERSIONINFO -FILEVERSION VERSION_MAJOR,VERSION_MINOR,0,0 -PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,0,0 +FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 +PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 FILEOS 4 FILETYPE 1 BEGIN @@ -18,12 +24,12 @@ BEGIN BEGIN VALUE "CompanyName", "Godot Engine" VALUE "FileDescription", _MKSTR(VERSION_NAME) " Editor (" _MKSTR(VERSION_STATUS) ")" - VALUE "FileVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "."_MKSTR(VERSION_REVISION) + VALUE "FileVersion", _MKSTR(VERSION_MAJOR),_MKSTR(VERSION_MINOR),_MKSTR(VERSION_PATCH) VALUE "ProductName", _MKSTR(VERSION_NAME) VALUE "Licence", "MIT" VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur" VALUE "Info", "http://www.godotengine.org" - VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "."_MKSTR(VERSION_REVISION) + VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." _MKSTR(VERSION_REVISION) END END BLOCK "VarFileInfo" -- cgit v1.2.3 From cf851f7ed432134adb1da0077995a3ff26cc404d Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Wed, 27 Jul 2016 18:11:55 +0200 Subject: AboutDialog: Popup respecting its minimum size --- tools/editor/editor_node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 2839708f8d..f27a753464 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -2842,7 +2842,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; case SETTINGS_ABOUT: { - about->popup_centered(Size2(500,130)*EDSCALE); + about->popup_centered_minsize(Size2(500,130)*EDSCALE); } break; case SOURCES_REIMPORT: { -- cgit v1.2.3 From 35cb8ff89e1c1871e7ad3383b524b2ebf82dfa3e Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Wed, 27 Jul 2016 19:32:46 +0200 Subject: LineEdit: Fix event handled as text when a mod key is pressed --- scene/gui/line_edit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 89c235e101..fcea12fd6b 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -468,7 +468,7 @@ void LineEdit::_input_event(InputEvent p_event) { if (handled) { accept_event(); - } else { + } else if (!k.mod.alt && !k.mod.command) { if (k.unicode>=32 && k.scancode!=KEY_DELETE) { if (editable) { -- cgit v1.2.3 From 0bc589a0c7a12c80f4e365724586174e2e7c9dbd Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 27 Jul 2016 15:35:49 -0300 Subject: Fix Windows resource script --- platform/windows/godot_res.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index c1754afa8c..b86869d316 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -23,8 +23,8 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Godot Engine" - VALUE "FileDescription", _MKSTR(VERSION_NAME) " Editor (" _MKSTR(VERSION_STATUS) ")" - VALUE "FileVersion", _MKSTR(VERSION_MAJOR),_MKSTR(VERSION_MINOR),_MKSTR(VERSION_PATCH) + VALUE "FileDescription", _MKSTR(VERSION_NAME) " Editor" + VALUE "FileVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) VALUE "ProductName", _MKSTR(VERSION_NAME) VALUE "Licence", "MIT" VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur" -- cgit v1.2.3 From 2d4c4b6ea9947607227e55682d195ebd05d383c6 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Thu, 28 Jul 2016 14:41:15 +0200 Subject: Fix regression with str() improvements for math types --- core/math/math_2d.cpp | 2 +- core/math/math_2d.h | 8 ++++---- core/math/matrix3.cpp | 13 +++---------- core/math/quat.cpp | 2 +- core/math/vector3.cpp | 2 +- core/variant.cpp | 40 ++++++++++++++++++++++++++++++++++------ 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index cf01e972a4..0e2060008c 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -658,5 +658,5 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons Matrix32::operator String() const { - return "("+String(String()+elements[0]+", "+elements[1]+", "+elements[2])+")"; + return String(String()+elements[0]+", "+elements[1]+", "+elements[2]); } diff --git a/core/math/math_2d.h b/core/math/math_2d.h index 5f511c933e..fbf700fb9c 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -157,7 +157,7 @@ struct Vector2 { float get_aspect() const { return width/height; } - operator String() const { return "("+String::num(x)+", "+String::num(y)+")"; } + operator String() const { return String::num(x)+", "+String::num(y); } _FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; } _FORCE_INLINE_ Vector2() { x=0; y=0; } @@ -356,7 +356,7 @@ struct Rect2 { } - operator String() const { return "("+String(pos)+", "+String(size)+")"; } + operator String() const { return String(pos)+", "+String(size); } Rect2() {} Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); } @@ -409,7 +409,7 @@ struct Point2i { float get_aspect() const { return width/(float)height; } - operator String() const { return "("+String::num(x)+", "+String::num(y)+")"; } + operator String() const { return String::num(x)+", "+String::num(y); } operator Vector2() const { return Vector2(x,y); } inline Point2i(const Vector2& p_vec2) { x=(int)p_vec2.x; y=(int)p_vec2.y; } @@ -540,7 +540,7 @@ struct Rect2i { } - operator String() const { return "("+String(pos)+", "+String(size)+")"; } + operator String() const { return String(pos)+", "+String(size); } operator Rect2() const { return Rect2(pos,size); } Rect2i(const Rect2& p_r2) { pos=p_r2.pos; size=p_r2.size; } diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 7b811c245c..71e6b62212 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -233,26 +233,19 @@ bool Matrix3::operator!=(const Matrix3& p_matrix) const { Matrix3::operator String() const { - String mtx("("); + String mtx; for (int i=0;i<3;i++) { - if (i!=0) - mtx+=", "; - - mtx+="("; - for (int j=0;j<3;j++) { - if (j!=0) + if (i!=0 || j!=0) mtx+=", "; mtx+=rtos( elements[i][j] ); } - - mtx+=")"; } - return mtx+")"; + return mtx; } Matrix3::operator Quat() const { diff --git a/core/math/quat.cpp b/core/math/quat.cpp index 5457638ada..73124e5e8e 100644 --- a/core/math/quat.cpp +++ b/core/math/quat.cpp @@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const Quat::operator String() const { - return "("+String::num(x)+", "+String::num(y)+", "+ String::num(z)+", "+ String::num(w)+")"; + return String::num(x)+", "+String::num(y)+", "+ String::num(z)+", "+ String::num(w); } Quat::Quat(const Vector3& axis, const real_t& angle) { diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 8a0a6e963d..8afd73f482 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -182,5 +182,5 @@ Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, co # endif Vector3::operator String() const { - return "("+(rtos(x)+", "+rtos(y)+", "+rtos(z))+")"; + return (rtos(x)+", "+rtos(y)+", "+rtos(z)); } diff --git a/core/variant.cpp b/core/variant.cpp index 31321dc0f3..a78c07d819 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1515,15 +1515,43 @@ Variant::operator String() const { case INT: return String::num(_data._int); case REAL: return String::num(_data._real); case STRING: return *reinterpret_cast(_data._mem); - case VECTOR2: return operator Vector2(); - case RECT2: return operator Rect2(); - case MATRIX32: return operator Matrix32(); - case VECTOR3: return operator Vector3(); + case VECTOR2: return "("+operator Vector2()+")"; + case RECT2: return "("+operator Rect2()+")"; + case MATRIX32: { + + Matrix32 mat32 = operator Matrix32(); + return "("+Variant(mat32.elements[0]).operator String()+", "+Variant(mat32.elements[1]).operator String()+", "+Variant(mat32.elements[2]).operator String()+")"; + } break; + case VECTOR3: return "("+operator Vector3()+")"; case PLANE: return operator Plane(); //case QUAT: case _AABB: return operator AABB(); - case QUAT: return operator Quat(); - case MATRIX3: return operator Matrix3(); + case QUAT: return "("+operator Quat()+")"; + case MATRIX3: { + + Matrix3 mat3 = operator Matrix3(); + + String mtx("("); + for (int i=0;i<3;i++) { + + if (i!=0) + mtx+=", "; + + mtx+="("; + + for (int j=0;j<3;j++) { + + if (j!=0) + mtx+=", "; + + mtx+=Variant( mat3.elements[i][j] ).operator String(); + } + + mtx+=")"; + } + + return mtx+")"; + } break; case TRANSFORM: return operator Transform(); case NODE_PATH: return operator NodePath(); case INPUT_EVENT: return operator InputEvent(); -- cgit v1.2.3 From 740dea7de7ca9df8034076ee2c83fe7c0203b087 Mon Sep 17 00:00:00 2001 From: Paulb23 Date: Thu, 28 Jul 2016 15:47:47 +0100 Subject: Exposed enable syntax highlighting to properties --- scene/gui/text_edit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index af04fbd201..b265ef840a 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4508,6 +4508,7 @@ void TextEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("menu_option"),&TextEdit::menu_option); ObjectTypeDB::bind_method(_MD("get_menu:PopupMenu"),&TextEdit::get_menu); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), _SCS("set_syntax_coloring"), _SCS("is_syntax_coloring_enabled")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), _SCS("set_show_line_numbers"), _SCS("is_show_line_numbers_enabled")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), _SCS("set_highlight_all_occurrences"), _SCS("is_highlight_all_occurrences_enabled")); -- cgit v1.2.3 From 08ba6086be75aac58748417808fed5462608f498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 28 Jul 2016 19:03:32 +0200 Subject: World2D: Fix typo in default_density deprecation check --- scene/resources/world_2d.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 6b329a1a73..4c963da5b4 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -407,7 +407,7 @@ World2D::World2D() { Physics2DServer::get_singleton()->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY,GLOBAL_DEF("physics_2d/default_gravity",98)); Physics2DServer::get_singleton()->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY_VECTOR,GLOBAL_DEF("physics_2d/default_gravity_vector",Vector2(0,1))); // TODO: Remove this deprecation warning and compatibility code for 2.2 or 3.0 - if (Globals::get_singleton()->get("physics_2d/default_density") && !Globals::get_singleton()->get("physics_2d/default_linear_damp)")) { + if (Globals::get_singleton()->get("physics_2d/default_density") && !Globals::get_singleton()->get("physics_2d/default_linear_damp")) { WARN_PRINT("Deprecated parameter 'physics_2d/default_density'. It was renamed to 'physics_2d/default_linear_damp', adjusting your project settings accordingly (make sure to adjust scripts that potentially rely on 'physics_2d/default_density'."); Globals::get_singleton()->set("physics_2d/default_linear_damp", Globals::get_singleton()->get("physics_2d/default_density")); Globals::get_singleton()->set_persisting("physics_2d/default_linear_damp", true); -- cgit v1.2.3 From 3cdb5e0d1fff7a4d4b1dc1dcca4d024192df13d2 Mon Sep 17 00:00:00 2001 From: George Marques Date: Thu, 28 Jul 2016 21:23:05 -0300 Subject: Fix editor icons source file generation Also removes the unused make_icons.py file. --- tools/editor/icons/SCsub | 5 +---- tools/editor/icons/make_icons.py | 48 ---------------------------------------- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 tools/editor/icons/make_icons.py diff --git a/tools/editor/icons/SCsub b/tools/editor/icons/SCsub index f2f5dcca48..bc104294cb 100644 --- a/tools/editor/icons/SCsub +++ b/tools/editor/icons/SCsub @@ -37,12 +37,9 @@ def make_editor_icons_action(target, source, env): pngf.close(); var_str=os.path.basename(x)[:-4]+"_hidpi_png"; -#print("TRY OPEN: "+os.path.dirname(x)+"/2x/"+os.path.basename(x)+"\n") try: - pngf = open(os.path.dirname(x)+"/2x/"+os.path.basename(x)) - - #print(var_str) + pngf = open(os.path.dirname(x)+"/2x/"+os.path.basename(x), "rb") s.write("static const unsigned char "+ var_str +"[]={\n"); diff --git a/tools/editor/icons/make_icons.py b/tools/editor/icons/make_icons.py deleted file mode 100644 index e06cbac720..0000000000 --- a/tools/editor/icons/make_icons.py +++ /dev/null @@ -1,48 +0,0 @@ - -import glob - -pixmaps = glob.glob("*.png") - -f = open("../editor_icons.cpp","wb") - - -f.write("#include \"editor_icons.h\"\n\n") -f.write("#include \"scene/resources/theme.h\"\n\n") - -for x in pixmaps: - - var_str=x[:-4]+"_png"; - - f.write("static const unsigned char "+ var_str +"[]={\n"); - - pngf=open(x,"rb"); - - b=pngf.read(1); - while(len(b)==1): - f.write(hex(ord(b))) - b=pngf.read(1); - if (len(b)==1): - f.write(",") - - f.write("\n};\n\n\n"); - pngf.close(); - -f.write("static Ref make_icon(const uint8_t* p_png) {\n") -f.write("\tRef texture( memnew( ImageTexture ) );\n") -f.write("\ttexture->create_from_image( Image(p_png),ImageTexture::FLAG_FILTER );\n") -f.write("\treturn texture;\n") -f.write("}\n\n") - -f.write("void editor_register_icons(Ref p_theme) {\n\n") - - -for x in pixmaps: - - type=x[5:-4].title().replace("_",""); - var_str=x[:-4]+"_png"; - f.write("\tp_theme->set_icon(\""+type+"\",\"EditorIcons\",make_icon("+var_str+"));\n"); - -f.write("\n\n}\n\n"); -f.close() - - -- cgit v1.2.3 From 283530a70ba4c1a325dbd143f0c55e89b22f68df Mon Sep 17 00:00:00 2001 From: Dima Granetchi Date: Fri, 29 Jul 2016 03:33:59 +0300 Subject: keep selected_list up to date --- tools/editor/project_manager.cpp | 56 ++++++++++++++++++++++++---------------- tools/editor/project_manager.h | 1 + 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index dd634e51ee..9ca69935da 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -510,6 +510,27 @@ void ProjectManager::_panel_draw(Node *p_hb) { } } +void ProjectManager::_update_project_buttons() +{ + String single_selected = ""; + if (selected_list.size() == 1) { + single_selected = selected_list.front()->key(); + } + + single_selected_main = ""; + for(int i=0;iget_child_count();i++) { + CanvasItem *item = scroll_childs->get_child(i)->cast_to(); + item->update(); + + if (single_selected!="" && single_selected == item->get_meta("name")) + single_selected_main = item->get_meta("main_scene"); + } + + erase_btn->set_disabled(selected_list.size()<1); + open_btn->set_disabled(selected_list.size()<1); + run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); +} + void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { @@ -557,23 +578,7 @@ void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { } } - String single_selected = ""; - if (selected_list.size() == 1) { - single_selected = selected_list.front()->key(); - } - - single_selected_main = ""; - for(int i=0;iget_child_count();i++) { - CanvasItem *item = scroll_childs->get_child(i)->cast_to(); - item->update(); - - if (single_selected!="" && single_selected == item->get_meta("name")) - single_selected_main = item->get_meta("main_scene"); - } - - erase_btn->set_disabled(selected_list.size()<1); - open_btn->set_disabled(selected_list.size()<1); - run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); + _update_project_buttons(); if (p_ev.mouse_button.doubleclick) _open_project(); //open if doubleclicked @@ -739,6 +744,8 @@ void ProjectManager::_load_recent_projects() { memdelete( scroll_childs->get_child(0)); } + Map selected_list_copy = selected_list; + List properties; EditorSettings::get_singleton()->get_property_list(&properties); @@ -845,6 +852,8 @@ void ProjectManager::_load_recent_projects() { main_scene = cf->get_value("application","main_scene"); } + selected_list_copy.erase(project); + HBoxContainer *hb = memnew( HBoxContainer ); hb->set_meta("name",project); hb->set_meta("main_scene",main_scene); @@ -882,12 +891,15 @@ void ProjectManager::_load_recent_projects() { scroll_childs->add_child(hb); } - + + for (Map::Element *E = selected_list_copy.front();E;E = E->next()) { + String key = E->key(); + selected_list.erase(key); + } + scroll->set_v_scroll(0); - - erase_btn->set_disabled(selected_list.size()<1); - open_btn->set_disabled(selected_list.size()<1); - run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); + + _update_project_buttons(); EditorSettings::get_singleton()->save(); diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index 74d1d3693c..fac1fc7745 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -82,6 +82,7 @@ class ProjectManager : public Control { void _new_project(); void _erase_project(); void _erase_project_confirm(); + void _update_project_buttons(); void _exit_dialog(); void _scan_begin(const String& p_base); -- cgit v1.2.3 From 12ddc8703296abc5f1e88d9467f0ec0070fef103 Mon Sep 17 00:00:00 2001 From: "Daniel J. Ramirez" Date: Sun, 24 Jul 2016 11:41:03 -0500 Subject: New http request and tutorials icon Remove garbage in group icon --- tools/editor/icons/2x/icon_godot.png | Bin 1545 -> 1842 bytes tools/editor/icons/2x/icon_h_t_t_p_request.png | Bin 180 -> 425 bytes tools/editor/icons/icon_godot.png | Bin 695 -> 769 bytes tools/editor/icons/icon_h_t_t_p_request.png | Bin 154 -> 301 bytes tools/editor/icons/source/icon_godot.svg | 28 +- tools/editor/icons/source/icon_group.svg | 1005 +------------------- tools/editor/icons/source/icon_h_t_t_p_request.svg | 78 +- 7 files changed, 77 insertions(+), 1034 deletions(-) diff --git a/tools/editor/icons/2x/icon_godot.png b/tools/editor/icons/2x/icon_godot.png index f789c791bd..94d87e23cc 100644 Binary files a/tools/editor/icons/2x/icon_godot.png and b/tools/editor/icons/2x/icon_godot.png differ diff --git a/tools/editor/icons/2x/icon_h_t_t_p_request.png b/tools/editor/icons/2x/icon_h_t_t_p_request.png index e3f7568ea1..a334dea4e2 100644 Binary files a/tools/editor/icons/2x/icon_h_t_t_p_request.png and b/tools/editor/icons/2x/icon_h_t_t_p_request.png differ diff --git a/tools/editor/icons/icon_godot.png b/tools/editor/icons/icon_godot.png index a033ab48a8..0b72e6ecc7 100644 Binary files a/tools/editor/icons/icon_godot.png and b/tools/editor/icons/icon_godot.png differ diff --git a/tools/editor/icons/icon_h_t_t_p_request.png b/tools/editor/icons/icon_h_t_t_p_request.png index c00854a414..60c6845b33 100644 Binary files a/tools/editor/icons/icon_h_t_t_p_request.png and b/tools/editor/icons/icon_h_t_t_p_request.png differ diff --git a/tools/editor/icons/source/icon_godot.svg b/tools/editor/icons/source/icon_godot.svg index 927c3ee053..419f23125b 100644 --- a/tools/editor/icons/source/icon_godot.svg +++ b/tools/editor/icons/source/icon_godot.svg @@ -28,12 +28,12 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="22.627417" - inkscape:cx="4.9021021" - inkscape:cy="11.249083" + inkscape:zoom="32" + inkscape:cx="9.8470361" + inkscape:cy="9.8599985" inkscape:document-units="px" inkscape:current-layer="layer1" - showgrid="true" + showgrid="false" units="px" inkscape:snap-bbox="true" inkscape:bbox-paths="true" @@ -59,7 +59,7 @@ image/svg+xml - + @@ -146,5 +146,23 @@ + + + diff --git a/tools/editor/icons/source/icon_group.svg b/tools/editor/icons/source/icon_group.svg index c8d20af9dd..a0a2f02af5 100644 --- a/tools/editor/icons/source/icon_group.svg +++ b/tools/editor/icons/source/icon_group.svg @@ -28,9 +28,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="22.627417" - inkscape:cx="10.459761" - inkscape:cy="9.5219725" + inkscape:zoom="5.6568543" + inkscape:cx="14.789684" + inkscape:cy="26.718572" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -78,1005 +78,6 @@ d="M 7 1 L 7 3 L 7 7 L 3 7 C 3 6.9999766 2.554 7 2 7 C 1.446 7 1 6.9999766 1 7 L 1 9 L 1 13 C 1 13.000023 1.446 13 2 13 C 2.554 13 3 13.000023 3 13 L 3 9 L 7 9 L 7 13 L 3 13 C 2.9999766 13 3 13.446 3 14 C 3 14.554 2.9999766 15 3 15 L 7 15 C 7 15.000023 7.446 15 8 15 C 8.554 15 9 15.000023 9 15 L 9 13 L 9 9 L 13 9 C 13 9.0000234 13.446 9 14 9 C 14.554 9 15 9.0000234 15 9 L 15 7 L 15 3 C 15 2.9999766 14.554 3 14 3 C 13.446 3 13 2.9999766 13 3 L 13 7 L 9 7 L 9 3 L 13 3 C 13.000023 3 13 2.554 13 2 C 13 1.446 13.000023 1 13 1 L 9 1 C 9 0.99997659 8.554 1 8 1 C 7.446 1 7 0.99997659 7 1 z " id="rect4697" transform="translate(0,1036.3622)" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -28,9 +28,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="45.254836" - inkscape:cx="10.430372" - inkscape:cy="8.7048298" + inkscape:zoom="32.000001" + inkscape:cx="14.357316" + inkscape:cy="9.4289864" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -59,7 +59,7 @@ image/svg+xml - + @@ -73,18 +73,18 @@ id="rect4200" width="1" height="5" - x="0" - y="1042.3622" /> + x="1" + y="1046.3622" /> + x="6" + y="1046.3622" /> + x="9" + y="1046.3622" /> + x="13" + y="1046.3622" /> + x="15" + y="1046.3622" /> + x="13" + y="1048.3622" /> + + + + -- cgit v1.2.3 From 5035edb7fdff85749ab5640b9a7fda91b9d39012 Mon Sep 17 00:00:00 2001 From: Saracen Date: Fri, 29 Jul 2016 13:50:26 +0100 Subject: Explicitly initialize 'pending_auto_reload' to false. --- tools/editor/plugins/script_editor_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 4032a790d8..be4b002d89 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -2749,6 +2749,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { completion_cache = memnew( EditorScriptCodeCompletionCache ); restoring_layout=false; waiting_update_names=false; + pending_auto_reload=false; auto_reload_running_scripts=false; editor=p_editor; -- cgit v1.2.3 From 9720e73e0480e454b580afc9499240bb08a823f3 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Fri, 29 Jul 2016 17:06:37 +0200 Subject: Project Manager: Import projects using filesystem drag'n'drop. Can drop an engine.cfg file over the window to import it ;) --- tools/editor/project_manager.cpp | 17 +++++++++++++++++ tools/editor/project_manager.h | 1 + 2 files changed, 18 insertions(+) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 9ca69935da..28d9738fee 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -364,6 +364,12 @@ public: mode=p_mode; } + void import_from_file(const String& p_file) { + mode=MODE_IMPORT; + _file_selected(p_file); + ok_pressed(); + } + void show_dialog() { @@ -1097,6 +1103,14 @@ void ProjectManager::_install_project(const String& p_zip_path,const String& p_t npdialog->show_dialog(); } +void ProjectManager::_files_dropped(StringArray p_files, int p_screen) { + for (int i = 0; i < p_files.size(); i++) { + if (p_files[i].ends_with("engine.cfg")) { + npdialog->import_from_file(p_files[i]); + } + } +} + void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_open_project",&ProjectManager::_open_project); @@ -1116,6 +1130,7 @@ void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_unhandled_input",&ProjectManager::_unhandled_input); ObjectTypeDB::bind_method("_favorite_pressed",&ProjectManager::_favorite_pressed); ObjectTypeDB::bind_method("_install_project",&ProjectManager::_install_project); + ObjectTypeDB::bind_method("_files_dropped",&ProjectManager::_files_dropped); } @@ -1330,6 +1345,8 @@ ProjectManager::ProjectManager() { //get_ok()->set_text("Exit"); last_clicked = ""; + + SceneTree::get_singleton()->connect("files_dropped", this, "_files_dropped"); } diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index fac1fc7745..50bd7d94c8 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -95,6 +95,7 @@ class ProjectManager : public Control { void _panel_input(const InputEvent& p_ev,Node *p_hb); void _unhandled_input(const InputEvent& p_ev); void _favorite_pressed(Node *p_hb); + void _files_dropped(StringArray p_files, int p_screen); protected: -- cgit v1.2.3 From 6e137c02d26df269c9860ac69e9d8824e4b5336b Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Sat, 30 Jul 2016 01:11:02 +0200 Subject: Fix infinite loop when replacing text --- tools/editor/code_editor.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index ed7a46d70d..d2bf070f1b 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -188,7 +188,9 @@ void FindReplaceBar::_replace_all() { text_edit->cursor_set_line(0); text_edit->cursor_set_column(0); + String replace_text=get_replace_text(); int search_text_len=get_search_text().length(); + int rc=0; replace_all_mode = true; @@ -204,7 +206,7 @@ void FindReplaceBar::_replace_all() { if (match_from < prev_match) break; // done - prev_match=match_to; + prev_match=Point2i(result_line,result_col+replace_text.length()); text_edit->select(result_line,result_col,result_line,match_to.y); @@ -214,12 +216,12 @@ void FindReplaceBar::_replace_all() { continue; // replace but adjust selection bounds - text_edit->insert_text_at_cursor(get_replace_text()); + text_edit->insert_text_at_cursor(replace_text); if (match_to.x==selection_end.x) - selection_end.y+=get_replace_text().length() - get_search_text().length(); + selection_end.y+=replace_text.length()-search_text_len; } else { // just replace - text_edit->insert_text_at_cursor(get_replace_text()); + text_edit->insert_text_at_cursor(replace_text); } rc++; -- cgit v1.2.3 From 4755fe5576b05c94081bdcad5bd37523d5040150 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Sat, 30 Jul 2016 12:38:42 +0200 Subject: UI navigation via JOYSTICK_MOTION. Previously, you could assign joystick axis events to "ui_*" actions but they had no effect. See https://godotengine.org/qa/6232 --- scene/main/viewport.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f182f2c96c..7970229c06 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2095,6 +2095,7 @@ void Viewport::_gui_input_event(InputEvent p_event) { } break; case InputEvent::ACTION: case InputEvent::JOYSTICK_BUTTON: + case InputEvent::JOYSTICK_MOTION: case InputEvent::KEY: { -- cgit v1.2.3 From 09c4d65b64892f945aeb98a4abcedab42126c248 Mon Sep 17 00:00:00 2001 From: allkhor Date: Sun, 31 Jul 2016 00:18:30 +0600 Subject: Fix String::is_valid_integer() for single symbols + and - --- core/ustring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ustring.cpp b/core/ustring.cpp index 6788ada1bb..0d887210c3 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3491,7 +3491,7 @@ bool String::is_valid_integer() const { return false; int from=0; - if (operator[](0)=='+' || operator[](0)=='-') + if (len!=1 && (operator[](0)=='+' || operator[](0)=='-')) from++; for(int i=from;i Date: Sat, 30 Jul 2016 20:41:38 +0200 Subject: Document FuncRef, GDFunctionState, InstancePlaceholder, RID, World2D --- core/func_ref.cpp | 2 +- doc/base/classes.xml | 28 ++++++++++++++++++++++++++-- modules/gdscript/gd_editor.cpp | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 29b06ae9a0..644d8b5b63 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -65,7 +65,7 @@ void FuncRef::_bind_methods() { mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); defargs.push_back(Variant()); } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func",&FuncRef::call_func,mi,defargs); + ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs); } diff --git a/doc/base/classes.xml b/doc/base/classes.xml index dc24231dd0..b7b0502eaa 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -660,7 +660,7 @@ - Stop the function execution and return the current state. Call resume on the state to resume execution. This makes the state invalid. + Stop the function execution and return the current state. Call [method GDFunctionState.resume] on the state to resume execution. This invalidates the state. Returns anything that was passed to the resume function call. If passed an object and a signal, the execution is resumed when the object's signal is emmited. @@ -13042,8 +13042,11 @@ + Reference to a function in an object. + In GDScript, functions are not [i]first-class objects[/i]. This means it is impossible to store them directly as variables, return them from another function, or pass them as arguments. + However, by creating a [FuncRef] using the [method @GDScript.funcref] function, a reference to a function in a given object can be created, passed around and called. @@ -13068,18 +13071,21 @@ + Call the referenced function with the given arguments. The argument count must correspond to the required number of arguments in the function. Returns the return value of the function call. + Set the name of the function to call on the object, without parentheses or any parameters. + Set the object on which to call the referenced function. This object must be of a type actually inheriting from [Object], not a built-in type such as [int], [Vector2] or [Dictionary]. @@ -13088,15 +13094,17 @@ + State of a function call after yielding. + Calling [method @GDScript.yield] within a function will cause that function to yield and return its current state as an object of this type. The yielded function call can then be resumed later by calling [method resume] on this state object. - Should put children to the top left corner instead of center of the container. + Check whether the function call may be resumed. This is not the case if the function state was already resumed. @@ -13105,6 +13113,9 @@ + Resume execution of the yielded function call. + If handed an argument, return the argument from the [method @GDScript.yield] call in the yielded function call. You can pass e.g. an [Array] to hand multiple arguments. + This function returns what the resumed function call returns, possibly another function state if yielded again. @@ -17235,20 +17246,25 @@ + Placeholder for the root [Node] of a [PackedScene]. + Turning on the option [b]Load As Placeholder[/b] for an instanced scene in the editor causes it to be replaced by an InstacePlaceholder when running the game. This makes it possible to delay actually loading the scene until calling [method replace_by_instance]. This is useful to avoid loading large scenes all at once by loading parts of it selectively. + The InstancePlaceholder does not have a transform. This causes any child nodes to be positioned relatively to the Viewport from point (0,0), rather than their parent as displayed in the editor. Replacing the placeholder with a scene with a transform will transform children relatively to their parent again. + Retrieve the path to the [PackedScene] resource file that is loaded by default when calling [method replace_by_instance]. + Replace this placeholder by the scene handed as an argument, or the original scene if no argument is given. As for all resources, the scene is loaded only if it's not loaded already. By manually loading the scene beforehand, delays caused by this function can be avoided. @@ -30280,8 +30296,10 @@ + Handle for a [Resource]'s unique ID. + The RID type is used to access the unique integer ID of a resource. They are opaque, so they do not grant access to the associated resource by themselves. They are used by and with the low-level Server classes such as [VisualServer]. @@ -30290,12 +30308,14 @@ + Create a new RID instance with the ID of a given resource. When not handed a valid resource, silently stores the unused ID 0. + Retrieve the ID of the referenced resource. @@ -46584,24 +46604,28 @@ + Retrieve the [RID] of this world's canvas resource. Used by the [VisualServer] for 2D drawing. + Retrieve the state of this world's physics space. This allows arbitrary querying for collision. + Retrieve the [RID] of this world's sound space resource. Used by the [SpatialSound2DServer] for 2D spatial audio. + Retrieve the [RID] of this world's physics space resource. Used by the [Physics2DServer] for 2D physics, treating it as both a space and an area. diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index 520a8b18d8..b02e55cf9d 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -297,7 +297,7 @@ void GDScriptLanguage::get_public_functions(List *p_functions) const } { MethodInfo mi; - mi.name="yield"; + mi.name="yield:GDFunctionState"; mi.arguments.push_back(PropertyInfo(Variant::OBJECT,"object")); mi.arguments.push_back(PropertyInfo(Variant::STRING,"signal")); mi.default_arguments.push_back(Variant::NIL); -- cgit v1.2.3 From a1c0fdac9a4ec1e8c2097b457a52e568f983c7d0 Mon Sep 17 00:00:00 2001 From: Dima Granetchi Date: Sun, 31 Jul 2016 01:04:16 +0300 Subject: fix run button availability check --- tools/editor/project_manager.cpp | 21 ++++++++++----------- tools/editor/project_manager.h | 3 --- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 28d9738fee..f885fbba07 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -518,23 +518,23 @@ void ProjectManager::_panel_draw(Node *p_hb) { void ProjectManager::_update_project_buttons() { - String single_selected = ""; - if (selected_list.size() == 1) { - single_selected = selected_list.front()->key(); - } - - single_selected_main = ""; for(int i=0;iget_child_count();i++) { + CanvasItem *item = scroll_childs->get_child(i)->cast_to(); item->update(); - - if (single_selected!="" && single_selected == item->get_meta("name")) - single_selected_main = item->get_meta("main_scene"); + } + + bool has_runnable_scene = false; + for (Map::Element *E=selected_list.front(); E; E=E->next()) { + const String &selected_main = E->get(); + if (selected_main == "") continue; + has_runnable_scene = true; + break; } erase_btn->set_disabled(selected_list.size()<1); open_btn->set_disabled(selected_list.size()<1); - run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); + run_btn->set_disabled(!has_runnable_scene); } void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { @@ -1072,7 +1072,6 @@ void ProjectManager::_erase_project_confirm() { EditorSettings::get_singleton()->save(); selected_list.clear(); last_clicked = ""; - single_selected_main=""; _load_recent_projects(); } diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index 50bd7d94c8..da57033905 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -60,7 +60,6 @@ class ProjectManager : public Control { VBoxContainer *scroll_childs; Map selected_list; // name -> main_scene String last_clicked; - String single_selected_main; bool importing; HBoxContainer *projects_hb; @@ -69,8 +68,6 @@ class ProjectManager : public Control { Control *gui_base; - void _item_doubleclicked(); - void _scan_projects(); -- cgit v1.2.3 From 5e011dcd0e4958f6bc59f64e024402af1ad1dc0d Mon Sep 17 00:00:00 2001 From: Dima Granetchi Date: Sun, 31 Jul 2016 01:10:13 +0300 Subject: dnd folder open scan window if engine.cfg not found --- tools/editor/project_manager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 28d9738fee..20544d2f05 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -1104,11 +1104,17 @@ void ProjectManager::_install_project(const String& p_zip_path,const String& p_t } void ProjectManager::_files_dropped(StringArray p_files, int p_screen) { + bool import_project_file = false; for (int i = 0; i < p_files.size(); i++) { if (p_files[i].ends_with("engine.cfg")) { npdialog->import_from_file(p_files[i]); + import_project_file = true; } } + if (!import_project_file && p_files.size() > 0) { + scan_dir->set_current_dir(p_files[0]); + scan_dir->popup_centered_ratio(); + } } void ProjectManager::_bind_methods() { -- cgit v1.2.3 From 0b595f94c47a9144dbe9c200a8057558b0c4f839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sun, 31 Jul 2016 20:46:00 +0200 Subject: Improve dialog title when scanning for projects --- tools/editor/project_manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index daba5c9eba..90e655f116 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -1270,6 +1270,7 @@ ProjectManager::ProjectManager() { scan_dir = memnew( FileDialog ); scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM); scan_dir->set_mode(FileDialog::MODE_OPEN_DIR); + scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden scan_dir->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_path") ); gui_base->add_child(scan_dir); scan_dir->connect("dir_selected",this,"_scan_begin"); -- cgit v1.2.3 From ae1267d41cf15d9a5b40a4d2525f2cb151f6b17d Mon Sep 17 00:00:00 2001 From: Mario Schlack Date: Mon, 1 Aug 2016 16:30:09 +0800 Subject: Fix help page title indentation --- tools/editor/editor_help.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 1fc157098c..4ab86ad512 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -943,10 +943,9 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { class_desc->add_newline(); } - class_desc->add_newline(); - class_desc->pop(); - + class_desc->pop(); + class_desc->add_newline(); } if (cd.theme_properties.size()) { @@ -987,11 +986,10 @@ Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { class_desc->add_newline(); } - class_desc->add_newline(); class_desc->pop(); - - + class_desc->add_newline(); } + if (cd.signals.size()) { if (sort_methods) { -- cgit v1.2.3 From d7910f44d89e941772e1f54ffdc17d162795ba4a Mon Sep 17 00:00:00 2001 From: Paulb23 Date: Sun, 12 Jun 2016 16:47:29 +0100 Subject: Added Scene tree dock shortcuts --- tools/editor/scene_tree_dock.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 35ddb49465..9e2b2266a5 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -48,11 +48,9 @@ void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { if (get_viewport()->get_modal_stack_top()) return; //ignore because of modal window - uint32_t sc = p_event.key.get_scancode_with_modifiers(); if (!p_event.key.pressed || p_event.key.echo) return; - if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) { _tool_selected(TOOL_NEW); } @@ -83,9 +81,11 @@ void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) { _tool_selected(TOOL_NEW_SCENE_FROM); } - switch(sc) { - case KEY_MASK_SHIFT|KEY_DELETE: { _tool_selected(TOOL_ERASE, true); } break; - case KEY_DELETE: { _tool_selected(TOOL_ERASE); } break; + else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) { + _tool_selected(TOOL_ERASE, true); + } + else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) { + _tool_selected(TOOL_ERASE); } } @@ -1769,7 +1769,7 @@ void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { } menu->add_separator(); - menu->add_icon_item(get_icon("Remove","EditorIcons"),TTR("Delete Node(s)"), TOOL_ERASE, KEY_DELETE); + menu->add_icon_shortcut(get_icon("Remove","EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE); menu->set_size(Size2(1,1)); menu->set_pos(p_menu_pos); @@ -1846,6 +1846,8 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); + ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT|KEY_DELETE); + ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE); tb = memnew( ToolButton ); tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW, false)); -- cgit v1.2.3 From bee20910569d89cf36b6601eca2c6322f2947943 Mon Sep 17 00:00:00 2001 From: Dima Granetchi Date: Mon, 1 Aug 2016 01:59:31 +0300 Subject: Auto import project folder, confirm scan multiple folders or non-project folder --- tools/editor/project_manager.cpp | 56 ++++++++++++++++++++++++++++++++++------ tools/editor/project_manager.h | 2 ++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 90e655f116..62b15d344d 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -1103,16 +1103,50 @@ void ProjectManager::_install_project(const String& p_zip_path,const String& p_t } void ProjectManager::_files_dropped(StringArray p_files, int p_screen) { - bool import_project_file = false; + Set folders_set; + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < p_files.size(); i++) { - if (p_files[i].ends_with("engine.cfg")) { - npdialog->import_from_file(p_files[i]); - import_project_file = true; + String file = p_files[i]; + folders_set.insert(da->dir_exists(file) ? file : file.get_base_dir()); + } + memdelete(da); + if (folders_set.size()>0) { + StringArray folders; + for (Set::Element *E=folders_set.front();E;E=E->next()) { + folders.append(E->get()); + } + + bool confirm = true; + if (folders.size()==1) { + DirAccess *dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (dir->change_dir(folders[0])==OK) { + dir->list_dir_begin(); + String file = dir->get_next(); + while(confirm && file!=String()) { + if (!da->current_is_dir() && file.ends_with("engine.cfg")) { + confirm = false; + } + file = dir->get_next(); + } + dir->list_dir_end(); + } + memdelete(dir); + } + if (confirm) { + multi_scan_ask->get_ok()->disconnect("pressed", this, "_scan_multiple_folders"); + multi_scan_ask->get_ok()->connect("pressed", this, "_scan_multiple_folders", varray(folders)); + multi_scan_ask->set_text(vformat(TTR("You are about the scan %s folders for existing Godot projects. Do you confirm?"), folders.size())); + multi_scan_ask->popup_centered_minsize(); + } else { + _scan_multiple_folders(folders); } } - if (!import_project_file && p_files.size() > 0) { - scan_dir->set_current_dir(p_files[0]); - scan_dir->popup_centered_ratio(); +} + +void ProjectManager::_scan_multiple_folders(StringArray p_files) +{ + for (int i = 0; i < p_files.size(); i++) { + _scan_begin(p_files.get(i)); } } @@ -1136,6 +1170,7 @@ void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_favorite_pressed",&ProjectManager::_favorite_pressed); ObjectTypeDB::bind_method("_install_project",&ProjectManager::_install_project); ObjectTypeDB::bind_method("_files_dropped",&ProjectManager::_files_dropped); + ObjectTypeDB::bind_method(_MD("_scan_multiple_folders", "files"),&ProjectManager::_scan_multiple_folders); } @@ -1332,8 +1367,13 @@ ProjectManager::ProjectManager() { multi_run_ask = memnew( ConfirmationDialog ); multi_run_ask->get_ok()->set_text(TTR("Run")); multi_run_ask->get_ok()->connect("pressed", this, "_run_project_confirm"); - + gui_base->add_child(multi_run_ask); + + multi_scan_ask = memnew( ConfirmationDialog ); + multi_scan_ask->get_ok()->set_text(TTR("Scan")); + + gui_base->add_child(multi_scan_ask); OS::get_singleton()->set_low_processor_usage_mode(true); diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index da57033905..46f7aea3a5 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -55,6 +55,7 @@ class ProjectManager : public Control { ConfirmationDialog *erase_ask; ConfirmationDialog *multi_open_ask; ConfirmationDialog *multi_run_ask; + ConfirmationDialog *multi_scan_ask; NewProjectDialog *npdialog; ScrollContainer *scroll; VBoxContainer *scroll_childs; @@ -93,6 +94,7 @@ class ProjectManager : public Control { void _unhandled_input(const InputEvent& p_ev); void _favorite_pressed(Node *p_hb); void _files_dropped(StringArray p_files, int p_screen); + void _scan_multiple_folders(StringArray p_files); protected: -- cgit v1.2.3 From 7b165e8ac27c8c6f979bf6e2da32a9a58836da08 Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Tue, 2 Aug 2016 08:01:51 +0100 Subject: Added texture mipmaps and filtering to DynamicFont --- scene/resources/dynamic_font.cpp | 80 ++++++++++++++++++++++++++++++++++++---- scene/resources/dynamic_font.h | 18 +++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 67587a8f8b..0c25bde7a9 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -32,7 +32,7 @@ -Ref DynamicFontData::_get_dynamic_font_at_size(int p_size) { +Ref DynamicFontData::_get_dynamic_font_at_size(int p_size, uint32_t p_texture_flags) { if (size_cache.has(p_size)) { @@ -48,6 +48,7 @@ Ref DynamicFontData::_get_dynamic_font_at_size(int p_size) { size_cache[p_size]=dfas.ptr(); + dfas->texture_flags=p_texture_flags; dfas->size=p_size; dfas->_load(); @@ -270,6 +271,15 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char,CharType p_next,const Vec return ret; } +void DynamicFontAtSize::set_texture_flags(uint32_t p_flags){ + + texture_flags=p_flags; + for(int i=0;i &tex = textures[i].texture; + if (!tex.is_null()) + tex->set_flags(p_flags); + } +} float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_char,CharType p_next,const Color& p_modulate,const Vector >& p_fallbacks) const { @@ -555,7 +565,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { if (tex.texture.is_null()) { tex.texture.instance(); - tex.texture->create_from_image(img,Texture::FLAG_VIDEO_SURFACE); + tex.texture->create_from_image(img,Texture::FLAG_VIDEO_SURFACE|texture_flags); } else { tex.texture->set_data(img); //update } @@ -595,6 +605,7 @@ DynamicFontAtSize::DynamicFontAtSize() { ascent=1; descent=1; linegap=1; + texture_flags=0; } DynamicFontAtSize::~DynamicFontAtSize(){ @@ -613,7 +624,7 @@ void DynamicFont::set_font_data(const Ref& p_data) { data=p_data; if (data.is_valid()) - data_at_size=data->_get_dynamic_font_at_size(size); + data_at_size=data->_get_dynamic_font_at_size(size,texture_flags); else data_at_size=Ref(); @@ -634,19 +645,64 @@ void DynamicFont::set_size(int p_size){ ERR_FAIL_COND(p_size<1); if (!data.is_valid()) return; - data_at_size=data->_get_dynamic_font_at_size(size); + data_at_size=data->_get_dynamic_font_at_size(size,texture_flags); for(int i=0;i_get_dynamic_font_at_size(size); + fallback_data_at_size[i]=fallbacks[i]->_get_dynamic_font_at_size(size,texture_flags); } emit_changed(); _change_notify(); } + int DynamicFont::get_size() const{ return size; } +void DynamicFont::_update_texture_flags(){ + + texture_flags = 0; + if (use_mipmaps) + texture_flags|=Texture::FLAG_MIPMAPS; + if (use_filter) + texture_flags|=Texture::FLAG_FILTER; + if (!data.is_valid()) + return; + data_at_size->set_texture_flags(texture_flags); + for(int i=0;iset_texture_flags(texture_flags); + } + + emit_changed(); + _change_notify(); +} + +bool DynamicFont::get_use_mipmaps() const{ + + return use_mipmaps; +} + +void DynamicFont::set_use_mipmaps(bool p_enable){ + + if (use_mipmaps==p_enable) + return; + use_mipmaps=p_enable; + _update_texture_flags(); +} + +bool DynamicFont::get_use_filter() const{ + + return use_filter; +} + +void DynamicFont::set_use_filter(bool p_enable){ + + if (use_filter==p_enable) + return; + use_filter=p_enable; + _update_texture_flags(); +} + float DynamicFont::get_height() const{ if (!data_at_size.is_valid()) @@ -699,7 +755,7 @@ void DynamicFont::set_fallback(int p_idx,const Ref& p_data) { ERR_FAIL_COND(p_data.is_null()); ERR_FAIL_INDEX(p_idx,fallbacks.size()); fallbacks[p_idx]=p_data; - fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(size); + fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(size,texture_flags); } @@ -707,7 +763,7 @@ void DynamicFont::add_fallback(const Ref& p_data) { ERR_FAIL_COND(p_data.is_null()); fallbacks.push_back(p_data); - fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(size)); //const.. + fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(size,texture_flags)); //const.. _change_notify(); emit_changed(); @@ -794,6 +850,11 @@ void DynamicFont::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_size","data"),&DynamicFont::set_size); ObjectTypeDB::bind_method(_MD("get_size"),&DynamicFont::get_size); + ObjectTypeDB::bind_method(_MD("set_use_mipmaps","enable"),&DynamicFont::set_use_mipmaps); + ObjectTypeDB::bind_method(_MD("get_use_mipmaps"),&DynamicFont::get_use_mipmaps); + ObjectTypeDB::bind_method(_MD("set_use_filter","enable"),&DynamicFont::set_use_filter); + ObjectTypeDB::bind_method(_MD("get_use_filter"),&DynamicFont::get_use_filter); + ObjectTypeDB::bind_method(_MD("add_fallback","data:DynamicFontData"),&DynamicFont::add_fallback); ObjectTypeDB::bind_method(_MD("set_fallback","idx","data:DynamicFontData"),&DynamicFont::set_fallback); ObjectTypeDB::bind_method(_MD("get_fallback:DynamicFontData","idx"),&DynamicFont::get_fallback); @@ -802,12 +863,17 @@ void DynamicFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT,"font/size"),_SCS("set_size"),_SCS("get_size")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_mipmaps"),_SCS("set_use_mipmaps"),_SCS("get_use_mipmaps")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_filter"),_SCS("set_use_filter"),_SCS("get_use_filter")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"font/font",PROPERTY_HINT_RESOURCE_TYPE,"DynamicFontData"),_SCS("set_font_data"),_SCS("get_font_data")); } DynamicFont::DynamicFont() { size=16; + use_mipmaps=false; + use_filter=false; + texture_flags=0; } DynamicFont::~DynamicFont() { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 9ad1b4edbf..c43dcd37f9 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -59,7 +59,7 @@ class DynamicFontData : public Resource { friend class DynamicFont; - Ref _get_dynamic_font_at_size(int p_size); + Ref _get_dynamic_font_at_size(int p_size, uint32_t p_texture_flags=0); protected: static void _bind_methods(); @@ -90,6 +90,8 @@ class DynamicFontAtSize : public Reference { int linegap; int rect_margin; + uint32_t texture_flags; + bool valid; struct CharTexture { @@ -145,7 +147,7 @@ public: float draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_char,CharType p_next,const Color& p_modulate,const Vector >& p_fallbacks) const; - + void set_texture_flags(uint32_t p_flags); DynamicFontAtSize(); ~DynamicFontAtSize(); @@ -157,7 +159,7 @@ class DynamicFont : public Font { OBJ_TYPE( DynamicFont, Font ); - Ref data; + Ref data; Ref data_at_size; Vector< Ref > fallbacks; @@ -166,9 +168,14 @@ class DynamicFont : public Font { int size; bool valid; + bool use_mipmaps; + bool use_filter; + uint32_t texture_flags; protected: + void _update_texture_flags(); + bool _set(const StringName& p_name, const Variant& p_value); bool _get(const StringName& p_name,Variant &r_ret) const; void _get_property_list( List *p_list) const; @@ -183,6 +190,11 @@ public: void set_size(int p_size); int get_size() const; + bool get_use_mipmaps() const; + void set_use_mipmaps(bool p_enable); + + bool get_use_filter() const; + void set_use_filter(bool p_enable); void add_fallback(const Ref& p_data); void set_fallback(int p_idx,const Ref& p_data); -- cgit v1.2.3 From af6ef01c692311410c084b0bf4f3fe2f4d46786d Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Tue, 2 Aug 2016 11:05:20 +0100 Subject: Added extra spacing support for DynamicFont Side effect is that label min-size will now take into account kerning. --- scene/gui/label.cpp | 4 +-- scene/resources/dynamic_font.cpp | 62 ++++++++++++++++++++++++++++++++++++---- scene/resources/dynamic_font.h | 18 ++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 4c025e92df..ec89b7b690 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -334,7 +334,7 @@ int Label::get_longest_line_width() const { } } else { - int char_width=font->get_char_size(current).width; + int char_width=font->get_char_size(current,text[i+1]).width; line_width+=char_width; } @@ -454,7 +454,7 @@ void Label::regenerate_word_cache() { word_pos=i; } - char_width=font->get_char_size(current).width; + char_width=font->get_char_size(current,text[i+1]).width; current_word_size+=char_width; line_width+=char_width; total_char_cache++; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 0c25bde7a9..0a3355e818 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -703,12 +703,43 @@ void DynamicFont::set_use_filter(bool p_enable){ _update_texture_flags(); } +int DynamicFont::get_spacing(int p_type) const{ + + if (p_type == SPACING_TOP){ + return spacing_top; + }else if (p_type == SPACING_BOTTOM){ + return spacing_bottom; + }else if (p_type == SPACING_CHAR){ + return spacing_char; + }else if (p_type == SPACING_SPACE){ + return spacing_space; + } + + return 0; +} + +void DynamicFont::set_spacing(int p_type, int p_value){ + + if (p_type == SPACING_TOP){ + spacing_top=p_value; + }else if (p_type == SPACING_BOTTOM){ + spacing_bottom=p_value; + }else if (p_type == SPACING_CHAR){ + spacing_char=p_value; + }else if (p_type == SPACING_SPACE){ + spacing_space=p_value; + } + + emit_changed(); + _change_notify(); +} + float DynamicFont::get_height() const{ if (!data_at_size.is_valid()) return 1; - return data_at_size->get_height(); + return data_at_size->get_height()+spacing_top+spacing_bottom; } float DynamicFont::get_ascent() const{ @@ -716,7 +747,7 @@ float DynamicFont::get_ascent() const{ if (!data_at_size.is_valid()) return 1; - return data_at_size->get_ascent(); + return data_at_size->get_ascent()+spacing_top; } float DynamicFont::get_descent() const{ @@ -724,7 +755,7 @@ float DynamicFont::get_descent() const{ if (!data_at_size.is_valid()) return 1; - return data_at_size->get_descent(); + return data_at_size->get_descent()+spacing_bottom; } @@ -733,7 +764,13 @@ Size2 DynamicFont::get_char_size(CharType p_char,CharType p_next) const{ if (!data_at_size.is_valid()) return Size2(1,1); - return data_at_size->get_char_size(p_char,p_next,fallback_data_at_size); + Size2 ret=data_at_size->get_char_size(p_char,p_next,fallback_data_at_size); + if (p_char==' ') + ret.width+=spacing_space+spacing_char; + else if (p_next) + ret.width+=spacing_char; + + return ret; } @@ -747,7 +784,7 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_ if (!data_at_size.is_valid()) return 0; - return data_at_size->draw_char(p_canvas_item,p_pos,p_char,p_next,p_modulate,fallback_data_at_size); + return data_at_size->draw_char(p_canvas_item,p_pos,p_char,p_next,p_modulate,fallback_data_at_size)+spacing_char; } void DynamicFont::set_fallback(int p_idx,const Ref& p_data) { @@ -854,6 +891,8 @@ void DynamicFont::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_use_mipmaps"),&DynamicFont::get_use_mipmaps); ObjectTypeDB::bind_method(_MD("set_use_filter","enable"),&DynamicFont::set_use_filter); ObjectTypeDB::bind_method(_MD("get_use_filter"),&DynamicFont::get_use_filter); + ObjectTypeDB::bind_method(_MD("set_spacing","type","value"),&DynamicFont::set_spacing); + ObjectTypeDB::bind_method(_MD("get_spacing","type"),&DynamicFont::get_spacing); ObjectTypeDB::bind_method(_MD("add_fallback","data:DynamicFontData"),&DynamicFont::add_fallback); ObjectTypeDB::bind_method(_MD("set_fallback","idx","data:DynamicFontData"),&DynamicFont::set_fallback); @@ -863,14 +902,27 @@ void DynamicFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT,"font/size"),_SCS("set_size"),_SCS("get_size")); + ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/top"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_TOP); + ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/bottom"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_BOTTOM); + ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/char"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_CHAR); + ADD_PROPERTYINZ(PropertyInfo(Variant::INT,"extra_spacing/space"),_SCS("set_spacing"),_SCS("get_spacing"),SPACING_SPACE); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_mipmaps"),_SCS("set_use_mipmaps"),_SCS("get_use_mipmaps")); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"font/use_filter"),_SCS("set_use_filter"),_SCS("get_use_filter")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"font/font",PROPERTY_HINT_RESOURCE_TYPE,"DynamicFontData"),_SCS("set_font_data"),_SCS("get_font_data")); + + BIND_CONSTANT( SPACING_TOP ); + BIND_CONSTANT( SPACING_BOTTOM ); + BIND_CONSTANT( SPACING_CHAR ); + BIND_CONSTANT( SPACING_SPACE ); } DynamicFont::DynamicFont() { size=16; + spacing_top=0; + spacing_bottom=0; + spacing_char=0; + spacing_space=0; use_mipmaps=false; use_filter=false; texture_flags=0; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index c43dcd37f9..899973f22f 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -159,6 +159,17 @@ class DynamicFont : public Font { OBJ_TYPE( DynamicFont, Font ); +public: + + enum SpacingType{ + SPACING_TOP, + SPACING_BOTTOM, + SPACING_CHAR, + SPACING_SPACE + }; + +private: + Ref data; Ref data_at_size; @@ -168,6 +179,10 @@ class DynamicFont : public Font { int size; bool valid; + int spacing_top; + int spacing_bottom; + int spacing_char; + int spacing_space; bool use_mipmaps; bool use_filter; uint32_t texture_flags; @@ -196,6 +211,9 @@ public: bool get_use_filter() const; void set_use_filter(bool p_enable); + int get_spacing(int p_type) const; + void set_spacing(int p_type, int p_value); + void add_fallback(const Ref& p_data); void set_fallback(int p_idx,const Ref& p_data); int get_fallback_count() const; -- cgit v1.2.3 From 0de7860511fe56f06d039c51ff463c7a1146b7e1 Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Tue, 2 Aug 2016 15:00:32 +0100 Subject: DynamicFont caches now accounts for texture flags CacheID added for future-proofing --- scene/resources/dynamic_font.cpp | 108 ++++++++++++++++++--------------------- scene/resources/dynamic_font.h | 26 ++++++---- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 0a3355e818..679c8a000c 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -30,13 +30,22 @@ #include "dynamic_font.h" #include "os/file_access.h" +bool DynamicFontData::CacheID::operator< (CacheID right) const{ + + if (size DynamicFontData::_get_dynamic_font_at_size(int p_size, uint32_t p_texture_flags) { +Ref DynamicFontData::_get_dynamic_font_at_size(CacheID p_id){ - if (size_cache.has(p_size)) { - return Ref( size_cache[p_size] ); + if (size_cache.has(p_id)) { + return Ref( size_cache[p_id] ); } @@ -46,10 +55,8 @@ Ref DynamicFontData::_get_dynamic_font_at_size(int p_size, ui dfas->font=Ref( this ); - size_cache[p_size]=dfas.ptr(); - - dfas->texture_flags=p_texture_flags; - dfas->size=p_size; + size_cache[p_id]=dfas.ptr(); + dfas->id=p_id; dfas->_load(); return dfas; @@ -170,11 +177,16 @@ Error DynamicFontAtSize::_load() { ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER ); }*/ - error = FT_Set_Pixel_Sizes(face,0,size); + error = FT_Set_Pixel_Sizes(face,0,id.size); ascent=face->size->metrics.ascender>>6; descent=-face->size->metrics.descender>>6; linegap=0; + texture_flags=0; + if (id.mipmaps) + texture_flags|=Texture::FLAG_MIPMAPS; + if (id.filter) + texture_flags|=Texture::FLAG_FILTER; //print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER)); @@ -506,7 +518,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { tex_x = 0; tex_y = 0; - int texsize = MAX(size*8,256); + int texsize = MAX(id.size*8,256); if (mw>texsize) texsize=mw; //special case, adapt to it? if (mh>texsize) @@ -612,19 +624,32 @@ DynamicFontAtSize::~DynamicFontAtSize(){ if (valid) { FT_Done_FreeType( library ); - font->size_cache.erase(size); + font->size_cache.erase(id); } } ///////////////////////// +void DynamicFont::_reload_cache(){ + + ERR_FAIL_COND(cache_id.size<1); + if (!data.is_valid()) + return; + data_at_size=data->_get_dynamic_font_at_size(cache_id); + for (int i=0;i_get_dynamic_font_at_size(cache_id); + } + + emit_changed(); + _change_notify(); +} void DynamicFont::set_font_data(const Ref& p_data) { data=p_data; if (data.is_valid()) - data_at_size=data->_get_dynamic_font_at_size(size,texture_flags); + data_at_size=data->_get_dynamic_font_at_size(cache_id); else data_at_size=Ref(); @@ -639,68 +664,41 @@ Ref DynamicFont::get_font_data() const{ void DynamicFont::set_size(int p_size){ - if (size==p_size) - return; - size=p_size; - ERR_FAIL_COND(p_size<1); - if (!data.is_valid()) + if (cache_id.size==p_size) return; - data_at_size=data->_get_dynamic_font_at_size(size,texture_flags); - for(int i=0;i_get_dynamic_font_at_size(size,texture_flags); - } - - emit_changed(); - _change_notify(); + cache_id.size=p_size; + _reload_cache(); } int DynamicFont::get_size() const{ - return size; -} - -void DynamicFont::_update_texture_flags(){ - - texture_flags = 0; - if (use_mipmaps) - texture_flags|=Texture::FLAG_MIPMAPS; - if (use_filter) - texture_flags|=Texture::FLAG_FILTER; - if (!data.is_valid()) - return; - data_at_size->set_texture_flags(texture_flags); - for(int i=0;iset_texture_flags(texture_flags); - } - - emit_changed(); - _change_notify(); + return cache_id.size; } bool DynamicFont::get_use_mipmaps() const{ - return use_mipmaps; + return cache_id.mipmaps; } void DynamicFont::set_use_mipmaps(bool p_enable){ - if (use_mipmaps==p_enable) + if (cache_id.mipmaps==p_enable) return; - use_mipmaps=p_enable; - _update_texture_flags(); + cache_id.mipmaps=p_enable; + _reload_cache(); } bool DynamicFont::get_use_filter() const{ - return use_filter; + return cache_id.filter; } void DynamicFont::set_use_filter(bool p_enable){ - if (use_filter==p_enable) + if (cache_id.filter==p_enable) return; - use_filter=p_enable; - _update_texture_flags(); + cache_id.filter=p_enable; + _reload_cache(); } int DynamicFont::get_spacing(int p_type) const{ @@ -792,7 +790,7 @@ void DynamicFont::set_fallback(int p_idx,const Ref& p_data) { ERR_FAIL_COND(p_data.is_null()); ERR_FAIL_INDEX(p_idx,fallbacks.size()); fallbacks[p_idx]=p_data; - fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(size,texture_flags); + fallback_data_at_size[p_idx]=fallbacks[p_idx]->_get_dynamic_font_at_size(cache_id); } @@ -800,7 +798,7 @@ void DynamicFont::add_fallback(const Ref& p_data) { ERR_FAIL_COND(p_data.is_null()); fallbacks.push_back(p_data); - fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(size,texture_flags)); //const.. + fallback_data_at_size.push_back(fallbacks[fallbacks.size()-1]->_get_dynamic_font_at_size(cache_id)); //const.. _change_notify(); emit_changed(); @@ -918,14 +916,10 @@ void DynamicFont::_bind_methods() { DynamicFont::DynamicFont() { - size=16; spacing_top=0; spacing_bottom=0; spacing_char=0; spacing_space=0; - use_mipmaps=false; - use_filter=false; - texture_flags=0; } DynamicFont::~DynamicFont() { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 899973f22f..4ae58ab0dd 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -45,21 +45,32 @@ class DynamicFontData : public Resource { OBJ_TYPE(DynamicFontData,Resource); +public: + + struct CacheID{ + + int size; + bool mipmaps; + bool filter; + + bool operator< (CacheID right) const; + CacheID() { size=16; mipmaps=false; filter=false; } + }; +private: const uint8_t *font_mem; int font_mem_size; bool force_autohinter; String font_path; - Map size_cache; + Map size_cache; friend class DynamicFontAtSize; friend class DynamicFont; - - Ref _get_dynamic_font_at_size(int p_size, uint32_t p_texture_flags=0); + Ref _get_dynamic_font_at_size(CacheID p_cache); protected: static void _bind_methods(); @@ -126,7 +137,7 @@ class DynamicFontAtSize : public Reference { friend class DynamicFontData; Ref font; - int size; + DynamicFontData::CacheID id; @@ -177,19 +188,16 @@ private: Vector< Ref > fallback_data_at_size; - int size; + DynamicFontData::CacheID cache_id; bool valid; int spacing_top; int spacing_bottom; int spacing_char; int spacing_space; - bool use_mipmaps; - bool use_filter; - uint32_t texture_flags; protected: - void _update_texture_flags(); + void _reload_cache(); bool _set(const StringName& p_name, const Variant& p_value); bool _get(const StringName& p_name,Variant &r_ret) const; -- cgit v1.2.3