BlackBerry Horizontal Scrolling in TreeField or ListField - blackberry

I am working on an application that requires text larger than the viewable screen size in both a TreeField and a ListField. As you know, the TreeField and ListField callbacks support only
graphics.drawText() methods, so I cannot add an instance of a Field per row.
Does anyone have a method of Scrolling horizontally past the viewable text size?
Is there maybe a scrollable panel that would work? I know of the NullField(Field.Focusable) trick but this won't work on the list field.
Lastly, I am aware that the type of screen makes a different as FullScreen and MainScreen use VerticalFieldMangers. So am using a PopupScreen at the moment for my testing.
Thank you in advance for your time.

Maybe it's better to split text in two lines and set row height 2 x font height (+ margins)?
alt text http://img219.imageshack.us/img219/5802/listh.jpg
class Scr extends MainScreen implements ListFieldCallback {
int DISPLAY_WIDTH = Display.getWidth();
Vector mItems = new Vector();
ListField mListField = new ListField();
public Scr() {
mListField.setCallback(this);
add(mListField);
mItems.addElement("Lorem ipsum dolor sit amet, ");
mItems.addElement("Lorem ipsum dolor sit");
mItems.addElement("Lorem ipsum dolor sit amet, "+
"consectetuer adipiscing elit");
mItems.addElement("Lorem ipsum dolor sit amet, "+
"consectetuer adipiscing elit, sed diam "+
"nonummy nibh euismod");
mItems.addElement("Lorem ipsum dolor sit amet, "+
"consectetuer adipiscing elit");
mItems.addElement("Lorem ipsum dolor sit amet, ");
mListField.setSize(mItems.size());
mListField.setRowHeight(
mListField.getFont().getHeight()*2 + 4);
}
public void drawListRow(ListField field, Graphics g,
int i, int y, int w) {
// Draw the text.
String text = (String) get(field, i);
if(g.getFont().getAdvance(text) > w)
{
int index = 0;
while(g.getFont().getAdvance(text.substring(0, index)) < w)
{
index++;
}
g.drawText(text.substring(0, index), 0, y, 0, w);
g.drawText(text.substring(index, text.length()-1), 0,
y + g.getFont().getHeight()+ 4, DrawStyle.ELLIPSIS, w);
}
else
{
g.drawText(text, 0, y, 0, w);
}
}
public Object get(ListField listField, int index) {
return mItems.elementAt(index);
}
public int getPreferredWidth(ListField listField) {
return DISPLAY_WIDTH;
}
public int indexOfList(ListField listField,
String prefix, int start) {
return 0;
}
}

Related

Hello could somebody help me modify an interesting indicator?

