Has anyone used MT.D MultilineEntryElement? - monotouch.dialog

I'm using the most recent one created by Alxandr (Feb/2012).
I'm trying to add it to a section using the same technique as I would adding an EntryElement. The MultilineEntryElement adds to the section but the receiving cell will not expand past it's default size. The MLEE will then overwrite the section below. I would like it to default to full screen width and 10 lines long. What is the best way to do this?
Thanks you!
Matt

To deal with this problem, set the RootElement's UnevenRows property to true, like this:
var r = new RootElement ("foo") { ... }
r.UnevenRows = true;

I did a bit more research on this issue. Please note - I am using my own implementation of MultilineEntryElement which is probably a bit different than others'.
First, it's worth stating that the issue does not manifest for me in "simple" scenarios - where a MultilineEntryElement is placed inside a section which is created as part of the initial creation of the RootElement. The issue only manifests when I manipulate an existing RootElement that has already been rendered by the DialogViewController.
It appears that there is a bug in the way MonoTouch.Dialog computes sizing of rows. If an element implements IElementSizing, then MT.D will call its GetHeight() overload. Once MT.D has detected an element with "irregular" height, it appears to need to call this method every time it processes a change to the enclosing section. This can be expensive... So if MT.D lays out a RootElement and hasn't found an element that implements IElementSizing, it appears that (perhaps intended as an optimization?) MT.D will IGNORE IElementSizing information for any elements that are added POST initial rendering. So the CELL's RowHeight property will return a standard row height, and the MultilineEntryElement will render a UITextView that spills over the cells below it.
The workaround I've come up with is to create a simple element called DummyElement which implements IElementSizing and returns 0 for GetHeight(), and to add it to the initial RootElement before the initial layout happens. If you do that, MT.D will register that there's an element which has an irregular height, and call the GetHeight() method on your MultilineEntryElement when you later add it to your element "DOM".
Here is my minimal impl of DummyElement in case it helps:
public class DummyElement : Element, IElementSizing
{
public DummyElement() : base ("empty")
{
}
public float GetHeight (UITableView tableView, NSIndexPath indexPath)
{
return 0;
}
}

Related

How to change layout of sap.uxap.ObjectPage Blocks

Demo
I have 2 + 5 blocks here, in small screen, each panel in blocks are in full width.
But in large screen, blocks are in 3:3:3 or 6:3. I want them all in a single row.
each section is contained in <div class="sapUiRespGridSpanL4 sapUiRespGridSpanM6 sapUiRespGridSpanS12 sapUiRespGridSpanXL3">
How to change it to class="sapUiRespGridSpanL12 sapUiRespGridSpanM12 sapUiRespGridSpanS12 sapUiRespGridSpanXL12" ?
I've tried to add layout in Panel, but not working.
Refrence:
sap.uxap.ObjectPageLayout Documentation
layout of blocks, blocks are in the same color, hard to specify
Finally after 1.5 hours figured out
Reason: Blocks will have to be extended from BlockBase to apply columnLayout.
Extending the BlockBase:
sap.ui.define(["sap/uxap/BlockBase"], function (BlockBase) {
"use strict";
var BlockPanel = BlockBase.extend("sap.uxap.sample.ObjectPageSubSectionSized.blocks.BlockPanel", {
metadata: {
/* no additional views provided */
}
});
return BlockPanel;
});
Then create a view and controller using the above new ui5 extended control. Use that in your page with columnLayout
xmlns:sample="sap.uxap.sample.ObjectPageSubSectionSized.blocks"
...
...
<uxap:blocks>
<sample:BlockPanel columnLayout="4"/>
</uxap:blocks>
columnLayout can't be applied if you don't extend block base. (which is really pathetic design). Nevertheless, values range from 1-4 and "auto".
Created working plnkr here
How to build custom SAPUI control?
You can wrap the target controls up with sap.uxap.BlockBase[API]. BlockBase controls are intended to be used inside sap.uxap.ObjectPageSubSection (hence the name <blocks>) and support customizing the grid spans with the property columnLayout.
Here is a demo: https://embed.plnkr.co/lSrDk9/?show=view%2FHome.view.xml,preview
<uxap:ObjectPageSubSection>
<block:MyBlock columnLayout="4"/>
<block:MyBlock columnLayout="4"/>
</uxap:ObjectPageSubSection>
Provide a not elegant, but very fast way: Overwrite CSS
<uxap:ObjectPageSubSection class="fullWidthPanel">
/* CSS specificity */
.fullWidthPanel .sapUiRespGrid.sapUiRespGridHSpace1 > div {
width: 98.88888889%;
width: -webkit-calc(100% - 1rem);
width: calc(100% - 1rem)
}

