I try to use mouse up and mouse down to draw rectangles on bitmaps. But the problem is that the rectangle always delay one event. For example, I try to draw a rectangle (0,0,50,50) in the first time but there is no rectangle drawing on bitmap. I continues drawing a rect (50,50,100,100) but a rect (0,0,50,50) created (not be the rect (50,50,100,100). If I keep to draw next rects, it always delay like that. Please help me!
This is my code:
Rectangle rect = new Rectangle(0, 0, 0, 0);
int Xmouse;
int Ymouse;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
this.DoubleBuffered = true;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Xmouse = e.X;
Ymouse = e.Y;
drawOK = true;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (drawOK)
{
drawOK = false;
rect = new Rectangle(Xmouse * 3676 / 800, Ymouse * 3676 / 800, (e.X - Xmouse) * 3676 / 800, (e.Y - Ymouse) * 3676 / 800);
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (var g = Graphics.FromImage(pictureBox1.Image))
{
using (Pen myPen = new Pen(Color.Black, 6))
{
g.DrawRectangle(myPen, rect);
}
}
}
Try moving your draw method outside of paint into a different sub and call that sub manually from mouse up:
Rectangle rect = new Rectangle(0, 0, 0, 0);
int Xmouse;
int Ymouse;
bool drawOK;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Xmouse = e.X;
Ymouse = e.Y;
Console.WriteLine("MouseDown({0},{1})", e.X, e.Y);
drawOK = true;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (drawOK)
{
drawOK = false;
Console.WriteLine("MouseUp({0},{1})", e.X, e.Y);
rect = new Rectangle(Xmouse , Ymouse , (e.X - Xmouse) , (e.Y - Ymouse) );
DrawRect();
pictureBox1.Invalidate();
}
}
private void DrawRect()
{
Console.WriteLine("drawing {0}", rect);
using (var g = Graphics.FromImage(pictureBox1.Image))
{
using (Pen myPen = new Pen(Color.Black, 6))
{
g.DrawRectangle(myPen, rect);
}
}
}
private void ClearPic()
{
using (var g = Graphics.FromImage(pictureBox1.Image))
{
using (Brush myPen = Brushes.White)
{
g.Clear(Color.White);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
Image bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = bmp;
ClearPic();
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
pictureBox1.MouseDown += pictureBox1_MouseDown;
pictureBox1.MouseUp += pictureBox1_MouseUp;
}
Related
so I'm creating an interactive story, and I want to switch between scenes by clicking buttons (like a standard old pokemon game except there isn't movement, just clicking).
I should probably use a switch statement right? But I don't know how to implement the changing of scenes and loading scenes into the cases. I also don't know if I would need to use 'if' statements within the cases.
This might be confusing, because it is very confusing to me. I'd appreciate any help you guys offer! I am desperate ;)
Code so far is below:
//PImages
PImage startScreen;
PImage[] waves = new PImage[3];
PImage[] scenes = new PImage[1];
int switchVariable;
//Objects
Button play;
void setup() {
size(750, 600);
background(#A3E9EA);
//Initialising Objects
play = new Button(50, 480, 330);
//loading wave images
waves[0] = loadImage("wave1.png");
waves[1] = loadImage("wave2.png");
waves[2] = loadImage("wave3.png");
//loading start image
startScreen = loadImage("start-screen.png");
//loading scenes
scenes[0] = loadImage("scene-one.png");
//setting frame rate
frameRate(6);
}
void draw() {
background(#A3E9EA);
frameCount++;
println (frameCount);
//drawing wave animation
if (frameCount < 5) {
image(waves[0], 0, 0);
}
else {
image(waves[1], 0, 0);
}
if (frameCount < 15 & frameCount > 10) {
background(#A3E9EA);
image(waves[2], 0, 0);
frameCount = 0;
}
//drawing start screen
image(startScreen, 0, 0);
//displaying play button
if (play.visible) play.buttonDisplay();
}
void mousePressed() {
if (play.visible) {
float d = dist(play.x+110, play.y+22, mouseX, mouseY);
if (d <= play.radius){
background(#A3E9EA);
image(scenes[0], 0, 0);
}
}
}
Button Class:
class Button {
float radius;
float x;
float y;
PImage[] buttonImage = new PImage[2];
boolean visible;
Button(float _radius, float _x, float _y) {
radius = _radius;
visible = true;
x = _x;
y = _y;
buttonImage[0] = loadImage("play-game-button.png");
}
void buttonDisplay() {
image(buttonImage[0], x, y);
}
}
The source code below shows one possible approach to your question. It does not rely on ‘switch’ but instead uses a custom control with up and down buttons similar to a Java stepper. The stepper control value corresponds with images in the scenes array and the background() is set accordingly. A separate button class is required and code for this follows the demo.
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
color GREEN = color(0, 255, 0);
color ORANGE = color(247, 168, 7);
PFont font;
PImage[] scenes = new PImage[6];
// **** Up/Down Buttons init, min, max values **** //
final int _initValue = 2;
final int _maxValue = 5;
final int _minValue = 0;
int stepperValue = 0;
Button _up;
Button _dwn;
Button _quit;
final int _displayX = 160;
final int _displayY = 30;
final int _displayW = 100;
final int _displayH = 24;
final int _txtSize = 18;
void stepperValueDisplay(int value) {
fill(WHITE); // background color
noStroke();
rect(_displayX, _displayY, _displayW, _displayH, 0);
fill(BLACK); // text color
textSize(_txtSize);
textAlign(CENTER);
String str = String.format("Scene %d", value);
text(str, _displayX, _displayY, _displayW, _displayH);
}
void scene_0(){
background(RED);
save("scene0.png");
}
void scene_1(){
background(GREEN);
save("scene1.png");
}
void scene_2(){
background(BLACK);
save("scene2.png");
}
void scene_3(){
background(YELLOW);
save("scene3.png");
}
void scene_4(){
background(LTGRAY);
save("scene4.png");
}
void scene_5(){
background(ORANGE);
save("scene5.png");
}
void setup() {
size(600, 600);
background(BLUE);
font = createFont("Menlo-Bold", 20);
_dwn = new Button( _displayX - 40, _displayY, 40, 24, "--", LTGRAY, BLACK);
_up = new Button( _displayX + _displayW, _displayY, 40, 24, "++", LTGRAY, BLACK);
stepperValue = _initValue;
_quit = new Button(width - 60, 20, 30, 24, "Q", LTGRAY, BLACK);
scene_0();
scene_1();
scene_2();
scene_3();
scene_4();
scene_5();
scenes[0] = loadImage("scene0.png");
scenes[1] = loadImage("scene1.png");
scenes[2] = loadImage("scene2.png");
scenes[3] = loadImage("scene3.png");
scenes[4] = loadImage("scene4.png");
scenes[5] = loadImage("scene5.png");
}
void draw() {
background(scenes[stepperValue]);
_up.display();
_dwn.display();
_quit.display();
stepperValueDisplay(stepperValue);
}
void mousePressed() {
if (mouseX > _quit.x && mouseX < _quit.x + _quit.w && mouseY > _quit.y && mouseY < _quit.y + _quit.h) {
exit();
}
if (mouseX > _up.x && mouseX < _up.x + _up.w && mouseY > _up.y && mouseY < _up.y + _up.h) {
stepperValue++;
if (stepperValue > _maxValue) {
stepperValue = _maxValue;
}
stepperValueDisplay(stepperValue);
}
if (mouseX > _dwn.x && mouseX < _dwn.x + _dwn.w && mouseY > _dwn.y && mouseY < _dwn.y + _dwn.h) {
stepperValue--;
if (stepperValue < _minValue) {
stepperValue = _minValue;
}
stepperValueDisplay(stepperValue);
}
}
Button Class:
int _btnTxtSize = 18;
class Button {
float x, y, w, h;
String title;
color bkgrndColor;
color txtColor;
// Constructor
Button(int xpos, int ypos, float wt, float ht, String titleStr, color background, color textColor) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = titleStr;
bkgrndColor = background;
txtColor = textColor;
}
void display(){
fill(bkgrndColor);
noStroke();
rect( x, y, w, h, 0);
fill(txtColor);
textSize(_btnTxtSize);
textAlign(CENTER);
text(title, x, y, w, h);
}
}
I am having trouble understanding what approach to take to customize my own Toolbar in Xamarin.ios. The Navigation controller comes with its own default toolbar but how can i change the height and have my own buttons, background image.
What is the best approach for the above ?
You can create a custom navigationBar as you want .
public class xxxViewController: UIViewController
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NavigationController.NavigationBar.Hidden = true;
double height = IsiphoneX();
UIView backView = new UIView()
{
BackgroundColor = UIColor.White,
Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height),
};
UIButton backBtn = new UIButton() {
Frame = new CGRect(20, height-44, 40, 44),
Font = UIFont.SystemFontOfSize(18),
} ;
backBtn.SetTitle("Back", UIControlState.Normal);
backBtn.SetTitleColor(UIColor.Blue, UIControlState.Normal);
backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside);
UILabel titleLabel = new UILabel() {
Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height),
Font = UIFont.SystemFontOfSize(20),
Text = "xxx",
TextColor = UIColor.Black,
Lines = 0,
};
UILabel line = new UILabel() {
Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
BackgroundColor = UIColor.Black,
};
backView.AddSubview(backBtn);
backView.AddSubview(titleLabel);
backView.AddSubview(line);
View.AddSubview(backView);
}
double IsiphoneX()
{
double height = 44;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 64;
}
}
return height;
}
[Export("GoBack")]
void GoBack()
{
NavigationController.PopViewController(true);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NavigationController.NavigationBar.Hidden = false;
}
}
You can set the property of title , backButton and navigationBar as you need (such as text , color ,BackgroundColor ,font e.g.)
With a left mouse click then mouse moved, a line is drawned on this line chart, and also on axis.
I would like to draw line only on chart so that it does not overlap x or y axis. How to accomplish this?
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;
public class LinesEdit extends Application {
Path path;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis(1, 21, 0.1);
yAxis.setTickUnit(1);
yAxis.setPrefWidth(35);
yAxis.setMinorTickCount(10);
yAxis.setSide(Side.RIGHT);
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
#Override
public String toString(Number object) {
String label;
label = String.format("%7.2f", object.floatValue());
return label;
}
});
final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
lineChart.setCreateSymbols(false);
lineChart.setAlternativeRowFillVisible(false);
lineChart.setLegendVisible(false);
XYChart.Series series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Jan", 1));
series1.getData().add(new XYChart.Data("Feb", 4));
series1.getData().add(new XYChart.Data("Mar", 2.5));
series1.getData().add(new XYChart.Data("Apr", 5));
series1.getData().add(new XYChart.Data("May", 6));
series1.getData().add(new XYChart.Data("Jun", 8));
series1.getData().add(new XYChart.Data("Jul", 12));
series1.getData().add(new XYChart.Data("Aug", 8));
series1.getData().add(new XYChart.Data("Sep", 11));
series1.getData().add(new XYChart.Data("Oct", 13));
series1.getData().add(new XYChart.Data("Nov", 10));
series1.getData().add(new XYChart.Data("Dec", 20));
BorderPane bp = new BorderPane();
bp.setCenter(lineChart);
Scene scene = new Scene(bp, 800, 600);
lineChart.setAnimated(false);
lineChart.getData().addAll(series1);
LinesEdit.MouseHandler mh = new LinesEdit.MouseHandler( bp );
bp.setOnMouseClicked( mh );
bp.setOnMouseMoved( mh );
stage.setScene(scene);
path = new Path();
path.setStrokeWidth(1);
path.setStroke(Color.BLACK);
scene.setOnMouseDragged(mh);
scene.setOnMousePressed(mh);
bp.getChildren().add(path);
stage.setScene(scene);
stage.show();
}
class MouseHandler implements EventHandler< MouseEvent > {
private boolean gotFirst = false;
private Line line;
private Pane pane;
private double x1, y1, x2, y2;
private LineHandler lineHandler;
public MouseHandler( Pane pane ) {
this.pane = pane;
lineHandler = new LineHandler(pane);
}
class LineHandler implements EventHandler< MouseEvent > {
double x, y;
Pane pane;
public LineHandler(Pane pane){
this.pane = pane;
}
#Override
public void handle( MouseEvent e ) {
Line l = (Line) e.getSource();
// remove line on right click
if( e.getEventType() == MouseEvent.MOUSE_PRESSED
&& e.isSecondaryButtonDown() ) {
pane.getChildren().remove( l );
} else if( e.getEventType() == MouseEvent.MOUSE_DRAGGED
&& e.isPrimaryButtonDown() ) {
double tx = e.getX();
double ty = e.getY();
double dx = tx - x;
double dy = ty - y;
l.setStartX( l.getStartX() + dx );
l.setStartY( l.getStartY() + dy );
l.setEndX( l.getEndX() + dx );
l.setEndY( l.getEndY() + dy );
x = tx;
y = ty;
} else if( e.getEventType() == MouseEvent.MOUSE_ENTERED ) {
// just to show that the line is selected
x = e.getX();
y = e.getY();
l.setStroke( Color.RED );
} else if( e.getEventType() == MouseEvent.MOUSE_EXITED ) {
l.setStroke( Color.BLACK );
}
// should not pass event to the parent
e.consume();
}
}
#Override
public void handle( MouseEvent event ) {
if( event.getEventType() == MouseEvent.MOUSE_CLICKED ) {
if( !gotFirst ) {
x1 = x2 = event.getX();
y1 = y2 = event.getY();
line = new Line( x1, y1, x2, y2 );
pane.getChildren().add( line );
gotFirst = true;
}
else {
line.setOnMouseEntered( lineHandler );
line.setOnMouseExited( lineHandler );
line.setOnMouseDragged( lineHandler );
line.setOnMousePressed( lineHandler );
// to consume the event
line.setOnMouseClicked( lineHandler );
line.setOnMouseReleased( lineHandler );
line = null;
gotFirst = false;
}
}
else {
if( line != null ) {
x2 = event.getX();
y2 = event.getY();
// update line
line.setEndX( x2 );
line.setEndY( y2 );
}
}
}
}
}
The first thing to know is that many JavaFX UI-Element like charts consist of many underlying children. The part where you want to draw is in fact a Region that is part of a Pane that is child of the LineChart. I really recommend you to use ScenicView, because it shows exactly how your scene graph (including built-in UI-Components) looks like.
Back to your problem: your listeners should only apply to the Region which shows the actual representation of the data. That Region ends exactly where the x and y axis are. The following code will get you that Region and make it the target for your listeners:
//your previous code in start()...
Pane p = (Pane) lineChart.getChildrenUnmodifiable().get(1);
Region r = (Region) p.getChildren().get(0);
LinesEdit.MouseHandler mh = new LinesEdit.MouseHandler(r);
r.setOnMouseClicked(mh);
r.setOnMouseMoved(mh);
stage.setScene(scene);
path = new Path();
path.setStrokeWidth(1);
path.setStroke(Color.BLACK);
r.setOnMouseDragged(mh);
r.setOnMousePressed(mh);
bp.getChildren().add(path);
stage.setScene(scene);
//the following code.....
The next steps are:
1. rewrite your handler methods, so that they accept a `Region` object as parameter
2. rewrite a bit of your line-setting code. Background: you cannot add objects into a `Region` because you cannot access the writable `List` of childrens. So you have to put the lines into the `Pane` object which holds the `Region`. Because every JavaFX UI-Element has its own coordinate system, you have to calculate the offset between the `Pane` and the `Region`, because the `Pane` is a bit larger. If you don't do this, your line will be drawn slightly above the mousepointer. You can get the width and height of a `Pane` and/or `Region` by calling `xyz.getBoundsInLocal().getWidth()/height()`.
UPDATE: Full Solution as requested
As requested in the comments i will show one way to solve this problem. Have a look at your GUI in this picture. It shows all graphical elements in ScenicView. As you can see, the Pane is bigger than the inner Region. Important for us is to know that the origin of all coordinate systems in JavaFX start at the upper left corner of an element. In this scenario, you have to add a line to the Pane, but in respect to the borders of the Region. In the code-snippet i showed earlier i added all of your listeners to the region, which means we get the mouse coordinates inside the coordinate system of the region. Now we have to "translate" or better "transform" these coordinates (the points you wish to set the start or endpoints of the line) into the coordinate system of the Pane (the place the line is actually placed, read above why), because we want the line to start exactly where our mouse is. There is a method you can call to get a transformation matrix: r.getLocalToParentTransform(). We need this matrix because we have to get the exact values for the x and y translation that is applied to the Region (you can see that the Region is approximatly 10 pixels moved from the Panes origin in both x and y axes)
I wrote a simple method for getting the x and y translation between the Region and the Pane: getCoordDiff(Region r, Pane p).
The rest of start() method remains unchanged (but with the changes i wrote earlier). But the handle() methods of MouseHandler and LineHandler have to be modified.
public class LinesEdit extends Application
{
Path path;
public double[] getCoordDiff(Region r, Pane p)
{
//Acquires transformation matrix and returns x and y offset/translation from parent
double[] diffs =
{ r.getLocalToParentTransform().getTx(), r.getLocalToParentTransform().getTy() };
return diffs;
}
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage stage)
{
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis(1, 21, 0.1);
yAxis.setTickUnit(1);
yAxis.setPrefWidth(35);
yAxis.setMinorTickCount(10);
yAxis.setSide(Side.RIGHT);
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis)
{
#Override
public String toString(Number object)
{
String label;
label = String.format("%7.2f", object.floatValue());
return label;
}
});
final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
lineChart.setCreateSymbols(false);
lineChart.setAlternativeRowFillVisible(false);
lineChart.setLegendVisible(false);
XYChart.Series series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Jan", 1));
series1.getData().add(new XYChart.Data("Feb", 4));
series1.getData().add(new XYChart.Data("Mar", 2.5));
series1.getData().add(new XYChart.Data("Apr", 5));
series1.getData().add(new XYChart.Data("May", 6));
series1.getData().add(new XYChart.Data("Jun", 8));
series1.getData().add(new XYChart.Data("Jul", 12));
series1.getData().add(new XYChart.Data("Aug", 8));
series1.getData().add(new XYChart.Data("Sep", 11));
series1.getData().add(new XYChart.Data("Oct", 13));
series1.getData().add(new XYChart.Data("Nov", 10));
series1.getData().add(new XYChart.Data("Dec", 20));
BorderPane bp = new BorderPane();
bp.setCenter(lineChart);
Scene scene = new Scene(bp, 800, 600);
lineChart.setAnimated(false);
lineChart.getData().addAll(series1);
Pane p = (Pane) lineChart.getChildrenUnmodifiable().get(1);
Region r = (Region) p.getChildren().get(0);
LinesEdit.MouseHandler mh = new LinesEdit.MouseHandler(r);
r.setOnMouseClicked(mh);
r.setOnMouseMoved(mh);
stage.setScene(scene);
path = new Path();
path.setStrokeWidth(1);
path.setStroke(Color.BLACK);
r.setOnMouseDragged(mh);
r.setOnMousePressed(mh);
bp.getChildren().add(path);
stage.setScene(scene);
ScenicView.show(scene);
stage.show();
}
class MouseHandler implements EventHandler<MouseEvent>
{
private boolean gotFirst = false;
private Line line;
private Region reg;
private double x1, y1, x2, y2;
private LineHandler lineHandler;
public MouseHandler(Region reg)
{
this.reg = reg;
lineHandler = new LineHandler(reg);
}
class LineHandler implements EventHandler<MouseEvent>
{
double x, y;
Region reg;
public LineHandler(Region reg)
{
this.reg = reg;
}
#Override
public void handle(MouseEvent e)
{
Line l = (Line) e.getSource();
l.setStrokeWidth(3);
// remove line on right click
if (e.getEventType() == MouseEvent.MOUSE_PRESSED && e.isSecondaryButtonDown())
{
((Pane) reg.getParent()).getChildren().remove(l);
}
else if (e.getEventType() == MouseEvent.MOUSE_DRAGGED && e.isPrimaryButtonDown())
{
double tx = e.getX();
double ty = e.getY();
double dx = tx - x;
double dy = ty - y;
l.setStartX(l.getStartX() + dx);
l.setStartY(l.getStartY() + dy);
l.setEndX(l.getEndX() + dx);
l.setEndY(l.getEndY() + dy);
x = tx;
y = ty;
}
else if (e.getEventType() == MouseEvent.MOUSE_ENTERED)
{
// just to show that the line is selected
x = e.getX();
y = e.getY();
l.setStroke(Color.RED);
}
else if (e.getEventType() == MouseEvent.MOUSE_EXITED)
{
l.setStroke(Color.BLACK);
}
// should not pass event to the parent
e.consume();
}
}
#Override
public void handle(MouseEvent event)
{
if (event.getEventType() == MouseEvent.MOUSE_CLICKED)
{
double[] diff = getCoordDiff(reg, (Pane) reg.getParent());
if (!gotFirst)
{
//add translation to start/endcoordinates
x1 = x2 = event.getX() + diff[0];
y1 = y2 = event.getY() + diff[1];
line = new Line(x1, y1, x2, y2);
line.setStrokeWidth(3);
((Pane) reg.getParent()).getChildren().add(line);
gotFirst = true;
line.setOnMouseClicked(new EventHandler<Event>()
{
#Override
public void handle(Event arg0)
{
line.setOnMouseEntered(lineHandler);
line.setOnMouseExited(lineHandler);
line.setOnMouseDragged(lineHandler);
line.setOnMousePressed(lineHandler);
// to consume the event
line.setOnMouseClicked(lineHandler);
line.setOnMouseReleased(lineHandler);
line = null;
gotFirst = false;
}
});
}
}
else
{
if (line != null)
{
double[] diff = getCoordDiff(reg, (Pane) reg.getParent());
//add translation to end coordinates
x2 = event.getX() + diff[0];
y2 = event.getY() + diff[1];
// update line
line.setEndX(x2);
line.setEndY(y2);
}
}
}
}
}
You can see the parts where i add the translation values to the lines start and endpoints. This is needed so that line really starts and ends at the points where your mouse is. I moved your code that was executed if gotFirst == true, because it prevented the user to place the line (so that it doesn't follow the cursor). Background: your cursor is now always (pixel perfect) at the end of the line , which doesn't have a 'Listener' at the moment you place it the first time. That missing listener prevents the MouseEvent-click from going to the Region. In short: the "Click" event is now always done on the line itself, thats why we need a listener before the line is finally placed.
Remaining bugs: a line cannot be placed on the yellow lines of the graph. Thats because the click-event is not triggerd on the lines. I might fix that bug at a later time, or you try yourself.
I am very new to andEngine, I want to add sprites on screen and let them move and zoom on finger touch.
Right now i am able to add multiple sprites on scene , and they can be dragged on touch.
Here is my code:
public class Main extends SimpleBaseGameActivity {
#Override
private Camera camera;
private BitmapTextureAtlas mBitmapTextureAtlas;
private ITextureRegion mFaceTextureRegion;
private ITextureRegion mFaceTextureRegion2;
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
#Override
public EngineOptions onCreateEngineOptions() {
camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true,
ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(
CAMERA_WIDTH, CAMERA_HEIGHT), camera);
return engineOptions;
}
#Override
protected void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 1024, 1600, TextureOptions.NEAREST);
// background
// this.background = new Sprite(0, 0,
// BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas,
// this, "ui_ball_1.png", 0, 0, 1, 1),
// this.getVertexBufferObjectManager());
this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this,
"ui_ball_1.png", 0, 0);
this.mFaceTextureRegion2 = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this,
"ui_ball_1.png", 0, 0);
this.mBitmapTextureAtlas.load();
// this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
/*
* this.mBitmapTextureAtlas = new
* BitmapTextureAtlas(this.getTextureManager(), 32, 32,
* TextureOptions.BILINEAR); this.mFaceTextureRegion =
* BitmapTextureAtlasTextureRegionFactory
* .createFromAsset(this.mBitmapTextureAtlas, this, "ui_ball_1.png", 0,
* 0); this.mBitmapTextureAtlas.load();
*/
}
#Override
protected Scene onCreateScene() {
/*
* this.scene = new Scene(); this.scene.attachChild(this.background);
* this.scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
* return this.scene;
*/
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene();
scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion
.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
.getHeight()) / 2;
final Sprite face = new Sprite(centerX, centerY,
this.mFaceTextureRegion, this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
face.setScale(2);
scene.attachChild(face);
scene.registerTouchArea(face);
final Sprite face2 = new Sprite(0, 0, this.mFaceTextureRegion2,
this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
face2.setScale(2);
scene.attachChild(face2);
scene.registerTouchArea(face2);
scene.setTouchAreaBindingOnActionDownEnabled(true);
return scene;
}
}
Now i want to zoom each sprite on touch, but unable to find such method like setPosition available to move sprite to a specific position. Can anyone help me in achieving this without affecting the current functionality. Any help would be appreciated, may be in form of code or some direction/method to do this.
Thanks in advance :)
you can use a EntityModifier to make your effect:
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
this.clearEntityModifiers();
this.RegisterEntityModifier(new ScaleModifier(1f,2f,4f));
//1f = time to convert the scale of sprite of 2f to 4f
//2f = initial scale
//4f = finish scale
//when you dont touch the sprite back to normal scale
if(event.getAction()== MotionEvent.ACTION_UP) {
this.clearEntityModifiers();
this.RegisterEntityModifier(new ScaleModifier(1f,4f,2f));
}
//you also can work with "MotionEvent.ACTION_DOWN" and
//MotionEvent.ACTION_MOVE
return true;
}
how to develop a crop selection control like photoshop's in c# 4.0 in widows form application.
I have a windows form application in c# 4.0 that can crop images. At first you have to draw a rectangle using mouse to select the cropped region.
private Point _pt;
private Point _pt2;
private void picBoxImageProcessing_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int ix = (int)(e.X / _zoom);
int iy = (int)(e.Y / _zoom);
//reset _pt2
_pt2 = new Point(0, 0);
_pt = new Point(ix, iy);
// pictureBox1.Invalidate();
picBoxImageProcessing.Invalidate();
}
}
private void picBoxImageProcessing_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _selecting)
{
_selecting = false;
}
}
private void picBoxImageProcessing_Paint(object sender, PaintEventArgs e)
{
if (_selecting &&_pt.X >= 0 && _pt.Y >= 0 && _pt2.X >= 0 && _pt2.Y >= 0)
{
e.Graphics.DrawRectangle(pen, _pt.X * _zoom, _pt.Y * _zoom,
(_pt2.X - _pt.X) * _zoom, (_pt2.Y - _pt.Y) * _zoom);
}
}
private void picBoxImageProcessing_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_selecting = true;
int ix = (int)(e.X / _zoom);
int iy = (int)(e.Y / _zoom);
_pt2 = new Point(ix, iy);
// pictureBox1.Invalidate();
picBoxImageProcessing.Invalidate();
}
}
there is no problem to draw the rectangle by mouse dragging. But if i want to change the height or width of the rectangle then I have to draw a new rectangle, that i don't want. I want to change the height and width of the rectangle by modifying the drawn rectangle instead of drawing a new rectangle.
I don’t want to know how to crop. I need to draw a resizable rectangle on the image as we can do in photoshop.
So I need a crop selection control like photoshop's crop control.