I got this indicator for mt4, I would like somebody to help me modify it so I can input an integer to select how many bars should be plotted. normally it will plot infinite bars, I'd like to be able to select the number of MTF bars the indicator should plot. This to eliminate the lag when changin timeframes, I imagine the lag is because of the big amount of MTF candles plotted.
Other change that I would really apreciate, if you see when open and close price is exactly the same it will not create a doji, it will only show wicks, not the classic horizontal line for a doji.
I paid a coder to make this, now he's chargin plus to make this changes, I tried to make them myself copying an indicator that has that function but my coding skills are hugely limited.
Thanks.
//+------------------------------------------------------------------+
//| MTF_Candles.mq4 |
//+------------------------------------------------------------------+
#property copyright "Ab Moncada"
#property version "1.0"
#property strict
#property indicator_chart_window
enum enumTimeFrames{
m1 = PERIOD_M1, //M1
m5 = PERIOD_M5, //M5
m15 = PERIOD_M15, //M15
m30 = PERIOD_M30, //M30
h1 = PERIOD_H1, //H1
h4 = PERIOD_H4, //H4
d1 = PERIOD_D1, //D1
w1 = PERIOD_W1, //W1
mn1 = PERIOD_MN1 //MN1
};
//input ENUM_TIMEFRAMES MTF_Period = PERIOD_H1; //Timeframe
input enumTimeFrames MTF_Period = h1; //Timeframe
input color UpColor = clrGainsboro; //ColorBulls
input color DownColor = clrGainsboro; //ColorBears
input bool LineType = false; //Background
input ENUM_LINE_STYLE LineStyle = STYLE_DOT; //LineStyle
input int LineWidth = 3; //LineWidth
string indiName = "MTF_CandleStick";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(){
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
objDelete(indiName+IntegerToString(MTF_Period));
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
if(MTF_Period <= _Period) return(0);
int limit = rates_total - prev_calculated;
if(limit > 0){
objDelete(indiName+IntegerToString(MTF_Period));
limit = rates_total-1;
}
else{
if(MTF_Period < 1440) limit = MTF_Period/_Period;
else limit = 1;
}
for(int i=0; i<limit; i++){
double mtfOpen, mtfClose, mtfHigh, mtfLow;
int first, last=0;
if(MTF_Period < 1440){
if(MathMod(time[i], MTF_Period*60) != 0) continue;
first = i;
for(int t=i-1; t>=0; t--){
if(time[i]+MTF_Period*60 <= time[t]){
last = t+1;
break;
}
}
mtfOpen = open[first];
mtfClose = close[last];
mtfHigh = high[iHighest(NULL, 0, MODE_HIGH, first-last+1, last)];
mtfLow = low[iLowest(NULL, 0, MODE_LOW, first-last+1, last)];
}
else{
if(time[Bars-1] > iTime(NULL, MTF_Period, i)) break;
mtfOpen = iOpen(NULL, MTF_Period, i);
mtfClose = iClose(NULL, MTF_Period, i);
mtfHigh = iHigh(NULL, MTF_Period, i);
mtfLow = iLow(NULL, MTF_Period, i);
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false);
if(TimeHour(time[first]) != 0) first--;
if(i > 0){
last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false);
if(TimeHour(time[last]) == 0) last++;
}
/*
if(MTF_Period == 1440){
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false);
if(i > 0) last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false)+1;
}
else{
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false)-1;
if(i > 0) last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false);
}
*/
}
if(mtfOpen <= mtfClose){
Rectangle(indiName+IntegerToString(MTF_Period)+"_body"+IntegerToString(i), first, mtfOpen, last, mtfClose, UpColor, LineStyle, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_shadow"+IntegerToString(i), (first+last)/2, mtfClose, mtfHigh, UpColor, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_tail"+IntegerToString(i), (first+last)/2, mtfOpen, mtfLow, UpColor, LineWidth);
}
else{
Rectangle(indiName+IntegerToString(MTF_Period)+"_body"+IntegerToString(i), first, mtfOpen, last, mtfClose, DownColor, LineStyle, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_shadow"+IntegerToString(i), (first+last)/2, mtfOpen, mtfHigh, DownColor, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_tail"+IntegerToString(i), (first+last)/2, mtfClose, mtfLow, DownColor, LineWidth);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
void Rectangle(string name, int index1, double price1, int index2, double price2, color Rcolor, int Rstyle, int Rwidth){
long id = ChartID();
if (ObjectFind(name) != 0) {
ObjectCreate(id, name, OBJ_RECTANGLE, 0, Time[index1], price1, Time[index2], price2);
ObjectSetInteger(id, name, OBJPROP_COLOR, Rcolor);
if(LineType) ObjectSetInteger(id, name, OBJPROP_STYLE, Rstyle);
ObjectSetInteger(id, name, OBJPROP_WIDTH, Rwidth);
ObjectSetInteger(id, name, OBJPROP_BACK, !LineType);
//ObjectSetInteger(id, name, OBJPROP_RAY_RIGHT, false);
ObjectSetInteger(id, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(id, name, OBJPROP_HIDDEN, true);
}
else{
ObjectMove(name, 0, Time[index1], price1);
ObjectMove(name, 1, Time[index2], price2);
}
ChartRedraw(id);
}
void TrendLine(string name, int position, double price1, double price2, color Tcolor, int Twidth){
long id = ChartID();
if (ObjectFind(name) != 0) {
ObjectCreate(id, name, OBJ_TREND, 0, Time[position], price1, Time[position], price2);
ObjectSetInteger(id, name, OBJPROP_COLOR, Tcolor);
ObjectSetInteger(id, name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(id, name, OBJPROP_WIDTH, Twidth);
ObjectSetInteger(id, name, OBJPROP_BACK, true);
ObjectSetInteger(id, name, OBJPROP_RAY_RIGHT, false);
ObjectSetInteger(id, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(id, name, OBJPROP_HIDDEN, true);
}
else{
ObjectMove(name, 0, Time[position], price1);
ObjectMove(name, 1, Time[position], price2);
}
ChartRedraw(id);
}
void objDelete(string basicName){
for(int i=ObjectsTotal();i>=0;i--){
string ObjName = ObjectName(i);
if(StringFind(ObjName, basicName) >=0) ObjectDelete(ObjName);
}
}

Using MonoTouch.CoreText to draw multi-line text

I used that examples
http://developer.xamarin.com/recipes/ios/graphics_and_drawing/core_text/draw_unicode_text_with_coretext/
Using MonoTouch.CoreText to draw text fragments at specific coordinaates
to draw a text line over UIView.
Now I need to extend it to draw multi-line text. Basically is simple. In the Draw() method I split the multi-line string Text on "\n" and than I call DrawTextLine() for any single line adding a newLineDY to Y.
The only problem is that any new line draw starts after the X draw end of the previous one:
aaa
bbb
ccc
How to avoid the X displacement? Can be reset? How? I try appling a negative DX for any line, but I don't know the right value to apply.
private const float newLineDY = 40;
public override void Draw()
{
string[] lines = Text.Split("\n".ToCharArray());
float lx = X;
float ly = Y;
foreach (string line in lines)
{
DrawTextLine(line, lx, ly);
//lx -= 100; // negative DX
ly += newLineDY;
}
}
private void DrawTextLine(string text, float x, float y)
{
CGContext gctx = UIGraphics.GetCurrentContext();
gctx.SaveState();
gctx.TranslateCTM(x, y);
//gctx.TextPosition = new CGPoint(x, y);
gctx.ScaleCTM(1, -1);
//gctx.RotateCTM((float)Math.PI * 315 / 180);
gctx.SetFillColor(UIColor.Black.CGColor);
var attributedString = new NSAttributedString(text,
new CTStringAttributes
{
ForegroundColorFromContext = true,
Font = new CTFont("Arial", 24)
});
using (CTLine textLine = new CTLine(attributedString))
{
textLine.Draw(gctx);
}
gctx.RestoreState();
}
Thaks!
I have solved using attributedString.DrawString(new CGPoint(x, y)), a much simpler API, as suggested here
http://monotouch.2284126.n4.nabble.com/Using-MonoTouch-CoreText-to-draw-text-fragments-at-specific-coordinates-td4658531.html
So my code became:
private const float newLineDY = 40;
public override void Draw()
{
string[] lines = Text.Split("\n".ToCharArray());
float lx = X;
float ly = Y;
foreach (string line in lines)
{
DrawTextLine(line, lx, ly);
ly += newLineDY;
}
}
private void DrawTextLine(string text, float x, float y)
{
NSAttributedString attributedString = new NSAttributedString(
text,
new CTStringAttributes
{
ForegroundColorFromContext = true,
Font = new CTFont("Arial", 24)
});
attributedString.DrawString(new CGPoint(x, y));
}

How to set an Image border on BlackBerry Screen

I have a List Items(an Image and text)on BB Screen,
My requirement is to set an image border(So that Image Separation will be done on List Items) to image on BB Screen
Could any one help?
Here My Code:
public void drawListRow(ListField list, Graphics g, int index, int y,
int width) {
String title = (String) listElements.elementAt(index);
Bitmap image = (Bitmap) listImage.elementAt(index);
int LEFT_OFFSET = 2;
int TOP_OFFSET = 8;
int xpos = LEFT_OFFSET;
int ypos = TOP_OFFSET + y;
int w = image.getWidth();
int h = image.getHeight();
g.drawBitmap(xpos, ypos, w, h, image, 4, 6);
xpos = w + 20;
g.setFont(myFont);
g.setColor(Color.BLACK);
g.drawText(title, xpos, ypos);
}
i hope i got your question right and would suggest you drawing a rectangle around the image like that:
g.setColor(Color.RED);
g.drawRect(xpos - 1, ypos - 1, w + 1, h + 1);
This would draw the rectangle around your image without overlapping it. For more details on why you need these adjustments of the position and the size of the rectangle you can check on the documentation of Graphics class here http://www.it.uc3m.es/florina/docencia/j2me/midp/docs/api/javax/microedition/lcdui/Graphics.html

How to justify LabelField in Blackberry

I have long text content and I want to display it on screen with justify alignment using LabelField or something else. Currently, I can do right/left/center align but can't justify align.
Are there any custom controls that help me do this?
This is just a prototype, so there may be some things it doesn't handle. But, it should be a start, that you can use to do what you want. Most of the important logic is in the paint() method.
I'm not aware of any built-in (RIM libraries) way to do this.
public class JustifiedLabelField extends LabelField {
/** a cache of the label's words, to avoid having to recalculate every
time paint() is called */
private String[] _words;
/** the dynamic field height */
private int _height = 0;
public JustifiedLabelField(Object text, long style){
super(text, style);
setText(text);
}
public void setText(Object text) {
// update the words cache when text changes
_words = split((String)text, " "); // NOTE: this only supports String type!
super.setText(text);
}
public int getPreferredHeight() {
// I believe overriding this method is necessary because the
// justification might produce a different total number of lines,
// depending on the algorithm used
return (_height > 0) ? _height : super.getPreferredHeight();
}
protected void paint(Graphics g) {
Font font = g.getFont();
int space = font.getAdvance(' ');
int fontHeight = font.getHeight();
int fieldWidth = getWidth();
int word = 0;
int y = 0;
while (word < _words.length) {
// each iteration of this loop handles one line
int wordsInLine = 0;
int lineWordWidths = 0;
// first loop over all words that fit on this line, to measure
while (word < _words.length) {
int wordWidth = font.getAdvance(_words[word]);
if (lineWordWidths + wordWidth <= fieldWidth) {
lineWordWidths += (wordWidth + space);
word++;
wordsInLine++;
} else {
break;
}
}
// how much total space (gap) should be placed between every two words?
int gapSpacing = 0;
if (word == _words.length) {
// don't justify at all on last line
gapSpacing = space;
} else if (wordsInLine != 1) {
gapSpacing = (fieldWidth - (lineWordWidths - wordsInLine * space)) / (wordsInLine - 1);
}
int x = 0;
// now actually draw the words, with added spacing
for (int j = word - wordsInLine; j < word; j++) {
int span = g.drawText(_words[j], x, y);
x += span + gapSpacing;
}
y += fontHeight;
}
_height = y;
}
}
The above code makes use of a String split() method. You can find one possible implementation here.
Then, use the class like this:
public LabelScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);
String loremIpsum = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam cursus. Morbi ut mi. Nullam enim leo, egestas id, condimentum at, laoreet mattis, massa. Sed eleifend nonummy diam. Praesent mauris ante, elementum et, bibendum at, posuere sit amet, nibh. Duis tincidunt lectus quis dui viverra vestibulum. Suspendisse vulputate aliquam dui. Nulla elementum dui ut augue. Aliquam vehicula mi at mauris. Maecenas placerat, nisl at consequat rhoncus, sem nunc gravida justo, quis eleifend arcu velit quis lacus. Morbi magna magna, tincidunt a, mattis non, imperdiet vitae, tellus. Sed odio est, auctor ac, sollicitudin in, consequat vitae, orci. Fusce id felis. Vivamus sollicitudin metus eget eros.";
JustifiedLabelField label = new JustifiedLabelField(loremIpsum, Field.NON_FOCUSABLE);
add(label);
}
producing this:
Limitations
I don't do anything to account for things like padding in this field
LabelField allows you to call setText() or the constructor, with other types, not just String. My class only supports String, but you could easily expand that.
My class splits the string on spaces (' ') only. You may want to support splitting on other characters, or even inserting dashes to break really long words. I'll leave that to you.
I didn't test any edge cases, like words that were longer than could fit in the field width. I only tested this with a full screen width field, with small to medium-sized words.
see Eugen's comments on the page I link to for the split() method used
Follow-Up
I refined the code posted above a bit, and posted it online here. The newer version should handle padding, which this version does not. It should also handle vertical size issues if you pick a string splitting algorithm that changes how many lines the LabelField superclass thinks the field should have. More comments, too.

use graphics.drawText(String, x, y) to draw a string on several lines

I am making a custom Field representing an image and a label near it.
I am drawing the image by graphics.drawBitmap(...)
Nw for the text, I am using graphics.drawText(String, x, y); but if the text it bigger than the display, it doesn't return to the line. I tried to add \n but that didn't solve the problem.
How can I draw a text that can expand on several lines?
Thanks,
I found a solution to the problem. You can find it below for those who are interested in this question:
public void drawMultipleLines(Graphics graphics, String text, int X, int Y, int XavailableSpace) {
String[] texts = UiSpliter.split(text, " "); //UiSpliter is a class that will split the string into string array based on the ' ' character
int x = X;
int y = Y;
for (int i = 0 ; i < texts.length ; i ++) {
if (x + getFont().getAdvance(texts[i]) - X > XavailableSpace) {
if (!(x == X)) {
x = X;
y = y + getFont().getHeight();
}
}
graphics.drawText(texts[i] + " ", x, y);
x += getFont().getAdvance(texts[i] + " ");
}
}
As this answer says :
The drawString method does not handle new-lines, so is drawText
You'll have to split the string on new-line characters yourself and draw the lines one by one with a proper vertical offset.See that answer for details.
You can use AttributedCharacterIterator,TextLayout and LineBreakMeasurer classes as explained in this Java Tutorial.

Resources