When using the following code
public static boolean isDown;
public boolean keyDown(int key) {
if (key == Keys.SPACE) {
isDown = true;
KeyMethods.testKeyDown();
}
if (key == Keys.DOWN) {
KeyMethods.testKeyPressed();
}
return false;
}
public boolean keyUp(int key) {
if (key == Keys.SPACE) {
isDown = false;
}
return false;
}
The keyUp is not setting the isDow to false. The testKeyDown:
public static void testKeyDown() {
while (GameKeyListener.isDown) {
System.out.println("Down");
}
}
It just creates an infinite loop. Is there any other way to do this?
You have to return true at the very end of the keyDown/keyUp methods. this indicates that the event is handled.
Related
I'm trying to use Topshelf Framework to create a windows service. But when i try to start the service, there is this exception :
" The service failed to start... System.Service.Process.TimeoutException : the waiting period has expired and the operation has not been completed"
This is my code :
public class MyService : ServiceControl
{
private System.Timers.Timer _timer;
public void MyService()
{
_timer = new System.Timers.Timer(10);
_timer.AutoReset = false;
_timer.Elapsed += new ElapsedEventHandler(TimerOnElapsed);
}
private void TimerOnElapsed(object source, ElapsedEventArgs e)
{
//all the operation to do at the startup
}
public bool Start(HostControl hostControl)
{
_timer.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
_timer.Stop();
return true;
}
}
Thanks for any help :)
There are several issues I notice:
The current code would make the timer fire only once (you have AutoReset = false)
with TopShelf, the MyService class should look like this:
using System.Timers;
using Topshelf;
namespace TopShelfTestService
{
public class MyService
{
private System.Timers.Timer _timer;
public MyService()
{
_timer = new System.Timers.Timer(10);
_timer.AutoReset = true;
_timer.Elapsed += new ElapsedEventHandler(TimerOnElapsed);
}
private void TimerOnElapsed(object source, ElapsedEventArgs e)
{
//all the operation to do at the startup
}
public bool Start(HostControl hostControl)
{
_timer.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
_timer.Stop();
return true;
}
}
}
and the console app/ Program.cs will look like so:
using Topshelf;
namespace TopShelfTestService
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service<MyService>(s =>
{
s.ConstructUsing(name => new MyService());
s.WhenStarted((tc, hostControl) => tc.Start(hostControl));
s.WhenStopped((tc, hostControl) => tc.Stop(hostControl));
});
x.RunAsLocalSystem();
x.SetDescription("Sample Topshelf Host"); //7
x.SetDisplayName("Test Service with TopShelf"); //8
x.SetServiceName("TopShelfTestService");
});
}
}
}
I want to create keyboard shortcuts in my application, for instance Ctrl+C for copy. Also I want to ignore that shortcut if a TextBox has focus.
First you need a way to check if control key is pressed. CoreWindow.GetKeyState will do the job but might be a little bit tricky to use so I created an helper class:
public class ModifierKeys
{
#region ShiftIsDown property
public static bool ShiftIsDown
{
get
{
return (Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift) & CoreVirtualKeyStates.Down) != 0;
}
}
public static bool OnlyShiftIsDown
{
get
{
return ShiftIsDown && !AltIsDown && !ControlIsDown;
}
}
#endregion
#region AltIsDown property
public static bool AltIsDown
{
get
{
return (Window.Current.CoreWindow.GetKeyState(VirtualKey.Menu) & CoreVirtualKeyStates.Down) != 0;
}
}
public static bool OnlyAltIsDown
{
get
{
return !ShiftIsDown && AltIsDown && !ControlIsDown;
}
}
#endregion
#region ControlIsDown property
public static bool ControlIsDown
{
get
{
return (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) & CoreVirtualKeyStates.Down) != 0;
}
}
public static bool OnlyControlIsDown
{
get
{
return !ShiftIsDown && !AltIsDown && ControlIsDown;
}
}
#endregion
#region NoModifierKeyIsDown property
public static bool NoModifierKeyIsDown
{
get
{
return !ShiftIsDown && !AltIsDown && !ControlIsDown;
}
}
#endregion
}
Now in OnNavigateTo/From in your page subscribe/unsubscribe on key down events:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
/*...*/
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
/*...*/
Window.Current.CoreWindow.KeyDown -= CoreWindow_KeyDown;
}
The CoreWindow_KeyDown will then looks something like this:
void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args)
{
var focusedElement = FocusManager.GetFocusedElement();
if (args.KeyStatus.WasKeyDown == false && ModifierKeys.OnlyControlIsDown &&
!(focusedElement is TextBox)
)
{
if (args.VirtualKey == VirtualKey.X)
{
/*...cut...*/
}
else if (args.VirtualKey == VirtualKey.V)
{
/*...paste...*/
}
else if (args.VirtualKey == VirtualKey.C)
{
/*...copy...*/
}
}
}
I tried to bind a widget to a viewmodel property but I'm getting an exception
MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature
[0:] MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature
04-26 21:02:15.380 I/mono-stdout(32490): MvxBind:Warning: 14.76 Failed to create target binding for binding Signature for Order.ClientSignature
The widget is courtesy of Al taiar
The axml is
<SignatureWidget
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="#+id/signatureWidget1"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:layout_marginBottom="5dp"
local:MvxBind="Signature Order.ClientSignature" />
The code for the view is
using Android.Content;
using Android.Graphics;
using Android.Util;
using Android.Views;
using Core.Models;
using System;
public class SignatureWidget
: View
{
#region Implementation
private Bitmap _bitmap;
private Canvas _canvas;
private readonly Path _path;
private readonly Paint _bitmapPaint;
private readonly Paint _paint;
private float _mX, _mY;
private const float TouchTolerance = 4;
#endregion
public Signature Signature;
public event EventHandler SignatureChanged;
public SignatureWidget(Context context, IAttributeSet attrs)
: base(context, attrs)
{
Signature = new Signature();
_path = new Path();
_bitmapPaint = new Paint(PaintFlags.Dither);
_paint = new Paint
{
AntiAlias = true,
Dither = true,
Color = Color.Argb(250, 00, 0, 0)
};
_paint.SetStyle(Paint.Style.Stroke);
_paint.StrokeJoin = Paint.Join.Round;
_paint.StrokeCap = Paint.Cap.Round;
_paint.StrokeWidth = 5;
}
protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
{
base.OnSizeChanged(w, h, oldw, oldh);
_bitmap = Bitmap.CreateBitmap(w, (h > 0 ? h : ((View)this.Parent).Height), Bitmap.Config.Argb8888);
_canvas = new Canvas(_bitmap);
}
protected override void OnDraw(Canvas canvas)
{
canvas.DrawColor(Color.White);
canvas.DrawBitmap(_bitmap, 0, 0, _bitmapPaint);
canvas.DrawPath(_path, _paint);
}
private void TouchStart(float x, float y)
{
_path.Reset();
_path.MoveTo(x, y);
_mX = x;
_mY = y;
Signature.AddPoint(SignatureState.Start, (int)x, (int)y);
}
private void TouchMove(float x, float y)
{
float dx = Math.Abs(x - _mX);
float dy = Math.Abs(y - _mY);
if (dx >= TouchTolerance || dy >= TouchTolerance)
{
_path.QuadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
Signature.AddPoint(SignatureState.Move, (int)x, (int)y);
_mX = x;
_mY = y;
}
}
private void TouchUp()
{
if (!_path.IsEmpty)
{
_path.LineTo(_mX, _mY);
_canvas.DrawPath(_path, _paint);
}
else
{
_canvas.DrawPoint(_mX, _mY, _paint);
}
Signature.AddPoint(SignatureState.End, (int)_mX, (int)_mY);
_path.Reset();
}
public override bool OnTouchEvent(MotionEvent e)
{
var x = e.GetX();
var y = e.GetY();
switch (e.Action)
{
case MotionEventActions.Down:
TouchStart(x, y);
Invalidate();
break;
case MotionEventActions.Move:
TouchMove(x, y);
Invalidate();
break;
case MotionEventActions.Up:
TouchUp();
Invalidate();
break;
}
RaiseSignatureChangedEvent();
return true;
}
public void ClearCanvas()
{
_canvas.DrawColor(Color.White);
Invalidate();
}
public Bitmap CanvasBitmap()
{
return _bitmap;
}
public void Clear()
{
ClearCanvas();
Signature.Clear();
RaiseSignatureChangedEvent();
}
private void RaiseSignatureChangedEvent()
{
var handler = SignatureChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
And the code for the model is
public class Signature
{
private List<Point> _currentPath;
private readonly List<List<Point>> _paths;
public event EventHandler PointAdded;
public Signature()
{
_currentPath = new List<Point>();
_paths = new List<List<Point>>();
}
public IReadOnlyList<IReadOnlyList<Point>> Paths
{
get { return _paths; }
}
public Point LastPoint()
{
if (_currentPath != null && _currentPath.Count > 0)
{
return _currentPath.Last();
}
return new Point(0, 0);
}
public void Clear()
{
_paths.Clear();
_currentPath.Clear();
}
public void AddPoint(SignatureState state, int x, int y)
{
if (state == SignatureState.Start)
{
_currentPath = new List<Point>();
}
if (x != 0 && y != 0)
{
_currentPath.Add(new Point(x, y));
}
if (state == SignatureState.End)
{
if (_currentPath != null)
{
_paths.Add(_currentPath);
}
}
RaisePointAddedEvent();
}
public int Length
{
get { return _paths.Count; }
}
protected void RaisePointAddedEvent()
{
if (PointAdded != null)
PointAdded(this, EventArgs.Empty);
}
}
I will need two-way binding for this widget. Anyone care to help???
I will also need to add a "Clear" text as an overlay on the view. Clicking this text will trigger a command to clear the widget. Any clue how to do this?
P.S:
I've followed the informative post and I still cannot get it to work. I've added the following.
public class SignatureWidgetSignatureTargetBinding
: MvxPropertyInfoTargetBinding<SignatureWidget>
{
public SignatureWidgetSignatureTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
View.SignatureChanged += OnSignatureChanged;
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
private void OnSignatureChanged(object sender, EventArgs eventArgs)
{
FireValueChanged(View.Signature);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
View.SignatureChanged -= OnSignatureChanged;
}
}
}
and registered using
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(SignatureWidgetSignatureTargetBinding), typeof(SignatureWidget), "Signature"));
MvvmCross will automatically bind a View property if you model it using the format:
public foo Bar {
get { /* ... your code ... */ }
set { /* ... your code ... */ }
}
public event EventHandler BarChanged;
Based on this I think your problem is that you are trying to use a field - public Signature Signature; - try using a property instead.
I think the binding mode you are looking for is also the unusual OneWayToSource instead of TwoWay
I have many buttons being populated on the stage. They are all movieclips with an on and off state on frame one and 2. The problem is when you mouse over the buttons quickly sometimes it gets stuck on the over state. Is there something i am missing?
public class SimpleRollOverButton extends MovieClip
{
private var _selected:Boolean;
public function SimpleRollOverButton()
{
// EVENTS
this.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
enable();
}
//
// PUblic functions
//
public function enable():void
{
this.selected = false;
this.gotoAndStop(1);
this.mouseEnabled = this.mouseChildren = true;
this.buttonMode = true;
}
public function disable():void
{
this.mouseEnabled = this.mouseChildren = false;
this.buttonMode = false;
}
public function onState():void
{
this.disable();
this.selected = true;
this.gotoAndStop(2);
}
public function offState():void
{
this.enable();
}
//
// Private Functions
//
protected function onClick(e:MouseEvent):void
{
onState();
}
protected function onMouseOver(e:MouseEvent):void
{
this.gotoAndStop(2);
}
protected function onMouseOut(e:MouseEvent):void
{
this.gotoAndStop(1);
}
//
// ACCESSORS
//
public function get selected():Boolean
{
return _selected;
}
public function set selected(value:Boolean):void
{
_selected = value;
}
}
You could add a listener to the stage or to the MovieClip, which contains the buttons (if it has a background, and its not transparent):
stage.addEventListener(MouseEvent.ROLL_OVER, turnThemOff);
function turnThemOff(evt:MouseEvent):void {
for (var i:int=0; i<yourButtons.length; i++) yourButtons[i].gotoAndStop(1);
}
If you move the mouse quickly away from the SWF movie, this could help:
stage.addEventListener(Event.MOUSE_LEAVE, turnThemOff);
Is it somehow possible to bind view properties to ICommand.CanExecute?
I'd for example like to be able to do something like this in a touch view:
this
.CreateBinding(SignInWithFacebookButton)
.For(b => b.Enabled)
.To((SignInViewModel vm) => vm.SignInWithFacebookCommand.CanExecute)
.Apply();
I've already read How to use CanExecute with Mvvmcross, but unfortunately it skips the questions and instead just proposes another implementation.
One way of doing this is to use your own custom button inheriting from UIButton.
For Android, I've got an implementation of this to hand - it is:
public class FullButton : Button
{
protected FullButton(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
Click += OnClick;
}
public FullButton(Context context) : base(context)
{
Click += OnClick;
}
public FullButton(Context context, IAttributeSet attrs) : base(context, attrs)
{
Click += OnClick;
}
public FullButton(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
Click += OnClick;
}
private IDisposable _subscription;
private object _commandParameter;
public object CommandParameter
{
get { return _commandParameter; }
set
{
_commandParameter = value;
UpdateEnabled();
}
}
private ICommand _command;
public ICommand Command
{
get { return _command; }
set
{
if (_subscription != null)
{
_subscription.Dispose();
_subscription = null;
}
_command = value;
if (_command != null)
{
var cec = typeof (ICommand).GetEvent("CanExecuteChanged");
_subscription = cec.WeakSubscribe(_command, (s, e) =>
{
UpdateEnabled();
});
}
UpdateEnabled();
}
}
private void OnClick(object sender, EventArgs eventArgs)
{
if (Command == null)
return;
if (Command.CanExecute(CommandParameter))
Command.Execute(CommandParameter);
}
private void UpdateEnabled()
{
Enabled = ShouldBeEnabled();
}
private bool ShouldBeEnabled()
{
if (_command == null)
return false;
return _command.CanExecute(CommandParameter);
}
}
and this can be bound as:
<FullButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Show Detail"
local:MvxBind="Command ShowDetailCommand; CommandParameter CurrentItem" />
For iOS, I'd expect the same type of technique to work... inheriting from a UIButton and using TouchUpInside instead of Click - but I'm afraid I don't have this code with me at the moment.