Gtk (mm) limit width of combobox

Because I use Comboboxes that may contain text entries of very long size,
which leads to the combobox increasing its width far beyond reasonable size,
I am trying to give a maximum width to the combobox.
If I am doing this like this:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
render.property_width_chars() = 10;
render.property_ellipsize() = Pango::ELLIPSIZE_END;
pack_start(render, true);
}
};
The result will be an empty cell of the desired width, which seems logical since I did not specify which column to show. But how can I do this with that attempt? Using pack_start will just bypass the renderer...
Another approach is this one:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
pack_start(render, true);
set_cell_data_func(render, sigc::mem_fun(*this, &MyCombo::render_iter));
}
void render_iter(const TreeModel::const_iterator& iter) {
Glib::ustring data = get_string_from_iter(iter);
int desired_width_chars = 10; //for example
render.property_text() = ellipsize_string(data, desired_width_chars);
}
};
Using that approach, it works, but the text in the popup (what opens up when u click the combobox) is also shortened which is not what I want (obviously the user should be able to read the whole string and I dont care about the popup widht.)
Can you please help me with this? I would be happy for any advice/alternative solutions.
Regards tagelicht
NOTE: set_wrap_width is a function that wraps the total number of entries in the combo box over a number of columns specified; it does not answer the question.
Using set_wrap_width(1) | Using set_wrap_width(5)
Following Noup's answer as a guide I managed to get the below code; which directly answers the question and its requirements (C++/Gtkmm).
// Get the first cell renderer of the ComboBox.
auto v_cellRenderer = (Gtk::CellRendererText*)v_comboBox.get_first_cell();
// Probably obsolete; Sets character width to 1.
v_cellRenderer->property_width_chars() = 1;
// Sets the ellipses ("...") to be at the end, where text overflows.
// See Pango::ELLIPSIZE enum for other values.
v_cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_END;
// Sets the size of the box, change this to suit your needs.
// -1 sets it to automatic scaling: (width, height).
v_cellRenderer->set_fixed_size(200, -1);
Result (image):
Result of code
BE AWARE: Depending on where you perform the above code; either all the cells will be the same size, or just the box itself (intended).
From experimenting, I've found:
In the parent object constructor: All cell sizes are the same.
In a separate function: Only the first cell (the box) is affected.
I'd recommend you put the code in a function that's connected to the comboBox's changed signal, such as:
v_comboBox.signal_changed().connect(sigc::mem_fun(*this, &YourClass::comboBox_changedFunction));
This may be what you are looking for:
cell_renderer_text.set_wrap_width(10)
This is for Python, but you get the idea :-)
Unfortunately, the documentation is scarce. I found this by poking around in Anjuta/Glade.
Edit:
the docs are here. They are not overly helpful, but they do exist.
As an alternative, the following works for me without having to set wrap_width nor to subclass ComboBox (in Gtk#):
ComboBoxText cb = new ComboBoxText();
cb.Hexpand = true; //If there's available space, we use it
CellRendererText renderer = (cb.Cells[0] as CellRendererText); //Get the ComboBoxText only renderer
renderer.WidthChars = 20; //Always show at least 20 chars
renderer.Ellipsize = Pango.EllipsizeMode.End;
Note: I'm using Expand to use space if it's available. If you just want to keep the combo box on a fixed width, just remove that bit.

iText: How to set page events for footer accounting for page rotation?

When creating a PDF from scratch, I'm trying to adapt this code
http://itextpdf.com/examples/iia.php?id=104
specifically the onEndPage() function shown there, to set a footer using page events. The problem is in my application, some pages are Portrait and some Landscape, and I don't know how to implement a query in that function to determine the page rotation.
First, I got it working when all pages are portrait. Then I added some landscape pages and tried to modify it as shown below. I originally thought a quick-and-dirty solution would be simply to center the footer table by adding,
table.setHorizontalAlignment(Element.ALIGN_CENTER);
but this didn't seem to have any effect (on landscape pages, the table is always aligned left on the long-edge of the paper). Then I tried to do a better solution by querying the page rotation, and based on its results, set the table columns to the correct widths, using,
if (???==90)
table.setTotalWidth(new float[]{2.25f*K.PPI,1.195f*K.PPI,0.805f*K.PPI,2.25f*K.PPI,}); // add to 6.5"
else
table.setTotalWidth(new float[]{3.25f*K.PPI,1.195f*K.PPI,0.805f*K.PPI,3.25f*K.PPI,}); // add to 6.5"
but I'm not sure how to query the page rotation (as you can tell). Any help would be appreciated. My code is as follows.
class HeaderFooter extends PdfPageEventHelper {
/** The header text. */
String footerLeft, footerRight;
/** The template with the total number of pages. */
PdfTemplate total;
/** Flag indicating true for first page */
Boolean firstPageFlag=true;
...
public void onEndPage(PdfWriter writer, Document document) {
if (firstPageFlag==false) {
/** The footer font */
FontFactory.register("/home/appFonts/Arial_Narrow.ttf", "arial_narrow");
Font styleFooter = FontFactory.getFont("arial_narrow", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, K.TEXT_FOOTER_FONT_SIZE, Font.UNDEFINED, BaseColor.BLACK);
PdfPTable table = new PdfPTable(4);
try {
//table.setHorizontalAlignment(Element.ALIGN_CENTER); // doesn't seem to have an effect for landscape pages
if (how to query page rotation, or other method to evaluate whether page is landscape or portrait?)
table.setTotalWidth(new float[]{2.25f*K.PPI,1.195f*K.PPI,0.805f*K.PPI,2.25f*K.PPI,}); // add to 6.5"
else
table.setTotalWidth(new float[]{3.25f*K.PPI,1.195f*K.PPI,0.805f*K.PPI,3.25f*K.PPI,}); // add to 8.5"
table.setLockedWidth(true);
table.getDefaultCell().setFixedHeight(14);
table.getDefaultCell().setBorder(Rectangle.TOP);
// col1, row1
table.addCell(new Phrase(footerLeft, styleFooter));
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
// col2, row1
table.addCell(new Phrase(String.format("page %d of", writer.getPageNumber()),styleFooter));
// col3, row1
PdfPCell cell = new PdfPCell(Image.getInstance(total));
cell.setBorder(Rectangle.TOP);
table.addCell(cell);
// col4, row1
table.addCell(new Phrase(footerRight, styleFooter));
table.writeSelectedRows(0,-1,document.left(),document.bottom()-0.35f*K.PPI,writer.getDirectContent());
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
} else
firstPageFlag=false;
}
...
}
Summarizing the solution developed in the comments to the question
As #Bruno initially stated correctly, the original attempt of the OP was
mixing page events (used when creating PDFs from scratch) with PdfReader (used when manipulating existing PDFs).
It would have been possible to actually use the OP's PdfReader centric test for landscape by switching to a two-pass architecture as used in the sample TwoPasses.java but the OP preferred a one-pass approach.
For this one-pass approach the original HeaderFooter page event listener was extended to also store the page dimension information upon page construction. This was done by overriding onStartPage() to retrieve the page size using
Rectangle pSize=document.getPageSize();
and storing its relevant information in a member variable of the listener. Eventually this information now is used in onEndPage() to determine how to set table columns.
In case of the OP's processes, landscape pages are created by means of rotation. Thus the relevant information in his case was whether
(pSize.getRotation()==90)
is true (landscape) or not (portrait). In general the whole Rectangle including both its rotation and its dimension values would have to be stored and eventually be used to determine the desired header and footer locations.

Need to access image for selected item in android gridview

I want to access the properties of an image when it is selected from a gridview. For example if I am using.
GridView gridview = (GridView) findViewById(R.id.imageGallery);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position,long id)
{
//need code in here that I can do something like this.
//Get access to the integer value of the R.drawable.myimage
//use that int too do a lookup in a dictionary to check for existance
//can't see to find any code to get at the drawable associated with the image clicked in the grid, did intense debug
And data not easily visible at runtime
}
);
#Reid I think you will want to create a custom adapter (extend BaseAdapter or other) that holds a view class containing the metadata you need to get at, based on the position in the list. Possibly an easier way, but that is what I did in a ListView.. A couple of links:
http://developer.android.com/resources/tutorials/views/hello-gridview.html
http://www.anddev.org/gridview-t5585.html

