As suggested by Mr Bruno Lowagie Here, I've been using the push button field to fill images in custom templates, as such:
AcroFields form = stamper.AcroFields;
PushbuttonField logo = form.GetNewPushbuttonFromField("1");
if(logo != null)
{
logo.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
logo.ProportionalIcon = true;
logo.Image = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Image.jpg"));
form.ReplacePushbuttonField("1", logo.Field);
}
The problem is if I have multiple pushbuttons with field names 1, and I want to replace all of them with that same image, this only replaces the first one.
These are the push button fields before replacing their icon:
This is after I try to replace them, and only the first gets replaced:
I also saw that we can set form.GetNewPushbuttonFromField(string field, int order), where order should be the index of the field with that field name?
So for testing I tried:
PushbuttonField logo = form.GetNewPushbuttonFromField("1", 0);
if(logo != null)
{
logo.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
logo.ProportionalIcon = true;
logo.Image = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Image.jpg"));
form.ReplacePushbuttonField("1", logo.Field);
}
PushbuttonField logo2 = form.GetNewPushbuttonFromField("1", 1);
if (CDlogo2 != null)
{
logo2.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
logo2.ProportionalIcon = true;
logo2.Image = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Image.jpg"));
form.ReplacePushbuttonField("1", logo2.Field);
}
However, for some reason the first pushbutton icon does not change and gets placed in the location of the second pushbutton that gets its icon changed, as such:
I need to be able to list through all of the pushbutton fields with that name field and replace all of them with that same image, how would I do that?
Thank you,
EDIT
As requested Here is a link to view the pdfs
EDIT 2
If anyone cares this is how I'm using mkl's answer to loop and fill all images: (I know it's done terribly, but it works, yes, I'm keeping it for the time being)
int n= 0;
PushbuttonField logo = form.GetNewPushbuttonFromField("1", n);
while (logo != null)
{
n++;
logo = form.GetNewPushbuttonFromField("1", n);
}
PushbuttonField logo2;
for (int z = 0; z < n; z++)
{
logo2 = form.GetNewPushbuttonFromField("1", z);
logo2.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
logo2.ProportionalIcon = true;
logo2.Image = iTextSharp.text.Image.GetInstance(Server.MapPath(imagePath));
form.ReplacePushbuttonField("1", logo2.Field, z);
}
Because I couldn't find a method to get the number of pushbuttons with the same name.
You
saw that we can set form.GetNewPushbuttonFromField(string field, int order), where order should be the index of the field with that field name
which is the correct direction to look. But you still used the form.ReplacePushbuttonField overload without an order parameter:
PushbuttonField logo2 = form.GetNewPushbuttonFromField("1", 1);
...
form.ReplacePushbuttonField("1", logo2.Field);
This creates a PushbuttonField from the second form field named "1" (including the position of the second button) and uses its information to replace the first field named "1". Thus, it
gets placed in the location of the second pushbutton
So, to fix this you also have to use the form.ReplacePushbuttonField overload with an order parameter, if you use the form.GetNewPushbuttonFromField overload with an order parameter, and the values should match:
PushbuttonField logo2 = form.GetNewPushbuttonFromField("1", 1);
...
form.ReplacePushbuttonField("1", logo2.Field, 1);
Related
I have profile photo of users stored in Firebase and I want to know how I can create a marker with the user's profile photo with an orange border.
I tried some code from the internet and it works but the measurements seem to be wrong and I don't know what I'm doing wrong.
The code I used:
fun setMarkerPhoto(user:User, location: Location){
var bitmapFinal : Bitmap?
if(hasProfilePhoto){
/*val options = RequestOptions()
options.centerCrop()*/
Glide.with(this)
.asBitmap()
/*.apply(options)*/
.centerCrop()
.load(user.image)
.into(object : CustomTarget<Bitmap>(){
override fun onResourceReady(resource: Bitmap, transition: com.bumptech.glide.request.transition.Transition<in Bitmap>?) {
bitmapFinal = createUserBitmapFinal(resource)
markerOptions
.position(LatLng(location!!.latitude, location!!.longitude))
.title("Current Location")
.snippet(address)
.icon(BitmapDescriptorFactory.fromBitmap(bitmapFinal))
mCurrentMarker = googleMap.addMarker(markerOptions)
}
override fun onLoadCleared(placeholder: Drawable?) {
TODO("Not yet implemented")
}
})
}else{
markerOptions
.position(LatLng(mLastLocation!!.latitude, mLastLocation!!.longitude))
.title("Current Location")
.snippet(address)
.icon(BitmapDescriptorFactory.fromBitmap(smallMarker))
mCurrentMarker = googleMap.addMarker(markerOptions)
}
}
private fun createUserBitmapFinal(bitmapInicial: Bitmap?): Bitmap? {
var result: Bitmap? = null
try {
result = Bitmap.createBitmap(150,150, Bitmap.Config.ARGB_8888) //change the size of the placeholder
result.eraseColor(Color.TRANSPARENT)
val canvas = Canvas(result)
val drawable: Drawable = resources.getDrawable(R.drawable.ic_pickup)
drawable.setBounds(0, 0, 150,150) //change the size of the placeholder, but you need to maintain the same proportion of the first line
drawable.draw(canvas)
val roundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
val bitmapRect = RectF()
canvas.save()
if (bitmapInicial != null) {
val shader =
BitmapShader(bitmapInicial, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val matrix = Matrix()
val scale: Float = 200 / bitmapInicial.width.toFloat() //reduce or augment here change the size of the original bitmap inside the placehoder.
// But you need to adjust the line bitmapRect with the same proportion
matrix.postTranslate(5f, 5f)
matrix.postScale(scale, scale)
roundPaint.shader = shader
shader.setLocalMatrix(matrix)
bitmapRect[10f, 10f, 104f+10f]=104f+10f //change here too to change the size
canvas.drawRoundRect(bitmapRect, 56f, 56f, roundPaint)
}
I didn't really understand how to perfectly fit the bitmap image inside the placeholder. My marker looked like this:
also the image wasn't being center cropped even though I mentioned that it should be in the code, where it says Glide.centerCrop()
Also, I'm using GeoFire to display markers of users in a specified radius of the user and for now I can display a simple marker but I want the marker to have that user's profile photo too! How can I do it?
GeoFire Code:
val geoQuery: GeoQuery = geoFire.queryAtLocation(GeoLocation(location.latitude, location.longitude), 0.5)
geoQuery.addGeoQueryEventListener(object : GeoQueryEventListener {
override fun onKeyEntered(key: String, location: GeoLocation) {
println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude))
Log.i("key entered","User found around you")
val aroundYou = LatLng(location.latitude, location.longitude)
if (markerList != null) {
for (marker in markerList) {
marker.remove()
}
}
otherMarkerOptions
.position(aroundYou)
.title("Current Location")
//.snippet(address)
.icon(BitmapDescriptorFactory.fromBitmap(smallMarker)) //This is a simple marker but i want it to have the user's profile photo
markerList.add(googleMap.addMarker(otherMarkerOptions))
//}
}
Thank you in advance
Edit:
In the line: val drawable: Drawable = resources.getDrawable(R.drawable.ic_pickup)
It's this png:
I want to insert the profile photo of the user on that drawable file and if the user doesn't have a profile photo then only the drawable photo will be visible.
You get the code to transform the bitmap from my code in another question in StrackOverflow. As I mentioned there, I can´t teste the code because i´m only working with flutter right now.
But looking ate your code I might try this:
Add this function:
fun dp(value: Float): Int {
return if (value == 0f) {
0
} else Math.ceil(resources.displayMetrics.density * value.toDouble()).toInt()
}
in your lines:
result = Bitmap.createBitmap(150,150, Bitmap.Config.ARGB_8888);
drawable.setBounds(0, 0, 150,150);
change to:
result = Bitmap.createBitmap(dp(62f), dp(76f), Bitmap.Config.ARGB_8888);
drawable.setBounds(0, 0, dp(150f), dp(150f)) ;
let me know the results.
Ok, so I managed to get all the buildings to stay in place, but now for some reason, the player character won't go in front of the buildings.
I tried switching the places in the code where the if the command for checking if the character's going behind the building and the if-else for checking if it's going in front of the code, but nothing changed.
here's the code:
var _dg = depth_grid;
var _inst_num = instance_number(obj_depth_buildings);
//below is for resizing the grid
ds_grid_resize(depth_grid,2, _inst_num);
//below adds instance info to grid
var _yy = 0;
with (obj_depth_buildings)
{
_dg[# 0,_yy] = id;
_dg[# 1,_yy] = y;
_yy++;
}
//below sorts the grid so that the ones with the biggest y variables end up at the top
ds_grid_sort(_dg,1,false);
//below goes through the grid and identifies everything
var _inst;
_yy = 0;
repeat (_inst_num)
{
//below pulls out an id
_inst = _dg[# 0, _yy];
//below gets the instance execute depth
with(_inst)
{
_inst.depth= layer_get_depth("collision") + _yy;
with (obj_nonbuilding_depths)
{
if object_index.y > _inst.y
{
object_index.depth = (_inst.depth + 1);
}
else if object_index.y <= _inst.y
{
object_index.depth = (_inst.depth - 1);
}
}
}
_yy++;
}
you should change the object depth by change the leyar depth in GMS2
This is likely embarrassingly easy but I'm new and I've been beating my head against the wall on this for a while now. What I am attempting to do is basically a modified version of the "Hello App Maker!" If else test.
The necessary info I have the following widgets attached to the appropriate data sources:
Dropdown widget called source_name (string - list)
Label widget I've called name (string)
Text Box widget called qty_duration (number)
Label widget I've called hours (number)
I have a dropdown widget called source_name with 5 options. On selection I have the value appear in a label widget I've called name. If the option selected from the drop down widget is ever LABOUR I am trying to then have the value of a Text Box widget called qty_duration appear in a label widget I've called hours
On the source_name dropdown event - onValueChange I have the following code:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget = nothing;
}
It's not giving me any errors, but it's also not outputting to the hours label. If I edit the code as follows just to muck with it:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = nothing;
}
I'm not sure what I'm doing wrong.
Assuming all labels and input widgets are inside a table row you will want to adjust your code as follows:
var tablerow = widget.parent;
var nameWidget = tablerow.descendants.name.text;
var outputWidget = tablerow.descendants.hours;
var techhours = tablerow.descendants.qty_duration.value;
if(nameWidget === 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = null;
}
By using widget.parent in the onValueChange event of the dropdown you will automatically reference the table row and then by using descendants you are referencing only the descendants of that table row. This will bridge the error by using an absolute reference when using table rows. If it still doesn't work let me know.
According to my understanding, project.getItems({selected: true}) returns wrong results: I'm selecting a curve, it returns the parent Path: Sketch
Try clicking on a curve or a segment. Whole path will be moved. Then try changing the behavior by setting var workaround = false to var workaround = true to observe desired behavior.
How can I get exactly what is really selected?
Current workaround
I'm currently adding those objects into an array on selection and use those items instead of project.getItems({selected: true}).
The thing is that in Paper.js architecture, curves and segments are not items (they are part of a specific item which is the path). So you shouldn't expect project.getItems() to return anything else than items.
Another thing you have to know is that a path is assumed selected if any of its part is selected (curves, segments, points, handles, position, bounds, ...). And a curve is assumed selected if all of its parts are selected (points and handles).
With that in mind, you can create an algorithm to retrieve "what is really selected" based on project.getItems({selected: true}) as its first part. Then, you need to loop through curves and segments to check if they are selected.
Here is a sketch demonstrating a possible solution.
var vector = new Point(10, 10);
// Create path.
var path = new Path({
segments: [
[100, 100],
[200, 100],
[260, 170],
[360, 170],
[420, 250]
],
strokeColor: 'red',
strokeWidth: 10
});
// Translate given thing along global vector.
function translateThing(thing) {
switch (thing.getClassName()) {
case 'Path':
thing.position += vector;
break;
case 'Curve':
thing.segment1.point += vector;
thing.segment2.point += vector;
break;
case 'Segment':
thing.point += vector;
break;
}
}
// On mouse down...
function onMouseDown(event) {
// ...only select what was clicked.
path.selected = false;
hit = paper.project.hitTest(event.point);
if (hit && hit.location) {
hit.location.curve.selected = true;
}
else if (hit && hit.segment) {
hit.segment.selected = true;
}
// We check all items for demo purpose.
// Move all selected things.
// First get selected items in active layer...
project.activeLayer.getItems({ selected: true })
// ...then map them to what is really selected...
.map(getSelectedThing)
// ...then translate them.
.forEach(translateThing);
}
// This method returns what is really selected in a given item.
// Here we assume that only one thing can be selected at the same time.
// Returned thing can be either a Curve, a Segment or an Item.
function getSelectedThing(item) {
// Only check curves and segments if item is a path.
if (item.getClassName() === 'Path') {
// Check curves.
for (var i = 0, l = item.curves.length; i < l; i++) {
if (item.curves[i].selected) {
return item.curves[i];
}
}
// Check segments.
for (var i = 0, l = item.segments.length; i < l; i++) {
if (item.segments[i].selected) {
return item.segments[i];
}
}
}
// return item by default.
return item;
}
That said, depending on your real use case, your current workaround could be more appropriate than this approach.
I'm using Jame Ferreira's Google Script: Enterprise Application Essentials to create a product page (Chapter 5). I've created the app that displays thumbnails of the products all on a page, and then the info panel with more detail that pops up when the user mouses over. It's using CSS to achieve this styling.
Problem comes in when placing the info panel. It pops up in only one location, as opposed to being tied to the thumbnail with which it is associated.
Here's the code related to the info panel. I believe the problem exists in the placement of the last few lines, but have tried everything I can think of:
function onInfo(e){
var app = UiApp.getActiveApplication();
var id = e.parameter.source;
for (var i in productDetails){
if(productDetails[i].id == id){
var r = 50;
var c = 0;
var infoPanel = app.createVerticalPanel().setSize('300px', '300px');
var horzPanel = app.createHorizontalPanel();
var image = app.createImage(productDetails[i].imageUrl).setHeight('100px');
var title = app.createLabel(productDetails[i].title);
horzPanel.add(image);
horzPanel.add(title);
var description = app.createLabel(productDetails[i].description);
infoPanel.add(horzPanel);
infoPanel.add(description);
applyCSS(infoPanel, _infoPanel);
applyCSS(image, _infoImage);
applyCSS(horzPanel, _infoBoxSeparator);
applyCSS(title, _infoTitle);
applyCSS(description, _infoDescription);
app.getElementById('infoGrid').setVisible(true)
.setWidget(0,0, infoPanel);
break;
}
c++
if (c == 3){
c = 0;
r = r+250;
}
switch (c)
{
case 0:
c=250;
break;
case 1:
c=500;
break;
case 2:
c=250;
break;
}
}
var _infoLocation =
{
"top":r+"px",
"left":c+"px",}
applyCSS(infoPanel, _infoLocation);
return app;
}
You may get the position of the mouse using e.parameter.x and e.parameter.y based on which you can position the infoPanel
infoPanel.setStyleAttribute('top',e.parameter.y)
.setStyleAttribute('left',e.parameter.x).setStyleAttribute('zIndex','1')
.setStyleAttribute('position','fixed');
You may add some offset to x and y positions of mouse to display it according to your needs.
Position related parameter which you get in handler function are
e.parameter.x
e.parameter.y
e.parameter.clientX
e.parameter.clientY
e.parameter.screenX
e.parameter.screenY