[dasher] iPhone: rewrite input filters + devices
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher] iPhone: rewrite input filters + devices
- Date: Tue, 18 Jan 2011 17:17:45 +0000 (UTC)
commit 330d097fcd5a4e41d9b29c4dccde16f2054d8ad2
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Thu Dec 2 15:34:48 2010 +0000
iPhone: rewrite input filters + devices
Specialized touch & tilt filters (only), as per android
-tilt switchable 1d/2d, hold-to-go/tap-to-start
-touch uses 'undoubled' coords for tap
Inputs obtain coords from EAGLView as reqd, rather than having pushed at them.
GUI uses checkbox not highlight; inline tilt 'calibrate' button;
module settings combines input filter, device, and iphone-specific opts
Src/iPhone/Classes/CDasherInterfaceBridge.h | 13 +-
Src/iPhone/Classes/CDasherInterfaceBridge.mm | 49 ++----
Src/iPhone/Classes/CDasherScreenBridge.h | 2 +
Src/iPhone/Classes/CDasherScreenBridge.mm | 7 +
Src/iPhone/Classes/DasherScreenCallbacks.h | 2 +
Src/iPhone/Classes/EAGLView.h | 4 +
Src/iPhone/Classes/EAGLView.mm | 23 +--
Src/iPhone/Classes/IPhoneFilters.cpp | 81 ---------
Src/iPhone/Classes/IPhoneFilters.h | 64 ++++++--
Src/iPhone/Classes/IPhoneFilters.mm | 163 ++++++++++++++++++
Src/iPhone/Classes/IPhoneInputs.h | 58 ++-----
Src/iPhone/Classes/IPhoneInputs.mm | 62 +++++--
Src/iPhone/Classes/InputMethodSelector.h | 1 -
Src/iPhone/Classes/InputMethodSelector.mm | 234 +++++++++++++++-----------
Src/iPhone/Classes/ParametersController.h | 9 +-
Src/iPhone/Classes/ParametersController.mm | 55 ++++--
Src/iPhone/Classes/PlainDragFilter.cpp | 38 ----
Src/iPhone/Classes/PlainDragFilter.h | 29 ----
Src/iPhone/Dasher.xcodeproj/project.pbxproj | 14 +-
19 files changed, 507 insertions(+), 401 deletions(-)
---
diff --git a/Src/iPhone/Classes/CDasherInterfaceBridge.h b/Src/iPhone/Classes/CDasherInterfaceBridge.h
index 52f6f32..515da97 100644
--- a/Src/iPhone/Classes/CDasherInterfaceBridge.h
+++ b/Src/iPhone/Classes/CDasherInterfaceBridge.h
@@ -10,7 +10,6 @@
#import "IPhoneInputs.h"
#import "IPhoneFilters.h"
#import "DefaultFilter.h"
-#import "PlainDragFilter.h"
#import "StylusFilter.h"
#import "Vec3.h"
@@ -23,7 +22,7 @@
/// Implements the necessary abstract methods by bridging them into Objective C
/// and sending messages onto the DasherAppDelegate.
-class CDasherInterfaceBridge : public CDasherInterfaceBase {
+class CDasherInterfaceBridge : public Dasher::CDasherInterfaceBase {
public:
@@ -39,12 +38,10 @@ public:
CDasherInterfaceBridge(DasherAppDelegate *aDasherApp);
~CDasherInterfaceBridge();
- void ChangeScreen(CDasherScreen *NewScreen);
//redefinitions to make public....
void OnUIRealised();
void NewFrame(unsigned long iTime, bool bForceRedraw);
- void NotifyTouch(screenint x, screenint y);
void SetTiltAxes(Vec3 main, float off, Vec3 slow, float off2);
bool SupportsClipboard() {return true;}
void CopyToClipboard(const std::string &strText);
@@ -72,12 +69,10 @@ private:
DasherAppDelegate *dasherApp; // objc counterpart
- CPlainDragFilter *m_pPlainDragFilter;
- CIPhone1DFilter *m_pOneDFilter;
- CIPhonePolarFilter *m_pPolarFilter;
+ CIPhoneTiltFilter *m_pTiltFilter;
+ CIPhoneTouchFilter *m_pTouchFilter;
- CMixedInput *m_pMixDevice, *m_pReverseMix;
CIPhoneMouseInput *m_pMouseDevice;
CIPhoneTiltInput *m_pTiltDevice;
-
+ UndoubledTouch *m_pUndoubledTouch;
};
diff --git a/Src/iPhone/Classes/CDasherInterfaceBridge.mm b/Src/iPhone/Classes/CDasherInterfaceBridge.mm
index 378a779..9271040 100644
--- a/Src/iPhone/Classes/CDasherInterfaceBridge.mm
+++ b/Src/iPhone/Classes/CDasherInterfaceBridge.mm
@@ -15,7 +15,9 @@
#import "CalibrationController.h"
#import "ControlManager.h"
#import "../Common/Common.h"
-
+#import "ButtonMode.h"
+#import "TwoButtonDynamicFilter.h"
+#import "TwoPushDynamicFilter.h"
#import <iostream>
#import <fcntl.h>
@@ -31,42 +33,33 @@ CDasherInterfaceBridge::CDasherInterfaceBridge(DasherAppDelegate *aDasherApp) :
void CDasherInterfaceBridge::CreateModules() {
//create the default set...a good idea?!?!
- CDasherInterfaceBase::CreateModules();
+ RegisterModule(m_pUndoubledTouch = new UndoubledTouch(m_pEventHandler, m_pSettingsStore));
RegisterModule(m_pMouseDevice =
new CIPhoneMouseInput(m_pEventHandler, m_pSettingsStore));
RegisterModule(m_pTiltDevice =
new CIPhoneTiltInput(m_pEventHandler, m_pSettingsStore));
- RegisterModule(m_pMixDevice =
- new CMixedInput(m_pEventHandler, m_pSettingsStore, m_pMouseDevice, m_pTiltDevice, MIXED_INPUT));
- RegisterModule(m_pReverseMix =
- new CMixedInput(m_pEventHandler, m_pSettingsStore, m_pTiltDevice, m_pMouseDevice, REVERSE_MIX));
- RegisterModule(m_pPlainDragFilter = new CPlainDragFilter(m_pEventHandler, m_pSettingsStore, this, 9, "Hold-down filter"));
- RegisterModule(m_pOneDFilter =
- new CIPhone1DFilter(m_pEventHandler, m_pSettingsStore, this, 16));
- RegisterModule(m_pPolarFilter =
- new CIPhonePolarFilter(m_pEventHandler, m_pSettingsStore, this, 17));
- CDasherModule *stylus = GetModuleByName("Stylus Control");
- DASHER_ASSERT(stylus && stylus->GetType() == InputMethod);
- SetDefaultInputMethod(static_cast<CInputFilter *>(stylus));
- SetDefaultInputDevice(m_pMouseDevice);
+ SetDefaultInputDevice(m_pMouseDevice);
+
+ RegisterModule(new CButtonMode(m_pEventHandler, m_pSettingsStore, this, true, 9, "Menu Mode"));
+ RegisterModule(new CButtonMode(m_pEventHandler, m_pSettingsStore, this, false, 8, "Direct Mode"));
+ RegisterModule(new CTwoButtonDynamicFilter(m_pEventHandler, m_pSettingsStore, this));
+ RegisterModule(new CTwoPushDynamicFilter(m_pEventHandler, m_pSettingsStore, this));
+
+ RegisterModule(m_pTiltFilter =
+ new CIPhoneTiltFilter(m_pEventHandler, m_pSettingsStore, this, 16, m_pMouseDevice));
+ RegisterModule(m_pTouchFilter =
+ new CIPhoneTouchFilter(m_pEventHandler, m_pSettingsStore, this, 17, m_pUndoubledTouch, m_pTiltDevice));
+ SetDefaultInputMethod(m_pTouchFilter);
}
CDasherInterfaceBridge::~CDasherInterfaceBridge() {
- if (m_pMouseDevice)
- delete m_pMouseDevice;
- if (m_pTiltDevice)
+ delete m_pMouseDevice;
delete m_pTiltDevice;
- if (m_pMixDevice)
- delete m_pMixDevice;
+ delete m_pUndoubledTouch;
//(ACL)registered input filters should be automatically free'd by the module mgr?
}
-void CDasherInterfaceBridge::NotifyTouch(screenint x, screenint y)
-{
- m_pMouseDevice->NotifyTouch(x, y);
-}
-
void CDasherInterfaceBridge::SetTiltAxes(Vec3 main, float off, Vec3 slow, float off2)
{
m_pTiltDevice->SetAxes(main, off, slow, off2);
@@ -78,12 +71,6 @@ void CDasherInterfaceBridge::SetupUI() {
void CDasherInterfaceBridge::OnUIRealised() {CDasherInterfaceBase::OnUIRealised();}
-void CDasherInterfaceBridge::ChangeScreen(CDasherScreen *pScreen) {
- CDasherInterfaceBase::ChangeScreen(pScreen);
- m_pTiltDevice->SetScreenBounds(pScreen->GetWidth(), pScreen->GetHeight());
- m_pMouseDevice->SetScreenBounds(pScreen->GetWidth(), pScreen->GetHeight());
-}
-
void CDasherInterfaceBridge::SetupPaths() {
NSString *systemDir = [NSString stringWithFormat:@"%@/", [[NSBundle mainBundle] bundlePath]];
NSString *userDir = [NSString stringWithFormat:@"%@/", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.h b/Src/iPhone/Classes/CDasherScreenBridge.h
index cd30023..9f89bd7 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.h
+++ b/Src/iPhone/Classes/CDasherScreenBridge.h
@@ -23,6 +23,8 @@ public:
CDasherScreenBridge(id<DasherScreenCallbacks> dv);
~CDasherScreenBridge();
+ bool GetTouchCoords(screenint &iX, screenint &iY);
+
// CDasherScreen methods
///
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.mm b/Src/iPhone/Classes/CDasherScreenBridge.mm
index 033d2e5..86bf200 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.mm
+++ b/Src/iPhone/Classes/CDasherScreenBridge.mm
@@ -19,6 +19,13 @@ CDasherScreenBridge::~CDasherScreenBridge() {
dasherView = nil; // didn't retain it, so don't release it.
}
+bool CDasherScreenBridge::GetTouchCoords(screenint &iX, screenint &iY) {
+ CGPoint p = dasherView.lastTouchCoords;
+ if (p.x==-1) return false;
+ iX=p.x; iY=p.y;
+ return true;
+}
+
void CDasherScreenBridge::Blank() {
[dasherView blankCallback];
}
diff --git a/Src/iPhone/Classes/DasherScreenCallbacks.h b/Src/iPhone/Classes/DasherScreenCallbacks.h
index fbc7163..362dd72 100644
--- a/Src/iPhone/Classes/DasherScreenCallbacks.h
+++ b/Src/iPhone/Classes/DasherScreenCallbacks.h
@@ -24,4 +24,6 @@ typedef struct {
-(void)setColourSchemeWithColourTable:(colour_t *)colourTable;
-(int)boundsWidth;
-(int)boundsHeight;
+
+ property (readonly,assign) CGPoint lastTouchCoords;
@end
\ No newline at end of file
diff --git a/Src/iPhone/Classes/EAGLView.h b/Src/iPhone/Classes/EAGLView.h
index af848b1..832b0ba 100644
--- a/Src/iPhone/Classes/EAGLView.h
+++ b/Src/iPhone/Classes/EAGLView.h
@@ -37,8 +37,12 @@ Note that setting the view non-opaque will only work if the EAGL surface has an
GLuint mouseTex, boxesTex;
GLshort rectcoords[8];
GLfloat texcoords[8];
+
+ CGPoint lastTouchCoords;
}
+ property (readonly,assign) CGPoint lastTouchCoords;
+
- (void)startAnimation;
- (void)stopAnimation;
- (void)drawView;
diff --git a/Src/iPhone/Classes/EAGLView.mm b/Src/iPhone/Classes/EAGLView.mm
index f0be848..e8e4a95 100644
--- a/Src/iPhone/Classes/EAGLView.mm
+++ b/Src/iPhone/Classes/EAGLView.mm
@@ -16,8 +16,6 @@
// A class extension to declare private methods
@interface EAGLView ()
- property (nonatomic, retain) EAGLContext *context;
-
- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;
@@ -26,8 +24,7 @@
@implementation EAGLView
- synthesize context;
-
+ synthesize lastTouchCoords;
// You must implement this method
+ (Class)layerClass {
@@ -69,28 +66,24 @@
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSAssert([touches count] == 1, @"Multitouch?!");
- CGPoint p = [((UITouch *)[touches anyObject]) locationInView:self];
+ lastTouchCoords = [((UITouch *)[touches anyObject]) locationInView:self];
NSAssert(!anyDown,@"Touches began when already in progress - multitouch enabled?!?!\n");
anyDown = YES;
- dasherApp.dasherInterface->NotifyTouch(p.x,p.y);
- dasherApp.dasherInterface->KeyDown(get_time(), 100, true, p.x, p.y);
+ dasherApp.dasherInterface->KeyDown(get_time(), 100, true, lastTouchCoords.x, lastTouchCoords.y);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- CGPoint p = [[touches anyObject] locationInView:self];
- dasherApp.dasherInterface->NotifyTouch(p.x,p.y);
+ lastTouchCoords = [[touches anyObject] locationInView:self];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSAssert([touches count] == 1, @"Multitouch?!");
NSAssert(anyDown,@"Touches ended when not in progress - multitouch enabled?!?!\n");
- UITouch *touch = [touches anyObject];
- CGPoint p = [touch locationInView:self];
- dasherApp.dasherInterface->NotifyTouch(p.x,p.y);
- anyDown = NO;
- dasherApp.dasherInterface->KeyUp(get_time(), 100, true, p.x, p.y);
+ lastTouchCoords = [(UITouch *)[touches anyObject] locationInView:self];
+ dasherApp.dasherInterface->KeyUp(get_time(), 100, true, lastTouchCoords.x, lastTouchCoords.y);
//finished dealing with touch-up event. Finger is now officially off the screen...
- dasherApp.dasherInterface->NotifyTouch(-1, -1);
+ lastTouchCoords.x = lastTouchCoords.y = -1;
+ anyDown = NO;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
diff --git a/Src/iPhone/Classes/IPhoneFilters.h b/Src/iPhone/Classes/IPhoneFilters.h
index 439f0a8..f98225a 100644
--- a/Src/iPhone/Classes/IPhoneFilters.h
+++ b/Src/iPhone/Classes/IPhoneFilters.h
@@ -8,30 +8,68 @@
*/
#include "OneDimensionalFilter.h"
+#include "StylusFilter.h"
+#include "IPhoneInputs.h"
using namespace Dasher;
-#define ONE_D_FILTER "IPhone1D Filter"
-#define POLAR_FILTER "Polar Filter"
-class CIPhone1DFilter : public COneDimensionalFilter {
-public:
- CIPhone1DFilter(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID);
+ class NSUserDefaultsObserver;
- virtual bool Timer(int iTime, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
+class IPhonePrefsObserver {
+public:
+ virtual void iPhonePrefsChanged(NSString *key)=0;
protected:
- virtual void ApplyTransform(myint &iDasherX, myint &iDasherY);
+ void ObserveKeys(NSString *key,...);
+ ~IPhonePrefsObserver();
private:
- int m_iSlow;
- double m_dRad;
+ NSUserDefaultsObserver *obsvr;
};
+#ifndef __IPHONE_FILTERS_MM__
+extern NSString *HOLD_TO_GO;
+extern NSString *TILT_1D;
+extern NSString *TILT_USE_TOUCH_X;
+extern NSString *TOUCH_USE_TILT_X;
+#endif
-class CIPhonePolarFilter : public COneDimensionalFilter {
+#define TILT_FILTER "IPhone Tilt Filter"
+#define TOUCH_FILTER "IPhone Touch Filter"
+class CIPhoneTiltFilter : public COneDimensionalFilter, private IPhonePrefsObserver {
public:
- CIPhonePolarFilter(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID);
-
+ CIPhoneTiltFilter(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, CDasherInput *pTouch);
+ ///override to enable hold-to-go
virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
+ ///override to enable hold-to-go
virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
+
+ ///respond to BP_DASHER_PAUSED by engaging wakelock (if !hold-to-go)
+ virtual void HandleEvent(CEvent *pEvent);
+ void iPhonePrefsChanged(NSString *key);
+ bool supportsPause();
protected:
- virtual void ApplyTransform(myint &iDasherX, myint &iDasherY);
+ ///Override to choose whether to apply 1D transform or not, and to get X coord from touch if appropriate
+ virtual void ApplyTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView);
+ ///Never apply offset (just eyetracker remapping!) - otherwise would be done when operating in 2d mode
+ virtual void ApplyOffset(myint &iDasherX, myint &iDasherY);
+
+private:
+ CDasherInput *m_pTouch;
+ bool bHoldToGo, bUseTouchX, bTilt1D;
};
+
+class CIPhoneTouchFilter : public CStylusFilter, private IPhonePrefsObserver {
+public:
+ CIPhoneTouchFilter(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, UndoubledTouch *pUndoubledTouch, CIPhoneTiltInput *pTilt);
+
+ virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
+
+ void ApplyTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView);
+ void Activate();
+ void Deactivate();
+ void iPhonePrefsChanged(NSString *key);
+private:
+ UndoubledTouch *m_pUndoubledTouch;
+ CIPhoneTiltInput *m_pTilt;
+ bool bUseTiltX;
+};
+
/// @}
\ No newline at end of file
diff --git a/Src/iPhone/Classes/IPhoneFilters.mm b/Src/iPhone/Classes/IPhoneFilters.mm
new file mode 100644
index 0000000..be386e9
--- /dev/null
+++ b/Src/iPhone/Classes/IPhoneFilters.mm
@@ -0,0 +1,163 @@
+/*
+ * IPhoneFilters.cpp
+ * Dasher
+ *
+ * Created by Alan Lawrence on 29/04/2009.
+ * Copyright 2009 Cavendish Laboratory. All rights reserved.
+ *
+ */
+#define __IPHONE_FILTERS_MM__
+#include "IPhoneFilters.h"
+
+#include "../Common/Common.h"
+#include "DasherInterfaceBase.h"
+#include "Event.h"
+#include "CDasherScreenBridge.h"
+#include <iostream>
+
+NSString *HOLD_TO_GO=@"HoldToGo";
+NSString *TILT_1D=@"Tilt1D";
+NSString * TILT_USE_TOUCH_X=@"UseTouchX";
+NSString * TOUCH_USE_TILT_X=@"UseTiltX";
+
+ interface NSUserDefaultsObserver : NSObject {
+ IPhonePrefsObserver *po;
+}
+-(id)initForPrefsObserver:(IPhonePrefsObserver *)po;
+-(void)stopObserving;
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
+ end
+
+ implementation NSUserDefaultsObserver
+
+-(id)initForPrefsObserver:(IPhonePrefsObserver *)_po {
+ if (self = [super init]) {
+ self->po = _po;
+ }
+ return self;
+}
+
+-(void)stopObserving {po=nil; [self autorelease];}
+
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+ NSAssert(object == [NSUserDefaults standardUserDefaults],@"Only observing user defaults?");
+ if (po) po->iPhonePrefsChanged(keyPath);
+ else [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:keyPath];
+}
+ end
+
+void IPhonePrefsObserver::ObserveKeys(NSString *key,...) {
+ va_list args;
+ va_start(args, key);
+
+ obsvr = [[NSUserDefaultsObserver alloc] initForPrefsObserver:this];
+ while (key) {
+ [[NSUserDefaults standardUserDefaults] addObserver:obsvr forKeyPath:key options:0 context:nil];
+ iPhonePrefsChanged(key);
+ key=va_arg(args, NSString *);
+ }
+ va_end(args);
+}
+
+IPhonePrefsObserver::~IPhonePrefsObserver() {
+ [obsvr stopObserving];
+ [obsvr release];
+}
+
+CIPhoneTiltFilter::CIPhoneTiltFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, CDasherInput *pTouch)
+: COneDimensionalFilter(pEventHandler, pSettingsStore, pInterface, iID, TILT_FILTER), m_pTouch(pTouch) {
+ ObserveKeys(HOLD_TO_GO, TILT_USE_TOUCH_X, TILT_1D, nil);
+};
+
+void CIPhoneTiltFilter::ApplyTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+ if (bHoldToGo && bUseTouchX) {
+ myint temp;
+ m_pTouch->GetDasherCoords(iDasherX,temp,pView);
+ }
+ if (bTilt1D) {
+ COneDimensionalFilter::ApplyTransform(iDasherX, iDasherY, pView);
+ //that skips CDefaultFilter::ApplyTransform => no LP_TARGET_OFFSET/BP_AUTO_CALIBRATE or BP_REMAP_XTREME
+ } else {
+ CDefaultFilter::ApplyTransform(iDasherX, iDasherY, pView);
+ }
+}
+
+void CIPhoneTiltFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog) {
+ if(iId == 100 && bHoldToGo)
+ m_pInterface->Unpause(iTime);
+ else COneDimensionalFilter::KeyDown(iTime, iId, pView, pInput, pModel, pUserLog);
+}
+
+void CIPhoneTiltFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
+ if(iId == 100 && bHoldToGo)
+ m_pInterface->Stop();
+ else COneDimensionalFilter::KeyUp(iTime, iId, pView, pInput, pModel);
+}
+
+bool CIPhoneTiltFilter::supportsPause() {
+ return !bHoldToGo;
+}
+
+void CIPhoneTiltFilter::ApplyOffset(myint &iDasherX, myint &iDasherY) {
+ //Do not apply LP_TARGET_OFFSET, or BP_AUTO_CALIBRATE
+}
+
+void CIPhoneTiltFilter::HandleEvent(CEvent *pEvent) {
+ if (pEvent->m_iEventType == EV_PARAM_NOTIFY
+ && static_cast<CParameterNotificationEvent *>(pEvent)->m_iParameter==BP_DASHER_PAUSED
+ && m_pInterface->GetActiveInputMethod()==this) {
+ [UIApplication sharedApplication].idleTimerDisabled=(!GetBoolParameter(BP_DASHER_PAUSED) && !bHoldToGo);
+ }
+}
+
+void CIPhoneTiltFilter::iPhonePrefsChanged(NSString *key) {
+ bool val = [[NSUserDefaults standardUserDefaults] boolForKey:key];
+ if ([key isEqualToString:HOLD_TO_GO])
+ bHoldToGo = val;
+ else if ([key isEqualToString:TILT_USE_TOUCH_X])
+ bUseTouchX = val;
+ else if ([key isEqualToString:TILT_1D])
+ bTilt1D = val;
+ //Hmmm, do we need to do anything _now_?
+}
+
+CIPhoneTouchFilter::CIPhoneTouchFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, UndoubledTouch *pUndoubledTouch, CIPhoneTiltInput *pTilt)
+: CStylusFilter(pEventHandler, pSettingsStore, pInterface, iID, TOUCH_FILTER), m_pUndoubledTouch(pUndoubledTouch), m_pTilt(pTilt) {
+ ObserveKeys(TOUCH_USE_TILT_X,nil);
+
+};
+
+void CIPhoneTouchFilter::iPhonePrefsChanged(NSString *key) {
+ if ([key isEqualToString:TOUCH_USE_TILT_X]) {
+ if (m_pInterface->GetActiveInputMethod()==this) {
+ //current=new value of preference, should be different from what we have atm...
+ // (exception is at construction time -
+ DASHER_ASSERT([[NSUserDefaults standardUserDefaults] boolForKey:TOUCH_USE_TILT_X] ^ bUseTiltX);
+ if (bUseTiltX)
+ m_pTilt->Deactivate(); //setting was on, so is being turned off
+ else
+ m_pTilt->Activate();
+ }
+ bUseTiltX = [[NSUserDefaults standardUserDefaults] boolForKey:TOUCH_USE_TILT_X];
+ }
+}
+
+void CIPhoneTouchFilter::Activate() {
+ if (bUseTiltX) m_pTilt->Activate();
+}
+
+void CIPhoneTouchFilter::Deactivate() {
+ if (bUseTiltX) m_pTilt->Deactivate();
+}
+
+void CIPhoneTouchFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
+ CStylusFilter::KeyUp(iTime, iId, pView, m_pUndoubledTouch, pModel);
+}
+
+void CIPhoneTouchFilter::ApplyTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+ if (bUseTiltX) {
+ myint temp;
+ m_pTilt->GetDasherCoords(iDasherX,temp,pView);
+ }
+ CStylusFilter::ApplyTransform(iDasherX, iDasherY, pView);
+}
\ No newline at end of file
diff --git a/Src/iPhone/Classes/IPhoneInputs.h b/Src/iPhone/Classes/IPhoneInputs.h
index ef00b1b..e1093af 100644
--- a/Src/iPhone/Classes/IPhoneInputs.h
+++ b/Src/iPhone/Classes/IPhoneInputs.h
@@ -14,32 +14,13 @@
#import <deque>
#import "Vec3.h"
//A bit odd I admit, but we use the same string as is the default input device in Parameters.h...
+#define UNDOUBLED_TOUCH "Undoubled Touch"
#define TOUCH_INPUT "Mouse Input"
#define TILT_INPUT "Tilt Input"
-#define MIXED_INPUT "Mixed Inputs"
-#define REVERSE_MIX "Reverse Mix"
-namespace Dasher {
-class CIPhoneInput : public CScreenCoordInput {
-public:
- CIPhoneInput(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const char *name)
- : CScreenCoordInput(pEventHandler, pSettingsStore, 0, 0, name) {};
- void SetScreenBounds(int maxX, int maxY) {this->maxX=maxX; this->maxY=maxY;}
-
- virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
- if (m_iX==-1) return false;
- iX = m_iX;
- iY = m_iY;
-
- return true;
- };
-
-protected:
- myint m_iX, m_iY;
- int maxX, maxY;
-};
+namespace Dasher {
-class CIPhoneTiltInput : public CIPhoneInput {
+class CIPhoneTiltInput : public CScreenCoordInput {
public:
CIPhoneTiltInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore);
~CIPhoneTiltInput();
@@ -56,8 +37,11 @@ public:
void Activate();
void Deactivate();
-
+
+ bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
private:
+ screenint m_iX, m_iY;
+ int maxX, maxY;
Vec3 main, slow;
float offset, slow_off;
SBTree *xTilts, *yTilts;
@@ -65,27 +49,19 @@ private:
id<UIAccelerometerDelegate> deleg;
};
-class CIPhoneMouseInput : public CIPhoneInput {
+class UndoubledTouch : public CScreenCoordInput {
public:
- CIPhoneMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore);
-
- void NotifyTouch(screenint _iX, screenint _iY) {
- if (GetBoolParameter(BP_DOUBLE_X)) _iX = std::min(2*_iX, maxX);
- m_iX = _iX;
- m_iY = _iY;
- };
+ UndoubledTouch(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore);
+ bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
+protected:
+ UndoubledTouch(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, ModuleID_t iId, const char *szName);
};
-class CMixedInput : public CDasherInput {
+class CIPhoneMouseInput : public UndoubledTouch {
public:
- CMixedInput(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore,
- CDasherInput *pXinput, CDasherInput *pYinput, const char *name)
- : CDasherInput(pEventHandler, pSettingsStore, 0, 0, name), m_pXinput(pXinput), m_pYinput(pYinput) {};
-
- virtual bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
- void Activate();
- void Deactivate();
-private:
- CDasherInput *m_pXinput, *m_pYinput;
+ CIPhoneMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore);
+
+ bool GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView);
};
}
+
diff --git a/Src/iPhone/Classes/IPhoneInputs.mm b/Src/iPhone/Classes/IPhoneInputs.mm
index e42e564..51991fb 100644
--- a/Src/iPhone/Classes/IPhoneInputs.mm
+++ b/Src/iPhone/Classes/IPhoneInputs.mm
@@ -35,7 +35,7 @@ using namespace Dasher;
@end
CIPhoneTiltInput::CIPhoneTiltInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore)
- : CIPhoneInput(pEventHandler, pSettingsStore, TILT_INPUT) {
+ : CScreenCoordInput(pEventHandler, pSettingsStore, 8, TILT_INPUT) {
deleg = [[Accel alloc] initWithInput:this];
xTilts = NULL;
};
@@ -80,32 +80,60 @@ void CIPhoneTiltInput::NotifyTilt(float fx, float fy, float fz) {
void CIPhoneTiltInput::Activate() {
[[DasherAppDelegate theApp] setLandscapeSupported:NO];
- [UIApplication sharedApplication].idleTimerDisabled = YES;
UIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];
theAccelerometer.updateInterval = 0.01; //in secs
theAccelerometer.delegate = deleg;
}
void CIPhoneTiltInput::Deactivate() {
[[DasherAppDelegate theApp] setLandscapeSupported:YES];
- [UIApplication sharedApplication].idleTimerDisabled = NO;
[UIAccelerometer sharedAccelerometer].delegate = nil;
}
-CIPhoneMouseInput::CIPhoneMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore)
- : CIPhoneInput(pEventHandler, pSettingsStore, TOUCH_INPUT) {
-};
+bool CIPhoneTiltInput::GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+ CDasherScreen *pScreen(pView->Screen());
+ maxX = pScreen->GetWidth();
+ maxY = pScreen->GetHeight();
+
+ //could check we're active, but not bothering for now...
+ iX=m_iX; iY=m_iY;
+ return true;
+}
-bool CMixedInput::GetScreenCoords(screenint &iX, screenint &iY,CDasherView *pView) {
- screenint temp;
- if (!m_pYinput->GetScreenCoords(temp,iY,pView)) return false;
- //got y; x coord stored into temp is not needed
- return m_pXinput->GetScreenCoords(iX, temp,pView);
-};
+UndoubledTouch::UndoubledTouch(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore) : CScreenCoordInput(pEventHandler, pSettingsStore, 7, UNDOUBLED_TOUCH) {
+}
+
+UndoubledTouch::UndoubledTouch(CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, ModuleID_t iId, const char *szName) : CScreenCoordInput(pEventHandler, pSettingsStore, iId, szName) {
+}
-void CMixedInput::Activate() {
- m_pYinput->Activate(); m_pXinput->Activate();
+bool UndoubledTouch::GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+ CDasherScreenBridge *sb(static_cast<CDasherScreenBridge *>(pView->Screen()));
+ return sb->GetTouchCoords(iX, iY);
}
-void CMixedInput::Deactivate() {
- m_pYinput->Deactivate(); m_pXinput->Deactivate();
-}
\ No newline at end of file
+
+CIPhoneMouseInput::CIPhoneMouseInput(CEventHandler * pEventHandler, CSettingsStore * pSettingsStore)
+ : UndoubledTouch(pEventHandler, pSettingsStore, 9, TOUCH_INPUT) {
+};
+
+bool CIPhoneMouseInput::GetScreenCoords(screenint &iX, screenint &iY, CDasherView *pView) {
+ if (!UndoubledTouch::GetScreenCoords(iX,iY, pView)) return false;
+ CDasherScreen *scr(pView->Screen());
+ //double x/y
+ if (GetBoolParameter(BP_DOUBLE_X)) {
+ switch (GetLongParameter(LP_REAL_ORIENTATION)) {
+ case Opts::LeftToRight:
+ iX=min(iX*2, scr->GetWidth());
+ break;
+ case Opts::RightToLeft:
+ iX=max(iX*2-scr->GetWidth(), 0);
+ break;
+ case Opts::TopToBottom:
+ iY=min(iY*2, scr->GetHeight());
+ break;
+ case Opts::BottomToTop:
+ iY=max(iY*2 - scr->GetHeight(), 0);
+ break;
+ }
+ }
+ return true;
+}
diff --git a/Src/iPhone/Classes/InputMethodSelector.h b/Src/iPhone/Classes/InputMethodSelector.h
index 775be68..6242599 100644
--- a/Src/iPhone/Classes/InputMethodSelector.h
+++ b/Src/iPhone/Classes/InputMethodSelector.h
@@ -11,7 +11,6 @@
@interface InputMethodSelector : UITableViewController {
NSIndexPath *selectedPath;
- UIView *calibButton;
}
- (id)init;
diff --git a/Src/iPhone/Classes/InputMethodSelector.mm b/Src/iPhone/Classes/InputMethodSelector.mm
index 4a87746..b9b86a6 100644
--- a/Src/iPhone/Classes/InputMethodSelector.mm
+++ b/Src/iPhone/Classes/InputMethodSelector.mm
@@ -13,35 +13,35 @@
#import "DasherAppDelegate.h"
#import "CalibrationController.h"
#import "ParametersController.h"
+#import "IPhoneFilters.h"
typedef struct __FILTER_DESC__ {
NSString *title;
NSString *subTitle;
const char *deviceName;
const char *filterName;
+ ///Null-terminated list of NSUserDefaults keys for extra non-Core settings
+ NSString **iPhoneOpts;
} SFilterDesc;
-SFilterDesc asTouchFilters[] = {
- {@"Hybrid Mode", @"Tap or Hold", TOUCH_INPUT, "Stylus Control"},
- {@"Boxes", @"Tap box to select", TOUCH_INPUT, "Direct Mode"},
-};
+NSString *touchSettings[] = {TOUCH_USE_TILT_X, NULL};
+NSString *tiltSettings[] = {HOLD_TO_GO, TILT_USE_TOUCH_X, TILT_1D, NULL};
-SFilterDesc asDynamicFilters[] = {
- {@"Scanning", @"Tap screen when box highlighted", TOUCH_INPUT, "Menu Mode"},
- {@"One Button Mode", @"Tap screen when cursor near", TOUCH_INPUT, "Static One Button Mode"},
- {@"Dynamic 1B Mode", @"Tap anywhere - twice", TOUCH_INPUT, "Two-push Dynamic Mode (New One Button)"},
- {@"Dynamic 2B Mode", @"Tap Top or Bottom", TOUCH_INPUT, "Two Button Dynamic Mode"},
+NSString *calibBtn=@"Calibrate...";//pointer equality used to mark cell for special-casing in cellForRowAtIndexPath: below
+
+SFilterDesc asNormalFilters[] = {
+ {@"Touch Control", @"Tap or Hold", TOUCH_INPUT, TOUCH_FILTER, touchSettings},
+ {@"Tilt Control", calibBtn, TILT_INPUT, TILT_FILTER, tiltSettings},
};
-SFilterDesc asTiltFilters[] = {
- {@"Full 2D",@"hold-to-go", TILT_INPUT, "Hold-down filter"},
- {@"Single-axis",@"with slowdown & tap-to-start", TILT_INPUT, ONE_D_FILTER},
+SFilterDesc asBoxFilters[] = {
+ {@"Direct Mode", @"Tap box to select", TOUCH_INPUT, "Direct Mode", NULL},
+ {@"Scanning", @"Tap screen when box highlighted", TOUCH_INPUT, "Menu Mode", NULL},
};
-SFilterDesc asMixedFilters[] = {
- {@"(X,Y)", @"by (touch,tilt)", MIXED_INPUT, "Hold-down filter"},
- {@"1D-mode", @"tilt for direction, X-touch for speed", MIXED_INPUT, POLAR_FILTER},
- {@"(Y,X)", @"by (touch,tilt)", REVERSE_MIX, "Stylus Control"},
+SFilterDesc asDynamicFilters[] = {
+ {@"Dynamic 1B Mode", @"Tap anywhere - twice", TOUCH_INPUT, "Two-push Dynamic Mode (New One Button)", NULL},
+ {@"Dynamic 2B Mode", @"Tap Top or Bottom", TOUCH_INPUT, "Two Button Dynamic Mode", NULL},
};
typedef struct __SECTION_DESC__ {
@@ -51,23 +51,28 @@ typedef struct __SECTION_DESC__ {
} SSectionDesc;
SSectionDesc allMeths[] = {
-{@"Touch Control", asTouchFilters, sizeof(asTouchFilters) / sizeof(asTouchFilters[0])},
-{@"Button Modes", asDynamicFilters, sizeof(asDynamicFilters) / sizeof(asDynamicFilters[0])},
-{@"Tilt Control", asTiltFilters, sizeof(asTiltFilters) / sizeof(asTiltFilters[0])},
-{@"Combined Touch & Tilt", asMixedFilters, sizeof(asMixedFilters) / sizeof(asMixedFilters[0])},
+{@"Normal Steering", asNormalFilters, sizeof(asNormalFilters) / sizeof(asNormalFilters[0])},
+{@"Box Modes", asBoxFilters, sizeof(asBoxFilters) / sizeof(asBoxFilters[0])},
+{@"Dynamic Modes", asDynamicFilters, sizeof(asDynamicFilters) / sizeof(asDynamicFilters[0])},
};
int numSections = sizeof(allMeths) / sizeof(allMeths[0]);
+ interface ExtraParametersController : ParametersController {
+ SModuleSettings *m_pSettings2;
+ int m_iCount2;
+ NSString **iPhonePrefKeys;
+}
+-(id)initForFilter:(SFilterDesc *)filtr;
+ end
+
+
@interface InputMethodSelector ()
- property (retain) NSIndexPath *selectedPath;
-- (void)doSelect;
+-(UITableViewCellAccessoryType)accessoryTypeForFilter:(SFilterDesc *)filter;
@end
@implementation InputMethodSelector
- synthesize selectedPath;
-
- (id)init {
if (self = [super initWithStyle:UITableViewStyleGrouped]) {
self.tabBarItem.title = @"Control";
@@ -122,91 +127,73 @@ int numSections = sizeof(allMeths) / sizeof(allMeths[0]);
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return numSections + 1; //add 1 for calibrate button
+ return numSections;
}
-
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return (section==numSections) ? 0 : allMeths[section].numFilters;
+ return allMeths[section].numFilters;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- DasherAppDelegate *app = [DasherAppDelegate theApp];
- static NSString *CellIdentifier = @"Cell";
-
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- UILabel *subText;
- if (cell)
- subText = [cell viewWithTag:1];
- else {
- cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
- subText = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
- subText.tag = 1;
- [cell addSubview:subText];
- //cell.autoresizesSubviews = YES; //ineffective even if done
- [subText setAdjustsFontSizeToFitWidth:YES];
+
+ SFilterDesc *filter = &allMeths[ [indexPath section] ].filters[ [indexPath row] ];
+ UITableViewCell *cell;
+
+ if (filter->subTitle==calibBtn) {
+ static NSString *CalibCellId = @"CalibCell";
+ cell = [tableView dequeueReusableCellWithIdentifier:CalibCellId];
+ if (!cell) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CalibCellId] autorelease];
+
+ UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
+ [btn setTitle:calibBtn forState:UIControlStateNormal];
+ CGSize textSize = [calibBtn sizeWithFont:btn.titleLabel.font];
+ btn.frame = CGRectMake(140.0,9.0,textSize.width+10,textSize.height+6);
+ [btn addTarget:self action:@selector(calibrate) forControlEvents:UIControlEventTouchUpInside];
+
+ [cell.contentView addSubview:btn];
}
+ } else {
+ static NSString *CellId = @"Cell";
+
+ cell = [tableView dequeueReusableCellWithIdentifier:CellId];
+ if (!cell)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellId] autorelease];
+ cell.detailTextLabel.text = filter->subTitle;
+ }
// Set up the cell...
- SFilterDesc *filter = &allMeths[ [indexPath section] ].filters[ [indexPath row] ];
- if (filter->deviceName == app.dasherInterface->GetStringParameter(SP_INPUT_DEVICE)
- && filter->filterName == app.dasherInterface->GetStringParameter(SP_INPUT_FILTER)
- && (!selectedPath || [indexPath compare:selectedPath])) {
- self.selectedPath = indexPath;
- [self performSelectorOnMainThread:@selector(doSelect) withObject:nil waitUntilDone:NO];
- }
+ cell.textLabel.text = filter->title;
+ CDasherInterfaceBase *intf = [DasherAppDelegate theApp].dasherInterface;
+ if (filter->deviceName == intf->GetStringParameter(SP_INPUT_DEVICE)
+ && filter->filterName == intf->GetStringParameter(SP_INPUT_FILTER)) {
+ //filter is currently selected...
+ DASHER_ASSERT(selectedPath==nil || [selectedPath isEqual:indexPath]);
+ selectedPath = indexPath;
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ } else {
+ cell.accessoryType = [self accessoryTypeForFilter:filter];
+ }
- UIButton *btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
- cell.accessoryView = btn;
- btn.tag = (int)filter;
- [btn addTarget:self action:@selector(settings:) forControlEvents:UIControlEventTouchUpInside];
-
- cell.text = filter->title;
- CGSize titleSize = [filter->title sizeWithFont:cell.font];
- subText.frame = CGRectMake(titleSize.width + 30.0, 5.0, 245.0 - titleSize.width, 34.0);
-
- subText.text = filter->subTitle;
+ return cell;
+}
- return cell;
+-(UITableViewCellAccessoryType)accessoryTypeForFilter:(SFilterDesc *)filter {
+ SModuleSettings *sets; int count;
+ CDasherInterfaceBase *intf = [DasherAppDelegate theApp].dasherInterface;
+ if (intf->GetModuleSettings(filter->filterName, &sets, &count))
+ if (count>0) return UITableViewCellAccessoryDisclosureIndicator;
+ if (intf->GetModuleSettings(filter->deviceName, &sets, &count))
+ if (count>0) return UITableViewCellAccessoryDisclosureIndicator;
+ if (filter->iPhoneOpts && *(filter->iPhoneOpts))
+ return UITableViewCellAccessoryDisclosureIndicator;
+ return UITableViewCellAccessoryNone;
}
- (void)moduleSettingsDone {
[self.navigationController popViewControllerAnimated:YES];
- [self doSelect];
-}
-
-- (void)doSelect {
- [self.tableView selectRowAtIndexPath:selectedPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
-}
-
-- (void)settings:(id)button {
- UIButton *btn = (UIButton *)button;
- SFilterDesc *desc = (SFilterDesc *)btn.tag;
- CDasherModule *mod = [DasherAppDelegate theApp].dasherInterface->GetModuleByName(desc->filterName);
- SModuleSettings *settings=NULL; int count=0;
- if (mod->GetSettings(&settings, &count)) {
- ParametersController *params = [[[ParametersController alloc] initWithTitle:NSStringFromStdString(desc->filterName) Settings:settings Count:count] autorelease];
- [params setTarget:self Selector:@selector(moduleSettingsDone)];
- [self.navigationController pushViewController:params animated:YES];
- }
-}
-
-- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
- if (section < numSections) return nil; //no special view => default, using title method (below)
- if (!calibButton) {
- calibButton = [[UIView alloc] initWithFrame:CGRectZero];
- calibButton.backgroundColor = [UIColor clearColor];
- calibButton.opaque = NO;
- UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- [btn setTitle:@"Calibrate Tilting..." forState:UIControlStateNormal];
- btn.font = [UIFont boldSystemFontOfSize:18.0];
- btn.frame = CGRectMake(9.0,2.0,302.0,[self tableView:tableView heightForHeaderInSection:section]-4.0);
- [btn addTarget:self action:@selector(calibrate) forControlEvents:UIControlEventTouchUpInside];
- [calibButton addSubview:btn];
- }
- return calibButton;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
@@ -223,12 +210,22 @@ int numSections = sizeof(allMeths) / sizeof(allMeths[0]);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- //[tableView deselectRowAtIndexPath:indexPath animated:NO];
- self.selectedPath = indexPath;
- DasherAppDelegate *app = [DasherAppDelegate theApp];
+ [tableView deselectRowAtIndexPath:indexPath animated:NO];
+ //self->selectedPath is the PREVIOUSLY-SELECTED filter. Take away the checkmark...
+ [tableView cellForRowAtIndexPath:selectedPath].accessoryType = [self accessoryTypeForFilter: &allMeths[[selectedPath section]].filters[[selectedPath row]]];
+ //now give the NEWLY-SELECTED filter a checkmark
+ [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
+
+ //and record it as selected...
+ self->selectedPath = indexPath;
+ CDasherInterfaceBase *intf = [DasherAppDelegate theApp].dasherInterface;
SFilterDesc *filter = &allMeths[ [indexPath section] ].filters[ [indexPath row] ];
- app.dasherInterface->SetStringParameter(SP_INPUT_DEVICE, filter->deviceName);
- app.dasherInterface->SetStringParameter(SP_INPUT_FILTER, filter->filterName);
+ intf->SetStringParameter(SP_INPUT_DEVICE, filter->deviceName);
+ intf->SetStringParameter(SP_INPUT_FILTER, filter->filterName);
+
+ ParametersController *params = [[[ExtraParametersController alloc] initForFilter:filter] autorelease];
+ [params setTarget:self Selector:@selector(moduleSettingsDone)];
+ [self.navigationController pushViewController:params animated:YES];
}
/*
@@ -275,6 +272,49 @@ int numSections = sizeof(allMeths) / sizeof(allMeths[0]);
[super dealloc];
}
+ end
+
+ implementation ExtraParametersController
+
+-(id)initForFilter:(SFilterDesc *)filter {
+ CDasherInterfaceBase *intf=[DasherAppDelegate theApp].dasherInterface;
+ SModuleSettings *settings; int count;
+ if (!intf->GetModuleSettings(filter->filterName, &settings, &count)) {
+ settings=NULL; count=0;
+ }
+ if (self = [super initWithTitle:NSStringFromStdString(filter->filterName) Settings:settings Count:count]) {
+ if (!intf->GetModuleSettings(filter->deviceName, &m_pSettings2, &m_iCount2)) {
+ m_pSettings2=NULL; m_iCount2=0;
+ }
+ iPhonePrefKeys = filter->iPhoneOpts;
+ }
+ return self;
+}
+
+-(int)layoutOptionsOn:(UIView *)view startingAtY:(int)y {
+ if (m_iCount)
+ y=[super layoutOptionsOn:view startingAtY:y];
+ else if (m_iCount2==0 && !iPhonePrefKeys)
+ return [self makeNoSettingsLabelOnView:view atY:y];
+ y=[self layoutModuleSettings:m_pSettings2 count:m_iCount2 onView:view startingAtY:y];
+ //finally, iPhone-specific keys...
+ NSUserDefaults *ud=[NSUserDefaults standardUserDefaults];
+ if (iPhonePrefKeys) {
+ for (NSString **key=iPhonePrefKeys; *key; key++) {
+ UISwitch *sw=[self makeSwitch:*key onView:view atY:&y];
+ sw.tag=(int)*key;
+ sw.on = [ud boolForKey:*key];
+ [sw addTarget:self action:@selector(boolUserDefChanged:) forControlEvents:UIControlEventValueChanged];
+ }
+ }
+ return y;
+}
+
+-(void)boolUserDefChanged:(id)uiswitch {
+ UISwitch *sw=(UISwitch *)uiswitch;
+ NSString *key = (NSString *)sw.tag;
+ [[NSUserDefaults standardUserDefaults] setBool:sw.on forKey:key];
+}
@end
diff --git a/Src/iPhone/Classes/ParametersController.h b/Src/iPhone/Classes/ParametersController.h
index 1fb7a18..b7b4790 100644
--- a/Src/iPhone/Classes/ParametersController.h
+++ b/Src/iPhone/Classes/ParametersController.h
@@ -10,11 +10,16 @@
#import "ModuleSettings.h"
@interface ParametersController : UIViewController {
- SModuleSettings *settings;
- int count;
+ SModuleSettings *m_pSettings;
+ int m_iCount;
}
-(id)initWithTitle:(NSString *)title Settings:(SModuleSettings *)settings Count:(int)count;
-(void)setTarget:(id)target Selector:(SEL)selector;
+///These are meant to be protected...
+-(int)layoutOptionsOn:(UIView *)view startingAtY:(int)y;
+-(int)layoutModuleSettings:(SModuleSettings *)settings count:(int)count onView:(UIView *)view startingAtY:(int)y;
+-(UISwitch *)makeSwitch:(NSString *)title onView:(UIView *)view atY:(int *)pY;
+-(int)makeNoSettingsLabelOnView:(UIView *)view atY:(int)y;
@end
diff --git a/Src/iPhone/Classes/ParametersController.mm b/Src/iPhone/Classes/ParametersController.mm
index fce10d9..8c4ba4c 100644
--- a/Src/iPhone/Classes/ParametersController.mm
+++ b/Src/iPhone/Classes/ParametersController.mm
@@ -20,12 +20,12 @@ using namespace Dasher;
@implementation ParametersController
--(id)initWithTitle:(NSString *)title Settings:(SModuleSettings *)_settings Count:(int)_count {
+-(id)initWithTitle:(NSString *)title Settings:(SModuleSettings *)settings Count:(int)count {
if (self = [super init]) {
self.title=title;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleDone target:nil action:nil];
- settings = _settings;
- count = _count;
+ m_pSettings = settings;
+ m_iCount = count;
}
return self;
}
@@ -37,27 +37,31 @@ using namespace Dasher;
}
- (void)loadView {
- CDasherInterfaceBridge *intf = [DasherAppDelegate theApp].dasherInterface;
-
UIScrollView *view = [[[UIScrollView alloc] init] autorelease];
self.view = view;
view.backgroundColor = [UIColor whiteColor];
-
- int y=15;
+
+ int y=[self layoutOptionsOn:view startingAtY:15];
+ [view setContentSize:CGSizeMake(320.0,y-15)];
+}
+
+-(int)layoutOptionsOn:(UIView *)view startingAtY:(int)y {
+ if (m_iCount==0) return [self makeNoSettingsLabelOnView:view atY:y];
+ return [self layoutModuleSettings:m_pSettings count:m_iCount onView:view startingAtY:y];
+}
+
+-(int)layoutModuleSettings:(SModuleSettings *)settings count:(int)count onView:(UIView *)view startingAtY:(int)y {
+ CDasherInterfaceBridge *intf = [DasherAppDelegate theApp].dasherInterface;
for (int i=0; i<count; i++) {
if (settings[i].iType == T_BOOL) {
- UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, y, 190.0, 20.0)] autorelease];
- label.text = NSStringFromStdString(intf->GetSettingsStore()->GetParameterName(settings[i].iParameter));
- UISwitch *sw = [[[UISwitch alloc] initWithFrame:CGRectMake(210.0, y, 100.0, 20.0)] autorelease];
- [view addSubview:label];
- [view addSubview:sw];
- sw.on = intf->GetBoolParameter(sw.tag = settings[i].iParameter);
+ UISwitch *sw=[self makeSwitch:NSStringFromStdString(intf->GetSettingsStore()->GetParameterName(settings[i].iParameter)) onView:view atY:&y];
+ sw.tag = settings[i].iParameter;
+ sw.on = intf->GetBoolParameter(settings[i].iParameter);
[sw addTarget:self action:@selector(boolParamChanged:) forControlEvents:UIControlEventValueChanged];
- y += 50;
} else if (settings[i].iType == T_LONG) {
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, y, 300.0, 20.0)] autorelease];
UISlider *slider = [[[UISlider alloc] initWithFrame:CGRectMake(10.0, y+20, 300.0, 20.0)] autorelease];
- slider.tag = (int)label; label.tag=i;
+ slider.tag = (int)label; label.tag=(int)&settings[i];
slider.minimumValue = settings[i].iMin; slider.maximumValue = settings[i].iMax;
slider.value = intf->GetLongParameter(settings[i].iParameter);
[slider addTarget:self action:@selector(longParamChanged:) forControlEvents:UIControlEventValueChanged];
@@ -66,7 +70,24 @@ using namespace Dasher;
y += 70;
}
}
- [view setContentSize:CGSizeMake(320.0,y-15)];
+ return y;
+}
+
+-(UISwitch *)makeSwitch:(NSString *)title onView:(UIView *)view atY:(int *)pY {
+ UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, *pY, 190.0, 20.0)] autorelease];
+ label.text = title;
+ UISwitch *sw = [[[UISwitch alloc] initWithFrame:CGRectMake(210.0, *pY, 100.0, 20.0)] autorelease];
+ [view addSubview:label];
+ [view addSubview:sw];
+ *pY += 50;
+ return sw;
+}
+
+-(int)makeNoSettingsLabelOnView:(UIView *)view atY:(int)y {
+ UILabel *label=[[[UILabel alloc] initWithFrame:CGRectMake(10.0, y, 300.0, 20.0)] autorelease];
+ label.text=@"No Settings";
+ [view addSubview:label];
+ return y+50;
}
-(void)boolParamChanged:(id)uiswitch {
@@ -78,7 +99,7 @@ using namespace Dasher;
CDasherInterfaceBridge *intf = [DasherAppDelegate theApp].dasherInterface;
UISlider *slider = (UISlider *)uislider;
UILabel *label = (UILabel *)slider.tag;
- SModuleSettings *setting = &settings[label.tag];
+ SModuleSettings *setting = (SModuleSettings *)label.tag;
long val = slider.value;
if (!label.text || val != intf->GetLongParameter(setting->iParameter)) {
intf->SetLongParameter(setting->iParameter, val);
diff --git a/Src/iPhone/Dasher.xcodeproj/project.pbxproj b/Src/iPhone/Dasher.xcodeproj/project.pbxproj
index c3b107e..fca3b5c 100755
--- a/Src/iPhone/Dasher.xcodeproj/project.pbxproj
+++ b/Src/iPhone/Dasher.xcodeproj/project.pbxproj
@@ -43,6 +43,7 @@
331F29C80F7A9C270044EB9C /* alphabet.welsh.xml in Resources */ = {isa = PBXBuildFile; fileRef = 331F293C0F7A9C270044EB9C /* alphabet.welsh.xml */; };
331F29CA0F7A9C270044EB9C /* alphabet.xsl in Resources */ = {isa = PBXBuildFile; fileRef = 331F293E0F7A9C270044EB9C /* alphabet.xsl */; };
331F29CB0F7A9C270044EB9C /* alphabet.xsl.good in Resources */ = {isa = PBXBuildFile; fileRef = 331F293F0F7A9C270044EB9C /* alphabet.xsl.good */; };
+ 3324F491129C119C00EE6A22 /* IPhoneFilters.mm in Sources */ = {isa = PBXBuildFile; fileRef = 332F32CC103C8D6E008448D7 /* IPhoneFilters.mm */; };
332BCAB40F71621400585DBD /* expat.dsp in Resources */ = {isa = PBXBuildFile; fileRef = 332BCA9A0F71621400585DBD /* expat.dsp */; };
332BCAB50F71621400585DBD /* expat_static.dsp in Resources */ = {isa = PBXBuildFile; fileRef = 332BCA9D0F71621400585DBD /* expat_static.dsp */; };
332BCAB60F71621400585DBD /* expatw.dsp in Resources */ = {isa = PBXBuildFile; fileRef = 332BCA9E0F71621400585DBD /* expatw.dsp */; };
@@ -60,8 +61,6 @@
332F32B4103C8A1E008448D7 /* ConversionHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 332F32AC103C8A1E008448D7 /* ConversionHelper.cpp */; };
332F32B5103C8A1E008448D7 /* MandarinAlphMgr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 332F32AD103C8A1E008448D7 /* MandarinAlphMgr.cpp */; };
332F32B6103C8A1E008448D7 /* Trainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 332F32AF103C8A1E008448D7 /* Trainer.cpp */; };
- 332F32CE103C8D6E008448D7 /* IPhoneFilters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 332F32CC103C8D6E008448D7 /* IPhoneFilters.cpp */; };
- 332F331E103C8EFD008448D7 /* PlainDragFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3376EBFD0FC15A7300C4DC9F /* PlainDragFilter.cpp */; };
332F34A3103D8F54008448D7 /* colour.blue.xml in Resources */ = {isa = PBXBuildFile; fileRef = 332F3496103D8F54008448D7 /* colour.blue.xml */; };
332F34A4103D8F54008448D7 /* colour.dtd in Resources */ = {isa = PBXBuildFile; fileRef = 332F3497103D8F54008448D7 /* colour.dtd */; };
332F34A5103D8F54008448D7 /* colour.euroasian.xml in Resources */ = {isa = PBXBuildFile; fileRef = 332F3498103D8F54008448D7 /* colour.euroasian.xml */; };
@@ -368,7 +367,7 @@
332F32AE103C8A1E008448D7 /* MandarinAlphMgr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MandarinAlphMgr.h; sourceTree = "<group>"; };
332F32AF103C8A1E008448D7 /* Trainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Trainer.cpp; sourceTree = "<group>"; };
332F32B0103C8A1E008448D7 /* Trainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Trainer.h; sourceTree = "<group>"; };
- 332F32CC103C8D6E008448D7 /* IPhoneFilters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IPhoneFilters.cpp; sourceTree = "<group>"; };
+ 332F32CC103C8D6E008448D7 /* IPhoneFilters.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = IPhoneFilters.mm; sourceTree = "<group>"; };
332F32CD103C8D6E008448D7 /* IPhoneFilters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPhoneFilters.h; sourceTree = "<group>"; };
332F3496103D8F54008448D7 /* colour.blue.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = colour.blue.xml; sourceTree = "<group>"; };
332F3497103D8F54008448D7 /* colour.dtd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = colour.dtd; sourceTree = "<group>"; };
@@ -704,8 +703,6 @@
337691700F9CE8630083FEB2 /* StringParamController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringParamController.mm; sourceTree = "<group>"; };
337691840F9CEFC70083FEB2 /* InputMethodSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputMethodSelector.h; sourceTree = "<group>"; };
337691850F9CEFC70083FEB2 /* InputMethodSelector.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InputMethodSelector.mm; sourceTree = "<group>"; };
- 3376EBFC0FC15A7300C4DC9F /* PlainDragFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlainDragFilter.h; sourceTree = "<group>"; };
- 3376EBFD0FC15A7300C4DC9F /* PlainDragFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlainDragFilter.cpp; sourceTree = "<group>"; };
337ECC1910DD5E0700D0C6A5 /* ExpansionPolicy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExpansionPolicy.cpp; sourceTree = "<group>"; };
337ECC1A10DD5E0700D0C6A5 /* ExpansionPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpansionPolicy.h; sourceTree = "<group>"; };
339F8A310FF5088000282847 /* CalibrationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CalibrationController.h; sourceTree = "<group>"; };
@@ -780,7 +777,7 @@
333B5D4E100F5A93002041C8 /* TextView.mm */,
3330BD420FA885FD0035E952 /* IPhoneInputs.h */,
3330BDC50FA8BE360035E952 /* IPhoneInputs.mm */,
- 332F32CC103C8D6E008448D7 /* IPhoneFilters.cpp */,
+ 332F32CC103C8D6E008448D7 /* IPhoneFilters.mm */,
332F32CD103C8D6E008448D7 /* IPhoneFilters.h */,
3330B80B0FA1FABB0035E952 /* Vec3.cpp */,
3330B7D00FA1198E0035E952 /* Vec3.h */,
@@ -805,8 +802,6 @@
3354AF4611ADBAFD006CF570 /* Actions.h */,
3354AF4711ADBAFD006CF570 /* Actions.mm */,
33EB48400F72A5680048E7C2 /* DasherScreenCallbacks.h */,
- 3376EBFC0FC15A7300C4DC9F /* PlainDragFilter.h */,
- 3376EBFD0FC15A7300C4DC9F /* PlainDragFilter.cpp */,
339F8A310FF5088000282847 /* CalibrationController.h */,
339F8A320FF5088000282847 /* CalibrationController.mm */,
);
@@ -1646,8 +1641,6 @@
332F32B4103C8A1E008448D7 /* ConversionHelper.cpp in Sources */,
332F32B5103C8A1E008448D7 /* MandarinAlphMgr.cpp in Sources */,
332F32B6103C8A1E008448D7 /* Trainer.cpp in Sources */,
- 332F32CE103C8D6E008448D7 /* IPhoneFilters.cpp in Sources */,
- 332F331E103C8EFD008448D7 /* PlainDragFilter.cpp in Sources */,
339F8A330FF5088000282847 /* CalibrationController.mm in Sources */,
333B5D4F100F5A93002041C8 /* TextView.mm in Sources */,
3334D4DF1014745F0077948A /* MiscSettings.mm in Sources */,
@@ -1728,6 +1721,7 @@
333F707A11A8AA66002E2BDF /* usenglish.c in Sources */,
3354AF4811ADBAFD006CF570 /* Actions.mm in Sources */,
337472D3121A976B001A858C /* AlphInfo.cpp in Sources */,
+ 3324F491129C119C00EE6A22 /* IPhoneFilters.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]