How to do single row expansion with CellTable?

I'm trying to use the new GWT CellTable widget but my table needs to support one row expansion, i.e. there is a zippy on the left of a row and when it's clicked, the row should expand to provide more detail information and this row should span across all columns. Is it possible to achieve this with the CellTable? How do I add a row that spans all columns between other rows dynamically?
Any help will be appreciated!
GWT 2.5 will add a CellTableBuilder with the exact goal of allowing this kind of things.
You can find a live example at http://showcase2.jlabanca-testing.appspot.com/#!CwCustomDataGrid (click on the "show friends" cells)
Can you not make the additional row invisible using getRowElement(int row) and using DOM methods to set display 'none' when rendered and as blank when the button, to show it, is hit.
I am working on the solution too and my plan for now is to use CSS classes + manual styles manipulation to make it look as I need. Not sure if I be able to merry it with GWT though: http://jsfiddle.net/7WFcF/
I took a different approach to solve this same problem.
The basic concept is using dom elements to add and remove rows based on an event. The following code is an abstract extension of CellTable. You'll want to call this method from your event that gets fired from the click to expand a row.
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
public abstract class ActionCellTable<T> extends CellTable<T> {
protected abstract void addActionsColumn();
Integer previousSelectedRow = null;
public void displayRowDetail(int selectedRow, Element e){
//Get the tbody of the Cell Table
//Assumption that we want the first (only?) tbody.
Element tbody = this.getElement().getElementsByTagName("tbody").getItem(0);
//Get all the trs in the body
NodeList<Element> trs = tbody.getElementsByTagName("tr");
//remove previously selected view, if there was one
if(previousSelectedRow!=null){
trs.getItem(previousSelectedRow+1).removeFromParent();
//If the current is further down the list then the current your index will be one off.
if(selectedRow>previousSelectedRow)selectedRow--;
}
if(previousSelectedRow==null || selectedRow != previousSelectedRow){// if the are equal we don't want to do anything else
Element td = Document.get().createTDElement();
td.setAttribute("colspan", Integer.toString(trs.getItem(selectedRow).getChildNodes().getLength()));
td.appendChild(e);
Element tr = Document.get().createTRElement();
tr.appendChild(td);
tbody.insertAfter(tr, trs.getItem(selectedRow));
previousSelectedRow=selectedRow;
} else {
previousSelectedRow=null;
}
}
}
previousSelectedRow is used to track which item is "expanded", this could probably be achieved using classes or IDs. If needed I can elaborate more on the CellTable, events, views, and activities.