I created a custom TextView that is displayed in a GridView. When the user taps on the TextView, a black circle has to be displayed in the center of this TextView. Actually this used to work fine on my tablet (an ASUS TF300, something like that). FYI all clicked textviews are then saved in a local database and can be loaded again.
I also tested that on a smartphone. Weird thing : the black circle is not displayed after a tap. However I know that it works because the black circles are well displayed if I save my UI and reload it again.
Did I miss something ?
Please find the code of the custom TextView below.
public class ChordItemTextView extends TextView {
// Properties
private ChordItem item;
public void setChordItem(ChordItem item)
{
this.item = item;
}
private Paint fretPaint;
private Paint chordPaint;
private Paint textPaint;
private int paperColor;
public ChordItemTextView(Context context) {
super(context);
this.Init(context);
}
public ChordItemTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
this.Init(context);
}
private void Init(Context context)
{
// Resources retrieval
Resources myResources = getResources();
this.fretPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.fretPaint.setColor(myResources.getColor(R.color.fretColor));
this.chordPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.chordPaint.setColor(myResources.getColor(R.color.fretColor));
this.textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.textPaint.setColor(myResources.getColor(R.color.fretIndication));
this.textPaint.setTextSize(myResources.getDimension(R.dimen.fretFontSize));
this.paperColor = myResources.getColor(R.color.bgColor);
}
#Override
protected void onDraw(Canvas canvas) {
// paper color
canvas.drawColor(this.paperColor);
// fret line drawing
canvas.drawLine(0, getMeasuredHeight() / 2, getMeasuredWidth(), getMeasuredHeight() / 2, this.fretPaint);
canvas.drawLine((float) (getMeasuredWidth() * 0.99), 0, (float) (getMeasuredWidth() * 0.99), getMeasuredHeight(), this.fretPaint);
if (this.item.getFretNumber() == 0)
{
canvas.drawLine((float)( getMeasuredWidth() * 0.95), 0, (float)( getMeasuredWidth() * 0.95), getMeasuredHeight(), this.fretPaint);
}
// "tap" drawing
if (this.item.getIsPushed())
{
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, getMeasuredHeight() / 4, this.chordPaint);
}
// fret number drawing
if (this.item.getStringNumber() == 1)
{
canvas.drawText(String.valueOf(this.item.getFretNumber()), getMeasuredWidth() / 2, getMeasuredHeight(), this.textPaint);
}
super.onDraw(canvas);
}
}
Related
I have a custom line view between a center button and 12 outer buttons, see pic.
Code block 1 is what I use to get the center points of each button combination.
Code block 2 is my 'custom drawing' , which draws the line between each set of center points, 12 lines in total.
The 12 custom lines are all inside an xml file.
The buttons and lines are passed into Public Class Drawline as in two separate arrays.
I've also created a class that uses Path to draw a triangle. this is sitting in the upper left hand corner of my graphic.
What I want.
A line between the centers of the buttons that stops short of the second end point.
I want the line between the points to end as you see between the buttons 'crispy crunchy' and 'balance'. I need help finding how to 'get' the x,y of this point. I also what to put the arrowhead on the end of the line.
public class Drawline {
public void drawLines(List<LineView> mlinesToDraw,ArrayList<Button> buttonsbalance, Context
context,Button btnbase) {
float centerXOnImage1;
double centerYOnImage1;
float centerXOfImageOnScreen1;
double centerYOfImageOnScreen1;
float centerXOnImage2;
float centerYOnImage2;
float centerXOfImageOnScreen2;
float centerYOfImageOnScreen2;
List<LineView> mLine = mlinesToDraw;
ArrayList<Button> btns = buttonsbalance;
PointF pointA;
PointF pointB;
for (int i = 0; i < mLine.size(); i++) {
Button button1 = btns.get(i + 1); //skip btnx0/btnbase
centerXOnImage1 = button1.getWidth() / 2;
centerYOnImage1 = (button1.getHeight()) / 2;//-actionBarHeight)/2;
centerXOfImageOnScreen1 = button1.getLeft()+ centerXOnImage1;
centerYOfImageOnScreen1 = button1.getTop() + (centerYOnImage1);
Button button2 = btnbase;
centerXOnImage2 = button2.getWidth() / 2;
centerYOnImage2 = (button2.getHeight()) / 2;//-actionBarHeight)/2;
centerXOfImageOnScreen2 = button2.getLeft() + centerXOnImage2;
centerYOfImageOnScreen2 = button2.getTop() + (centerYOnImage2);
pointA = new PointF(centerXOfImageOnScreen1, (float) centerYOfImageOnScreen1);
pointB = new PointF(centerXOfImageOnScreen2, (float) centerYOfImageOnScreen2);
mLine.get(i).setPointA(pointA);
mLine.get(i).setPointB(pointB);
mLine.get(i).draw();
}
}
Custom drawing class.
public class LineView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private PointF pointA,pointB;
// private void init() {
// paint.setColor(Color.BLACK);
// }
public LineView(Context context) {
super(context);
// init();
}
public LineView(Context context, AttributeSet attrs) {
super(context, attrs);
// init();
}
public LineView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// init();
}
#SuppressLint("ResourceAsColor")
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
int color = R.color.GradientStart;
paint.setColor(color);
paint.setAntiAlias(true);
paint.setStrokeWidth(6);
canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, paint);
}
public void setPointA(PointF point){
pointA=point;}
public void setPointB(PointF point){
pointB=point;}
public void draw(){
invalidate();
requestLayout();
}}
I feel like there should be an easier way to do this but I've not found it yet.
I appreciate any help.
thanks,
Jim
Because I now the angle of each outer button and the radius to the point, I was able to get the location using polar coordinates. I then used the following conversion to get the corresponding x and y coordinates.
val x = radius * Math.cos(angle);
val y = radius * Math.sin(angle);
This gave me the alternate endpoint I needed to draw the line.
I'm working on audio recording app.During recording i'm using visualizer like normal audio recording apps.But on specific time a want to draw a drawable on canvas visualizer(that is custom class extend View class).
Like this white drawable dot.
Here is my Custom view class.
public class VisualizerView extends View {
private static final int LINE_WIDTH = 1; // width of visualizer lines
private static final int LINE_SCALE = 75; // scales visualizer lines
private List<VisuallizerItem> visuallizerItems; // amplitudes for line lengths
private int width; // width of this View
private int height; // height of this View
private Paint linePaint; // specifies line drawing characteristics
//Boolean isImage=false;
// constructor
public VisualizerView(Context context, AttributeSet attrs) {
super(context, attrs); // call superclass constructor
linePaint = new Paint(); // create Paint for lines
linePaint.setColor(getResources().getColor(R.color.visualizerColor)); // set color to green
linePaint.setStrokeWidth(LINE_WIDTH); // set stroke width
}
// called when the dimensions of the View change
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w; // new width of this View
height = h; // new height of this View
visuallizerItems = new ArrayList<VisuallizerItem>();
}
// clear all amplitudes to prepare for a new visualization
public void clear() {
visuallizerItems.clear();
}
// add the given amplitude to the amplitudes ArrayList
public void addAmplitude(VisuallizerItem visuallizerItem) {
// isImage=false;
visuallizerItems.add(visuallizerItem); // add newest to the amplitudes ArrayList
// if the power lines completely fill the VisualizerView
if (visuallizerItems.size() * LINE_WIDTH >= width) {
visuallizerItems.remove(0); // remove oldest power value
}
}
public void addAmplitudeImage(VisuallizerItem visuallizerItem) {
//isImage=true;
visuallizerItems.add(visuallizerItem); // add newest to the amplitudes ArrayList
// if the power lines completely fill the VisualizerView
if (visuallizerItems.size() * LINE_WIDTH >= width) {
visuallizerItems.remove(0); // remove oldest power value
}
}
// draw the visualizer with scaled lines representing the amplitudes
#Override
public void onDraw(Canvas canvas) {
int middle = height / 2; // get the middle of the View
float curX = 0; // start curX at zero
// for each item in the amplitudes ArrayList
for (VisuallizerItem power : visuallizerItems) {
if (power.isImage == -100) {
float scaledHeight = power.amplitude / LINE_SCALE; // scale the power
curX += LINE_WIDTH; // increase X by LINE_WIDTH
// draw a line representing this item in the amplitudes ArrayList
canvas.drawLine(curX, middle + scaledHeight / 2, curX, middle
- scaledHeight / 2, linePaint);
} else {//**Here i'm trying to draw mark on canvas**
power.isImage = -100;
//TODO draw attachment image here
Paint p = new Paint();
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.yellow);
p.setColor(Color.RED);
canvas.drawBitmap(b, visuallizerItems.size(), middle, p);
}
}
}
}
This code add white mark once but remove it when onDraw calls again.
actually i want to draw a mark on canvas like above white dot.
Don't know why it remove it.Please help me
Thanks in advance
This is what I wish to achieve:
Clicky
The container color, the progress color, the progress background color and the rounded edge radius as well as the thickness should all be editable and modifiable.
How could this be achieved with a light weight custom UI element?
After days of research, I was able to achieve what was expected with clear crisp UI and with all the above requirements and flexibility. The exact above UI can be achieved and follow parameters can be achieved as well:
1. Progress Color
2. Progress background color
3. Container color (Color of container to be set by you, you can set color of rounded edges to match the container color)
4. Height and width of the progress bar to suit your needs.
Here's the code and steps to implement it:
I. Put this code in the attrs.xml file under the values folder
<declare-styleable name="SlantingProgressBar">
<attr name="slantingProgress" format="integer"/>
<attr name="borderRadius" format="integer"/>
<attr name="borderColor" format="integer"/>
<attr name="slantingProgressColor" format="string"/>
<attr name="progressBackgroundColor" format="string"/>
<attr name="slantingProgressFullColor" format="string"/>
</declare-styleable>
II. Create a java class like this:
public class SlantingProgressbar extends View {
private float height = 0;
private float width = 0;
private int borderRadius = 20;
private float progress = 0;
private int rawProgress = 0;
private static final String OPACITY_30_PERCENT = "#66";
private int roundedBorderColor;
private String backgroundColor = "";
private String progressColor = "";
private String progressFullColor = "#fc3d39";
public SlantingProgressbar(Context context) {
super(context);
}
public SlantingProgressbar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.SlantingProgressBar,
0, 0);
try {
setProgress(array.getInt(R.styleable.SlantingProgressBar_slantingProgress, 0));
setBackgroundColor(array.getString(R.styleable.SlantingProgressBar_progressBackgroundColor)); //Default color set in the method
setBorderRadius(array.getInt(R.styleable.SlantingProgressBar_borderRadius, 20));
setRoundedBorderColor(array.getInt(R.styleable.SlantingProgressBar_borderColor, 0));
setProgressColor(array.getString(R.styleable.SlantingProgressBar_slantingProgressColor));
} finally {
array.recycle();
}
}
public void setBorderRadius(int borderRadius) {
this.borderRadius = borderRadius;
}
public int getProgress() {
return rawProgress;
}
public void setProgress(int progress) {
if(progress >=0)
{
this.rawProgress = progress;
this.invalidate();
}
else
Log.e("ChlorophyllProgressBar", "Invalid 'progress' value detected, value should be between 0 and 100");
}
public void setRoundedBorderColor(int roundedBorderColor) {
if ( roundedBorderColor == 0) {
this.roundedBorderColor = getResources().getColor(R.color.white);
Log.e("CUSTOM_TAG", "Color set to White: " + this.roundedBorderColor);
return;
}
this.roundedBorderColor = roundedBorderColor;
Log.e("CUSTOM_TAG", "Color set to custom: " + this.roundedBorderColor);
}
private int getRoundedBorderColor()
{
return roundedBorderColor;
}
public void setSlantingProgressFullColor(String color)
{
if (TextUtils.isEmpty(progressFullColor)) {
this.progressFullColor = "#fc3d39";
return;
}
}
public void setBackgroundColor(String backgroundColor) {
if (TextUtils.isEmpty(backgroundColor)) {
this.backgroundColor = "#bfe8d4";
return;
}
this.backgroundColor = backgroundColor;
}
public void setProgressColor(String progressColor) {
if (TextUtils.isEmpty(progressColor)) {
this.progressColor = "#2bb673"; //Green
return;
}
this.progressColor = progressColor;
}
public float getViewHeight() {
return height;
}
public void setViewHeight(float height) {
this.height = height;
}
public float getViewWidth() {
return width;
}
public void setViewWidth(float width) {
this.width = width;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
height = getHeight();
width = getWidth();
progress = getProcessedProgress();
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor(backgroundColor));
canvas.drawPaint(paint);
paint.setColor(getProcessedProgressColor());
paint.setAntiAlias(true);
Log.d("CUSTOM_TAG", "Height: " + height);
canvas.drawRect(0, 0, progress, height, paint);
Path triangle = new Path();
triangle.setFillType(Path.FillType.EVEN_ODD);
triangle.moveTo(progress, 0);
triangle.lineTo(progress + height, 0);
triangle.lineTo(progress, height);
triangle.close();
canvas.drawPath(triangle, paint);
drawBorders(canvas, getRoundedBorderColor());
}
private void drawBorders(Canvas canvas, int color) {
float height = getHeight();
float trueWidth = getWidth();
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
//paint.setColor(getResources().getColor(R.color.white));
paint.setAntiAlias(true);
Path border = new Path();
border.moveTo(0, 0);
border.lineTo(0, height / 2);
border.quadTo(height / borderRadius, height / borderRadius, height / 2, 0);
border.lineTo(0, 0);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(0, height);
border.lineTo(height / 2, height);
border.quadTo(height / borderRadius, (height - height / borderRadius), 0, height / 2);
border.lineTo(0, height);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(trueWidth, 0);
border.lineTo(trueWidth - (height / 2), 0);
border.quadTo((trueWidth - height / borderRadius), height / borderRadius, trueWidth, height / 2);
border.lineTo(trueWidth, 0);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(trueWidth, height);
border.lineTo(trueWidth - (height / 2), height);
border.quadTo((trueWidth - height / borderRadius), (height - height / borderRadius), trueWidth, height / 2);
border.lineTo(trueWidth, height);
canvas.drawPath(border, paint);
//Adding 1 pixel color
Paint paint1 = new Paint();
paint1.setStyle(Paint.Style.FILL);
int fadedColor = (color & 0x00FFFFFF) | 0x66000000;
Log.d("CUSTOM_TAG", "Faded Color Code: " + fadedColor);
paint1.setColor(fadedColor);
canvas.drawRect(0, 0, 1, height, paint1);
canvas.drawRect(trueWidth-1, 0, trueWidth, height, paint1);
}
private float getProcessedProgress()
{
return (rawProgress == 99) ? ((getWidth() * 98) / 100) : ((getWidth() * rawProgress) / 100);
}
private int getProcessedProgressColor()
{
if(rawProgress > 100)
{
return Color.parseColor(progressFullColor);
}
else
{
return Color.parseColor(progressColor);
}
}
}
III. To use the layout in your xml file:
<com.whatever.package.SlantingProgressbar
android:id="#+id/progressbar_detail"
android:layout_width="match_parent"
android:layout_height="#dimen/dimension1"
android:layout_alignParentLeft="true"
slanting_progress:borderColor="#color/darkgray"
android:layout_below="#id/alphacon_detail"
android:layout_marginBottom="#dimen/budget_list_item_paddingBottom"
android:progress="50" />
I'm sharing this code after a little while, so I might have missed out a thing or two, I'm pretty sure you can get that worked out, please feel free to correct me.
Explanation:
We're using the 'draw' methods in java to implement this feature. The advantage is that, drawing a UI element gives us a sharp and clear UI no matter how big or small you make it.
There might be some hardcoded values, so be sure to edit those before implementing.
Good luck and don't forget to up-vote if this post helps you. Thanks! :)
I'll post an answer here to show some improvements on your code.
You should avoid creating new objects during draw.
draw is called several times again and again to redraw your custom element and all those calls to new Paint() are creating new objects, that needs new memory allocation, and it drives the garbage collector crazy and makes your View much more resource intensive and probably will cause lag on scrolling elements such as RecyclerView.
Alternatively you should have them declared as private Paint border and then private Paint triangle, etc, etc. And then you should initialise the values of All the paints in a separate method and only if the parameters changed. An example code:
private boolean initPaint = false;
private void initPaintsIfNecessary(){
if(!initPaint) return;
initPaint = false;
triangle = new Paint();
triangle.set.... etc
border = new Paint();
border.set.... etc
}
then on all the methods setRoundedBorderColor, setProgressColor, etc. You call initPaint = true; and on the beginning of draw you call initPaintsIfNecessary();. This will avoid all the extra garbage collector work and will allow the UI of your app to run much smoother.
That also includes all the Paint inside drawBorders method.
use format="color" instead ofstring`.
Calling Color.parse(String) is a very slow call and it is very error prone. Alternatively you should the correct color element, like following:
<attr name="slantingProgressColor" format="color"/>
that not just is the correct way, but gives you a color preview on the editor, can be indexed on app style parameters and avoid this inefficient call to parse
then of course you should adjust or method appriately. For example:
setProgressColor(array.getColor(R.styleable.SlantingProgressBar_slantingProgressColor));
getColor will return an integer that can be directly used in paint.setColor(int);
I hope those tips can help you (and others in the community) to create better more efficient View elements. Happy coding!
I know this this old question to answer but this answer may helpful..
You can use drawArc method to achieve this..
RectF oval = new RectF();
oval.set(left, top ,right, bottom);
canvas.drawArc(oval, 270, 360, false, paint);
I'm having simple custom view, which should effectively work as a progressbar.
I'd like to draw it with rounded corners, but that's seems to be not working for me..Below is whole code..In this state it gets drawn correctly, but without rounded corners. Once I set the strokeCap, or the layerType, the view gets effectively blank. Does anybody know why? And how to solve my issue?
EDIT: another interesting point is that eventhough drawLine works without strokeCap, drawPath does not draw any content at all. I have been drawing to canvas many times without ever having such weird issues..damn
EDIT 2: Path too large to be rendered into a texture - this am I getting while trying to render it with drawPath (but its definitely smaller then the maxWidth/height - the view is about 32x10dips)
public class CustomViewPagerIndicator extends View {
Paint mBgPaint;
Paint mFgPaing;
private int mMax;
private int mProgress;
public CustomViewPagerIndicator(Context context) {
this(context, null, 0);
}
public CustomViewPagerIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mMax = 1;
// setLayerType(LAYER_TYPE_SOFTWARE, null);
mBgPaint = new Paint();
mBgPaint.setColor(getResources().getColor(R.color.gray_2_translucent));
mBgPaint.setStyle(Paint.Style.STROKE);
mBgPaint.setStrokeWidth(R.dimen.grid_1);
// mBgPaint.setStrokeCap(Paint.Cap.ROUND);
mBgPaint.setAntiAlias(true);
mFgPaing = new Paint();
mFgPaing.setColor(getResources().getColor(R.color.gray_1));
mFgPaing.setStyle(Paint.Style.STROKE);
mFgPaing.setStrokeWidth(R.dimen.grid_1);
// mFgPaing.setStrokeCap(Paint.Cap.ROUND);
mFgPaing.setAntiAlias(true);
}
public void setMax(int max){
mMax = max;
};
public int getMax() {
return mMax;
}
public void setProgress(int progress){
mProgress = progress;
invalidate();
}
public int getProgress() {
return mProgress;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float step = getMeasuredWidth()/mMax;
canvas.drawLine(0, getMeasuredHeight()/2, canvas.getWidth(), getMeasuredHeight()/2, mBgPaint);
canvas.drawLine(0, getMeasuredHeight()/2, step*mProgress, getMeasuredHeight()/2, mFgPaing);
}
}
The root cause of the rounded corners not showing up is they are drawn off the edge of the canvas. You draw the line from one edge of the canvas to the other. drawLine draws the line at the coordinates given and then adds the caps. In your case, there is no room left on the canvas. You need to leave room for the caps by starting and ending drawing one half of your stroke length from the edges to leave room for the caps. See the example below. I have STROKE_SIZE as constant, but you probably want to load it with getDimension() on R.dimen.grid_1.
#Override
protected void onDraw(Canvas canvas) {
float step = (canvas.getWidth()-STROKE_SIZE/2)/(float)mMax;
canvas.drawLine(STROKE_SIZE/2, getMeasuredHeight()/2, canvas.getWidth()-STROKE_SIZE/2, getMeasuredHeight()/2, mBgPaint);
if(mProgress != 0) {
canvas.drawLine(STROKE_SIZE / 2, getMeasuredHeight() / 2, step * mProgress, getMeasuredHeight() / 2, mFgPaing);
}
}
I draw a graph with canvas in android, but I want to shift it to left or right side. I don't want to scroll it, I just want to shift it in one page by which you can see the graph is shifting lively.
I would be appreciated if any body help me.
I am looking for a an answer to this question as well. I have a solution but it is to slow and uses a lot of CPU time. I am drawing two graphs with a width of 200 pixels and have the values stored in an array. I just shift the values in the array and moves them into a path.
I would be nice to have a solution where the canvas gets shifted by 1 pixel to the left and the 200th column gets drawn with the new value. With both paths are empty it takes about 2ms (Droid Incredible) to draw the paths. When the 2 paths are filled up it can take more than 40ms. This would give still 25fps but I would like to run other threads at the same time and don't want to waste CPU time.
Here is the source.
public class OSCI extends View
{
Integer[] codebuffer = new Integer[200];
Integer[] codebuffer1 = new Integer[200];
private static final String TAG = "MyActivity";
long start;
int code=0;
// private static final String TAG = "MyActivity";
public OSCI(Context context)
{
super(context);
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
public OSCI(Context context, AttributeSet attrs)
{
super(context, attrs);;
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
#Override
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.YELLOW);
Path path = new Path();
path.moveTo(0, 70);
Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(2);
paint1.setColor(Color.GREEN);
Path path1 = new Path();
path1.moveTo(0, 70);
int max = Collections.max(Arrays.asList(codebuffer));
if(max==0)max=1;
for (int a = 0; a < codebuffer.length; a++)
{
if (codebuffer[a] < 0)code=0;
code = 70 * codebuffer[a] / max;
path.lineTo(a * 2 + 2, 70 - code);
path1.lineTo(a * 2+ 2, 70 - (codebuffer1[a]));
}
start=(SystemClock.elapsedRealtime());
canvas.drawPath(path1, paint);
canvas.drawPath(path, paint1);
Log.v(TAG, " "+(SystemClock.elapsedRealtime()-start));
}
public void newValue(int value, int valuew)
{
System.arraycopy(codebuffer, 1, codebuffer, 0, 199);
codebuffer[199] = value;
System.arraycopy(codebuffer1, 1, codebuffer1, 0, 199);
codebuffer1[199] = valuew;
invalidate();
}
}