diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/org/connectbot/ColorsActivity.java | 87 | ||||
| -rw-r--r-- | src/org/connectbot/ConsoleActivity.java | 2 | ||||
| -rw-r--r-- | src/org/connectbot/HostListActivity.java | 14 | ||||
| -rw-r--r-- | src/org/connectbot/PubkeyListActivity.java | 4 | ||||
| -rw-r--r-- | src/org/connectbot/bean/HostBean.java | 10 | ||||
| -rw-r--r-- | src/org/connectbot/service/FontSizeChangedListener.java | 6 | ||||
| -rw-r--r-- | src/org/connectbot/service/TerminalBridge.java | 88 | ||||
| -rw-r--r-- | src/org/connectbot/service/TerminalKeyListener.java | 72 | ||||
| -rw-r--r-- | src/org/connectbot/transport/Local.java | 5 | ||||
| -rw-r--r-- | src/org/connectbot/util/HostDatabase.java | 52 | ||||
| -rw-r--r-- | src/org/connectbot/util/PreferenceConstants.java | 10 | ||||
| -rw-r--r-- | src/org/connectbot/util/UberColorPickerDialog.java | 231 | 
12 files changed, 372 insertions, 209 deletions
| diff --git a/src/org/connectbot/ColorsActivity.java b/src/org/connectbot/ColorsActivity.java index 38336f7..be5dfb1 100644 --- a/src/org/connectbot/ColorsActivity.java +++ b/src/org/connectbot/ColorsActivity.java @@ -17,6 +17,7 @@  package org.connectbot; +import java.text.NumberFormat;  import java.util.Arrays;  import java.util.List; @@ -30,6 +31,7 @@ import android.content.Context;  import android.graphics.Canvas;  import android.graphics.Paint;  import android.os.Bundle; +import android.util.DisplayMetrics;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View; @@ -54,11 +56,12 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  	private int mColorScheme;  	private List<Integer> mColorList; -	private HostDatabase hostdb; +	private HostDatabase mHostDb;  	private int mCurrentColor = 0;  	private int[] mDefaultColors; +  	@Override  	protected void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState); @@ -71,10 +74,10 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		mColorScheme = HostDatabase.DEFAULT_COLOR_SCHEME; -		hostdb = new HostDatabase(this); +		mHostDb = new HostDatabase(this); -		mColorList = Arrays.asList(hostdb.getColorsForScheme(mColorScheme)); -		mDefaultColors = hostdb.getDefaultColorsForScheme(mColorScheme); +		mColorList = Arrays.asList(mHostDb.getColorsForScheme(mColorScheme)); +		mDefaultColors = mHostDb.getDefaultColorsForScheme(mColorScheme);  		mColorGrid = (GridView) findViewById(R.id.color_grid);  		mColorGrid.setAdapter(new ColorsAdapter(true)); @@ -82,12 +85,12 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		mColorGrid.setSelection(0);  		mFgSpinner = (Spinner) findViewById(R.id.fg); -		mFgSpinner.setAdapter(new ColorsAdapter(false)); +		mFgSpinner.setAdapter(new ColorsAdapter(false, R.string.colors_fg_label));  		mFgSpinner.setSelection(mDefaultColors[0]);  		mFgSpinner.setOnItemSelectedListener(this);  		mBgSpinner = (Spinner) findViewById(R.id.bg); -		mBgSpinner.setAdapter(new ColorsAdapter(false)); +		mBgSpinner.setAdapter(new ColorsAdapter(false, R.string.color_bg_label));  		mBgSpinner.setSelection(mDefaultColors[1]);  		mBgSpinner.setOnItemSelectedListener(this);  	} @@ -96,9 +99,9 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  	protected void onDestroy() {  		super.onDestroy(); -		if (hostdb != null) { -			hostdb.close(); -			hostdb = null; +		if (mHostDb != null) { +			mHostDb.close(); +			mHostDb = null;  		}  	} @@ -106,22 +109,28 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  	protected void onResume() {  		super.onResume(); -		if (hostdb == null) -			hostdb = new HostDatabase(this); +		if (mHostDb == null) +			mHostDb = new HostDatabase(this);  	}  	private class ColorsAdapter extends BaseAdapter { -		private boolean mSquareViews; +		private final boolean mSquareViews; +		private final int mResourceLabel;  		public ColorsAdapter(boolean squareViews) { +			this(squareViews, -1); +		} + +		public ColorsAdapter(boolean squareViews, int resourceLabel) {  			mSquareViews = squareViews; +			mResourceLabel = resourceLabel;  		}  		public View getView(int position, View convertView, ViewGroup parent) {  			ColorView c;  			if (convertView == null) { -				c = new ColorView(ColorsActivity.this, mSquareViews); +				c = new ColorView(ColorsActivity.this, mResourceLabel, mSquareViews);  			} else {  				c = (ColorView) convertView;  			} @@ -146,7 +155,16 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  	}  	private class ColorView extends View { -		private boolean mSquare; +		/** The font size displayed in the GridView entries. */ +		private static final float FONT_SIZE_DP = 20f; + +		/** Margin around the GridView entries. */ +		private static final float MARGIN_DP = 10f; + +		private final boolean mSquare; + +		private final int mResourceLabel; +		private final NumberFormat mNumberFormatter;  		private Paint mTextPaint;  		private Paint mShadowPaint; @@ -159,14 +177,19 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		private int mWidthCenter;  		private int mHeightCenter; -		public ColorView(Context context, boolean square) { +		public ColorView(Context context, int resourceLabel, boolean square) {  			super(context);  			mSquare = square; +			mResourceLabel = resourceLabel; + +			mNumberFormatter = NumberFormat.getIntegerInstance(getContext().getResources().getConfiguration().locale); + +			DisplayMetrics metrics = context.getResources().getDisplayMetrics();  			mTextPaint = new Paint();  			mTextPaint.setAntiAlias(true); -			mTextPaint.setTextSize(16); +			mTextPaint.setTextSize((int) (metrics.density * FONT_SIZE_DP + 0.5f));  			mTextPaint.setColor(0xFFFFFFFF);  			mTextPaint.setTextAlign(Paint.Align.CENTER); @@ -177,7 +200,8 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  			mShadowPaint.setStrokeWidth(4f);  			mShadowPaint.setColor(0xFF000000); -			setPadding(10, 10, 10, 10); +			int marginPx = (int) (MARGIN_DP * metrics.density + 0.5f); +			setPadding(marginPx, marginPx, marginPx, marginPx);  		}  		public void setColor(int color) { @@ -185,7 +209,11 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		}  		public void setNumber(int number) { -			mText = Integer.toString(number); +			if (mResourceLabel != -1) { +				mText = getContext().getResources().getString(mResourceLabel, number); +			} else { +				mText = mNumberFormatter.format(number); +			}  		}  		@Override @@ -193,10 +221,12 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  			int width = measureWidth(widthMeasureSpec);  			int height; -			if (mSquare) +			if (mSquare) { +				//noinspection SuspiciousNameCombination  				height = width; -			else +			} else {  				height = measureHeight(heightMeasureSpec); +			}  			mAscent = (int) mTextPaint.ascent();  			mWidthCenter = width / 2; @@ -206,7 +236,8 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		}  		private int measureWidth(int measureSpec) { -			int result = 0; +			int result; +  			int specMode = MeasureSpec.getMode(measureSpec);  			int specSize = MeasureSpec.getSize(measureSpec); @@ -228,7 +259,8 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		}  		private int measureHeight(int measureSpec) { -			int result = 0; +			int result; +  			int specMode = MeasureSpec.getMode(measureSpec);  			int specSize = MeasureSpec.getSize(measureSpec); @@ -249,7 +281,6 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  			return result;  		} -  		@Override  		protected void onDraw(Canvas canvas) {  			super.onDraw(canvas); @@ -273,7 +304,7 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  	public void onNothingSelected(AdapterView<?> arg0) { }  	public void colorChanged(int value) { -		hostdb.setGlobalColor(mCurrentColor, value); +		mHostDb.setGlobalColor(mCurrentColor, value);  		mColorList.set(mCurrentColor, value);  		mColorGrid.invalidateViews();  	} @@ -294,7 +325,7 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  		}  		if (needUpdate) -			hostdb.setDefaultColorsForScheme(mColorScheme, mDefaultColors[0], mDefaultColors[1]); +			mHostDb.setDefaultColorsForScheme(mColorScheme, mDefaultColors[0], mDefaultColors[1]);  	}  	@Override @@ -309,8 +340,8 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  			public boolean onMenuItemClick(MenuItem arg0) {  				// Reset each individual color to defaults.  				for (int i = 0; i < Colors.defaults.length; i++) { -					if (mColorList.get(i) != Colors.defaults[i]) { -						hostdb.setGlobalColor(i, Colors.defaults[i]); +					if (!mColorList.get(i).equals(Colors.defaults[i])) { +						mHostDb.setGlobalColor(i, Colors.defaults[i]);  						mColorList.set(i, Colors.defaults[i]);  					}  				} @@ -319,7 +350,7 @@ public class ColorsActivity extends Activity implements OnItemClickListener, OnC  				// Reset the default FG/BG colors as well.  				mFgSpinner.setSelection(HostDatabase.DEFAULT_FG_COLOR);  				mBgSpinner.setSelection(HostDatabase.DEFAULT_BG_COLOR); -				hostdb.setDefaultColorsForScheme(HostDatabase.DEFAULT_COLOR_SCHEME, +				mHostDb.setDefaultColorsForScheme(HostDatabase.DEFAULT_COLOR_SCHEME,  						HostDatabase.DEFAULT_FG_COLOR, HostDatabase.DEFAULT_BG_COLOR);  				return true; diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java index 7aca08c..aeb0e67 100644 --- a/src/org/connectbot/ConsoleActivity.java +++ b/src/org/connectbot/ConsoleActivity.java @@ -422,7 +422,7 @@ public class ConsoleActivity extends Activity {  				TerminalView terminal = (TerminalView)flip;  				TerminalKeyListener handler = terminal.bridge.getKeyHandler(); -				handler.metaPress(TerminalKeyListener.OUR_CTRL_ON); +				handler.metaPress(TerminalKeyListener.OUR_CTRL_ON, true);  				hideEmulatedKeys();  			}  		}); diff --git a/src/org/connectbot/HostListActivity.java b/src/org/connectbot/HostListActivity.java index dc39d49..7dce760 100644 --- a/src/org/connectbot/HostListActivity.java +++ b/src/org/connectbot/HostListActivity.java @@ -165,11 +165,23 @@ public class HostListActivity extends ListActivity {  		// detect HTC Dream and apply special preferences  		if (Build.MANUFACTURER.equals("HTC") && Build.DEVICE.equals("dream")) { +			SharedPreferences.Editor editor = prefs.edit(); +			boolean doCommit = false;  			if (!prefs.contains(PreferenceConstants.SHIFT_FKEYS) &&  			    !prefs.contains(PreferenceConstants.CTRL_FKEYS)) { -				SharedPreferences.Editor editor = prefs.edit();  				editor.putBoolean(PreferenceConstants.SHIFT_FKEYS, true);  				editor.putBoolean(PreferenceConstants.CTRL_FKEYS, true); +				doCommit = true; +			} +			if (!prefs.contains(PreferenceConstants.STICKY_MODIFIERS)) { +				editor.putString(PreferenceConstants.STICKY_MODIFIERS, PreferenceConstants.YES); +				doCommit = true; +			} +			if (!prefs.contains(PreferenceConstants.KEYMODE)) { +				editor.putString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); +				doCommit = true; +			} +			if (doCommit) {  				editor.commit();  			}  		} diff --git a/src/org/connectbot/PubkeyListActivity.java b/src/org/connectbot/PubkeyListActivity.java index be7a46f..b9654a4 100644 --- a/src/org/connectbot/PubkeyListActivity.java +++ b/src/org/connectbot/PubkeyListActivity.java @@ -155,7 +155,7 @@ public class PubkeyListActivity extends ListActivity implements EventListener {  		getListView().setOnItemClickListener(new OnItemClickListener() {  			public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {  				PubkeyBean pubkey = (PubkeyBean) getListView().getItemAtPosition(position); -				boolean loaded = bound.isKeyLoaded(pubkey.getNickname()); +				boolean loaded = bound != null && bound.isKeyLoaded(pubkey.getNickname());  				// handle toggling key in-memory on/off  				if(loaded) { @@ -307,7 +307,7 @@ public class PubkeyListActivity extends ListActivity implements EventListener {  		// cant change password or clipboard imported keys  		final boolean imported = PubkeyDatabase.KEY_TYPE_IMPORTED.equals(pubkey.getType()); -		final boolean loaded = bound.isKeyLoaded(pubkey.getNickname()); +		final boolean loaded = bound != null && bound.isKeyLoaded(pubkey.getNickname());  		MenuItem load = menu.add(loaded ? R.string.pubkey_memory_unload : R.string.pubkey_memory_load);  		load.setOnMenuItemClickListener(new OnMenuItemClickListener() { diff --git a/src/org/connectbot/bean/HostBean.java b/src/org/connectbot/bean/HostBean.java index 2fd7bfb..183d047 100644 --- a/src/org/connectbot/bean/HostBean.java +++ b/src/org/connectbot/bean/HostBean.java @@ -50,6 +50,7 @@ public class HostBean extends AbstractBean {  	private boolean compression = false;  	private String encoding = HostDatabase.ENCODING_DEFAULT;  	private boolean stayConnected = false; +	private boolean quickDisconnect = false;  	public HostBean() { @@ -202,6 +203,14 @@ public class HostBean extends AbstractBean {  		return stayConnected;  	} +	public void setQuickDisconnect(boolean quickDisconnect) { +		this.quickDisconnect = quickDisconnect; +	} + +	public boolean getQuickDisconnect() { +		return quickDisconnect; +	} +  	public String getDescription() {  		String description = String.format("%s@%s", username, hostname); @@ -234,6 +243,7 @@ public class HostBean extends AbstractBean {  		values.put(HostDatabase.FIELD_HOST_COMPRESSION, Boolean.toString(compression));  		values.put(HostDatabase.FIELD_HOST_ENCODING, encoding);  		values.put(HostDatabase.FIELD_HOST_STAYCONNECTED, stayConnected); +		values.put(HostDatabase.FIELD_HOST_QUICKDISCONNECT, quickDisconnect);  		return values;  	} diff --git a/src/org/connectbot/service/FontSizeChangedListener.java b/src/org/connectbot/service/FontSizeChangedListener.java index eb1c33d..56b9971 100644 --- a/src/org/connectbot/service/FontSizeChangedListener.java +++ b/src/org/connectbot/service/FontSizeChangedListener.java @@ -24,8 +24,8 @@ package org.connectbot.service;  public interface FontSizeChangedListener {  	/** -	 * @param size -	 *            new font size +	 * @param sizeDp +	 *            new font size in dp  	 */ -	void onFontSizeChanged(float size); +	void onFontSizeChanged(float sizeDp);  } diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index 6b87b74..2065a97 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -61,8 +61,9 @@ import de.mud.terminal.vt320;  public class TerminalBridge implements VDUDisplay {  	public final static String TAG = "ConnectBot.TerminalBridge"; -	public final static int DEFAULT_FONT_SIZE = 10; +	public final static int DEFAULT_FONT_SIZE_DP = 10;  	private final static int FONT_SIZE_STEP = 2; +	private final float displayDensity;  	public Integer[] color; @@ -107,7 +108,7 @@ public class TerminalBridge implements VDUDisplay {  	public int charHeight = -1;  	private int charTop = -1; -	private float fontSize = -1; +	private float fontSizeDp = -1;  	private final List<FontSizeChangedListener> fontSizeChangedListeners; @@ -143,6 +144,8 @@ public class TerminalBridge implements VDUDisplay {  		emulation = null;  		manager = null; +		displayDensity = 1f; +  		defaultPaint = new Paint();  		selectionArea = new SelectionArea(); @@ -169,6 +172,8 @@ public class TerminalBridge implements VDUDisplay {  		emulation = manager.getEmulation();  		scrollback = manager.getScrollback(); +		this.displayDensity = manager.getResources().getDisplayMetrics().density; +  		// create prompt helper to relay password and hostkey requests up to gui  		promptHelper = new PromptHelper(this); @@ -182,10 +187,11 @@ public class TerminalBridge implements VDUDisplay {  		fontSizeChangedListeners = new LinkedList<FontSizeChangedListener>(); -		int hostFontSize = host.getFontSize(); -		if (hostFontSize <= 0) -			hostFontSize = DEFAULT_FONT_SIZE; -		setFontSize(hostFontSize); +		int hostFontSizeDp = host.getFontSize(); +		if (hostFontSizeDp <= 0) { +			hostFontSizeDp = DEFAULT_FONT_SIZE_DP; +		} +		setFontSize(hostFontSizeDp);  		// create terminal buffer and handle outgoing data  		// this is probably status reply information @@ -384,7 +390,7 @@ public class TerminalBridge implements VDUDisplay {  		relayThread.start();  		// force font-size to make sure we resizePTY as needed -		setFontSize(fontSize); +		setFontSize(fontSizeDp);  		// finally send any post-login string, if requested  		injectString(host.getPostLogin()); @@ -429,7 +435,7 @@ public class TerminalBridge implements VDUDisplay {  		disconnectThread.setName("Disconnect");  		disconnectThread.start(); -		if (immediate) { +		if (immediate || (host.getQuickDisconnect() && !host.getStayConnected())) {  			awaitingClose = true;  			if (disconnectListener != null)  				disconnectListener.onDisconnected(TerminalBridge.this); @@ -480,13 +486,18 @@ public class TerminalBridge implements VDUDisplay {  	/**  	 * Request a different font size. Will make call to parentChanged() to make  	 * sure we resize PTY if needed. +	 * +	 * @param sizeDp Size of font in dp  	 */ -	/* package */ final void setFontSize(float size) { -		if (size <= 0.0) +	/* package */ final void setFontSize(float sizeDp) { +		if (sizeDp <= 0.0) {  			return; +		} + +		final int fontSizePx = (int) (sizeDp * this.displayDensity + 0.5f); -		defaultPaint.setTextSize(size); -		fontSize = size; +		defaultPaint.setTextSize(fontSizePx); +		fontSizeDp = sizeDp;  		// read new metrics to get exact pixel dimensions  		FontMetrics fm = defaultPaint.getFontMetrics(); @@ -498,13 +509,15 @@ public class TerminalBridge implements VDUDisplay {  		charHeight = (int)Math.ceil(fm.descent - fm.top);  		// refresh any bitmap with new font size -		if(parent != null) +		if (parent != null) {  			parentChanged(parent); +		} -		for (FontSizeChangedListener ofscl : fontSizeChangedListeners) -			ofscl.onFontSizeChanged(size); +		for (FontSizeChangedListener ofscl : fontSizeChangedListeners) { +			ofscl.onFontSizeChanged(sizeDp); +		} -		host.setFontSize((int) fontSize); +		host.setFontSize((int) sizeDp);  		manager.hostdb.updateFontSize(host);  		forcedSize = false; @@ -771,51 +784,52 @@ public class TerminalBridge implements VDUDisplay {  	/**  	 * Resize terminal to fit [rows]x[cols] in screen of size [width]x[height] -	 * @param rows -	 * @param cols -	 * @param width -	 * @param height +	 * +	 * @param rows desired number of text rows +	 * @param cols desired numbor of text colums +	 * @param width width of screen in pixels +	 * @param height height of screen in pixels  	 */  	public synchronized void resizeComputed(int cols, int rows, int width, int height) { -		float size = 8.0f; +		float sizeDp = 8.0f;  		float step = 8.0f;  		float limit = 0.125f;  		int direction; -		while ((direction = fontSizeCompare(size, cols, rows, width, height)) < 0) -			size += step; +		while ((direction = fontSizeCompare(sizeDp, cols, rows, width, height)) < 0) +			sizeDp += step;  		if (direction == 0) { -			Log.d("fontsize", String.format("Found match at %f", size)); +			Log.d("fontsize", String.format("Found match at %f", sizeDp));  			return;  		}  		step /= 2.0f; -		size -= step; +		sizeDp -= step; -		while ((direction = fontSizeCompare(size, cols, rows, width, height)) != 0 +		while ((direction = fontSizeCompare(sizeDp, cols, rows, width, height)) != 0  				&& step >= limit) {  			step /= 2.0f;  			if (direction > 0) { -				size -= step; +				sizeDp -= step;  			} else { -				size += step; +				sizeDp += step;  			}  		}  		if (direction > 0) -			size -= step; +			sizeDp -= step;  		this.columns = cols;  		this.rows = rows; -		setFontSize(size); +		setFontSize(sizeDp);  		forcedSize = true;  	} -	private int fontSizeCompare(float size, int cols, int rows, int width, int height) { +	private int fontSizeCompare(float sizeDp, int cols, int rows, int width, int height) {  		// read new metrics to get exact pixel dimensions -		defaultPaint.setTextSize(size); +		defaultPaint.setTextSize((int) (sizeDp * this.displayDensity + 0.5f));  		FontMetrics fm = defaultPaint.getFontMetrics();  		float[] widths = new float[1]; @@ -823,7 +837,7 @@ public class TerminalBridge implements VDUDisplay {  		int termWidth = (int)widths[0] * cols;  		int termHeight = (int)Math.ceil(fm.descent - fm.top) * rows; -		Log.d("fontsize", String.format("font size %f resulted in %d x %d", size, termWidth, termHeight)); +		Log.d("fontsize", String.format("font size %fdp resulted in %d x %d", sizeDp, termWidth, termHeight));  		// Check to see if it fits in resolution specified.  		if (termWidth > width || termHeight > height) @@ -1003,16 +1017,16 @@ public class TerminalBridge implements VDUDisplay {  	}  	/** -	 * +	 * Convenience function to increase the font size by a given step.  	 */  	public void increaseFontSize() { -		setFontSize(fontSize + FONT_SIZE_STEP); +		setFontSize(fontSizeDp + FONT_SIZE_STEP);  	}  	/** -	 * +	 * Convenience function to decrease the font size by a given step.  	 */  	public void decreaseFontSize() { -		setFontSize(fontSize - FONT_SIZE_STEP); +		setFontSize(fontSizeDp - FONT_SIZE_STEP);  	}  } diff --git a/src/org/connectbot/service/TerminalKeyListener.java b/src/org/connectbot/service/TerminalKeyListener.java index 7ff21df..13e8dd1 100644 --- a/src/org/connectbot/service/TerminalKeyListener.java +++ b/src/org/connectbot/service/TerminalKeyListener.java @@ -64,6 +64,14 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  	// backport constants from api level 11  	private final static int KEYCODE_ESCAPE = 111; +	private final static int KEYCODE_CTRL_LEFT = 113; +	private final static int KEYCODE_CTRL_RIGHT = 114; +	private final static int KEYCODE_INSERT = 124; +	private final static int KEYCODE_FORWARD_DEL = 112; +	private final static int KEYCODE_MOVE_HOME = 122; +	private final static int KEYCODE_MOVE_END = 123; +	private final static int KEYCODE_PAGE_DOWN = 93; +	private final static int KEYCODE_PAGE_UP = 92;  	private final static int HC_META_CTRL_ON = 0x1000;  	private final static int HC_META_CTRL_LEFT_ON = 0x2000;  	private final static int HC_META_CTRL_RIGHT_ON = 0x4000; @@ -81,6 +89,7 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  	private boolean shiftedNumbersAreFKeysOnHardKeyboard;  	private boolean controlNumbersAreFKeysOnSoftKeyboard;  	private boolean volumeKeysChangeFontSize; +	private int stickyMetas;  	private int ourMetaState = 0; @@ -234,6 +243,10 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  						return true;  					}  				} +				if (keyCode == KEYCODE_CTRL_LEFT || keyCode == KEYCODE_CTRL_RIGHT) { +					metaPress(OUR_CTRL_ON); +					return true; +				}  			}  			if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { @@ -258,7 +271,7 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  						sendEscape();  						ourMetaState &= ~OUR_CTRL_ON;  					} else -						metaPress(OUR_CTRL_ON); +						metaPress(OUR_CTRL_ON, true);  				}  				bridge.redraw();  				return true; @@ -292,7 +305,11 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  			int uchar = event.getUnicodeChar(derivedMetaState & ~HC_META_CTRL_MASK);  			int ucharWithoutAlt = event.getUnicodeChar(  			        derivedMetaState & ~(HC_META_ALT_MASK | HC_META_CTRL_MASK)); -			if (uchar != ucharWithoutAlt) { +			if (uchar == 0) { +				// Keymap doesn't know the key with alt on it, so just go with the unmodified version +				uchar = ucharWithoutAlt; +			} +			else if (uchar != ucharWithoutAlt) {  				// The alt key was used to modify the character returned; therefore, drop the alt  				// modifier from the state so we don't end up sending alt+key.  				derivedMetaState &= ~HC_META_ALT_MASK; @@ -405,6 +422,31 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  					bridge.tryKeyVibrate();  				}  				return true; + +			case KEYCODE_INSERT: +				((vt320) buffer).keyPressed(vt320.KEY_INSERT, ' ', +						getStateForBuffer()); +				return true; +			case KEYCODE_FORWARD_DEL: +				((vt320) buffer).keyPressed(vt320.KEY_DELETE, ' ', +						getStateForBuffer()); +				return true; +			case KEYCODE_MOVE_HOME: +				((vt320) buffer).keyPressed(vt320.KEY_HOME, ' ', +						getStateForBuffer()); +				return true; +			case KEYCODE_MOVE_END: +				((vt320) buffer).keyPressed(vt320.KEY_END, ' ', +						getStateForBuffer()); +				return true; +			case KEYCODE_PAGE_UP: +				((vt320) buffer).keyPressed(vt320.KEY_PAGE_UP, ' ', +						getStateForBuffer()); +				return true; +			case KEYCODE_PAGE_DOWN: +				((vt320) buffer).keyPressed(vt320.KEY_PAGE_DOWN, ' ', +						getStateForBuffer()); +				return true;  			}  		} catch (IOException e) { @@ -493,17 +535,25 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  	 *  	 * @param code  	 */ -	public void metaPress(int code) { +	public void metaPress(int code, boolean forceSticky) {  		if ((ourMetaState & (code << 1)) != 0) {  			ourMetaState &= ~(code << 1);  		} else if ((ourMetaState & code) != 0) {  			ourMetaState &= ~code;  			ourMetaState |= code << 1; -		} else +		} else if (forceSticky || (stickyMetas & code) != 0) {  			ourMetaState |= code; +		} else { +			// skip redraw +			return; +		}  		bridge.redraw();  	} +	public void metaPress(int code) { +		metaPress(code, false); +	} +  	public void setTerminalKeyMode(String keymode) {  		this.keymode = keymode;  	} @@ -538,18 +588,28 @@ public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceCha  		if (PreferenceConstants.KEYMODE.equals(key) ||  		    PreferenceConstants.SHIFT_FKEYS.equals(key) ||  		    PreferenceConstants.CTRL_FKEYS.equals(key) || -		    PreferenceConstants.VOLUME_FONT.equals(key)) { +		    PreferenceConstants.VOLUME_FONT.equals(key) || +		    PreferenceConstants.STICKY_MODIFIERS.equals(key)) {  			updatePrefs();  		}  	}  	private void updatePrefs() { -		keymode = prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); +		keymode = prefs.getString(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_NONE);  		shiftedNumbersAreFKeysOnHardKeyboard =  				prefs.getBoolean(PreferenceConstants.SHIFT_FKEYS, false);  		controlNumbersAreFKeysOnSoftKeyboard =  				prefs.getBoolean(PreferenceConstants.CTRL_FKEYS, false);  		volumeKeysChangeFontSize = prefs.getBoolean(PreferenceConstants.VOLUME_FONT, true); +		String stickyModifiers = prefs.getString(PreferenceConstants.STICKY_MODIFIERS, +		                                         PreferenceConstants.NO); +		if (PreferenceConstants.ALT.equals(stickyModifiers)) { +			stickyMetas = OUR_ALT_ON; +		} else if (PreferenceConstants.YES.equals(stickyModifiers)) { +			stickyMetas = OUR_SHIFT_ON | OUR_CTRL_ON | OUR_ALT_ON; +		} else { +			stickyMetas = 0; +		}  	}  	public void setCharset(String encoding) { diff --git a/src/org/connectbot/transport/Local.java b/src/org/connectbot/transport/Local.java index 5ace1b0..f7bbf11 100644 --- a/src/org/connectbot/transport/Local.java +++ b/src/org/connectbot/transport/Local.java @@ -153,6 +153,11 @@ public class Local extends AbsTransport {  	@Override  	public void setDimensions(int columns, int rows, int width, int height) { +		// We are not connected yet. +		if (shellFd == null) { +			return; +		} +  		try {  			Exec.setPtyWindowSize(shellFd, rows, columns, width, height);  		} catch (Exception e) { diff --git a/src/org/connectbot/util/HostDatabase.java b/src/org/connectbot/util/HostDatabase.java index 2a92bab..c6707ae 100644 --- a/src/org/connectbot/util/HostDatabase.java +++ b/src/org/connectbot/util/HostDatabase.java @@ -47,7 +47,7 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	public final static String TAG = "ConnectBot.HostDatabase";  	public final static String DB_NAME = "hosts"; -	public final static int DB_VERSION = 22; +	public final static int DB_VERSION = 24;  	public final static String TABLE_HOSTS = "hosts";  	public final static String FIELD_HOST_NICKNAME = "nickname"; @@ -69,6 +69,7 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	public final static String FIELD_HOST_COMPRESSION = "compression";  	public final static String FIELD_HOST_ENCODING = "encoding";  	public final static String FIELD_HOST_STAYCONNECTED = "stayconnected"; +	public final static String FIELD_HOST_QUICKDISCONNECT = "quickdisconnect";  	public final static String TABLE_PORTFORWARDS = "portforwards";  	public final static String FIELD_PORTFORWARD_HOSTID = "hostid"; @@ -139,9 +140,14 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	public static final Object[] dbLock = new Object[0]; +	/** Used during upgrades from DB version 23 to 24. */ +	private final float displayDensity; +  	public HostDatabase(Context context) {  		super(context, DB_NAME, null, DB_VERSION); +		this.displayDensity = context.getResources().getDisplayMetrics().density; +  		getWritableDatabase().close();  	} @@ -169,7 +175,8 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  				+ FIELD_HOST_WANTSESSION + " TEXT DEFAULT '" + Boolean.toString(true) + "', "  				+ FIELD_HOST_COMPRESSION + " TEXT DEFAULT '" + Boolean.toString(false) + "', "  				+ FIELD_HOST_ENCODING + " TEXT DEFAULT '" + ENCODING_DEFAULT + "', " -				+ FIELD_HOST_STAYCONNECTED + " TEXT)"); +				+ FIELD_HOST_STAYCONNECTED + " TEXT, " +				+ FIELD_HOST_QUICKDISCONNECT + " TEXT DEFAULT '" + Boolean.toString(false) + "')");  		db.execSQL("CREATE TABLE " + TABLE_PORTFORWARDS  				+ " (_id INTEGER PRIMARY KEY, " @@ -259,12 +266,18 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  			db.execSQL("DROP TABLE " + TABLE_COLOR_DEFAULTS);  			db.execSQL(CREATE_TABLE_COLOR_DEFAULTS);  			db.execSQL(CREATE_TABLE_COLOR_DEFAULTS_INDEX); +		case 22: +			db.execSQL("ALTER TABLE " + TABLE_HOSTS +					+ " ADD COLUMN " + FIELD_HOST_QUICKDISCONNECT + " TEXT DEFAULT '" + Boolean.toString(false) + "'"); +		case 23: +			db.execSQL("UPDATE " + TABLE_HOSTS +					+ " SET " + FIELD_HOST_FONTSIZE + " = " + FIELD_HOST_FONTSIZE + " / " + displayDensity);  		}  	}  	/**  	 * Touch a specific host to update its "last connected" field. -	 * @param nickname Nickname field of host to update +	 * @param host host to update  	 */  	public void touchHost(HostBean host) {  		long now = System.currentTimeMillis() / 1000; @@ -353,8 +366,7 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	}  	/** -	 * @param hosts -	 * @param c +	 * @param c cursor to read from  	 */  	private List<HostBean> createHostBeans(Cursor c) {  		List<HostBean> hosts = new LinkedList<HostBean>(); @@ -376,8 +388,8 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  			COL_FONTSIZE = c.getColumnIndexOrThrow(FIELD_HOST_FONTSIZE),  			COL_COMPRESSION = c.getColumnIndexOrThrow(FIELD_HOST_COMPRESSION),  			COL_ENCODING = c.getColumnIndexOrThrow(FIELD_HOST_ENCODING), -			COL_STAYCONNECTED = c.getColumnIndexOrThrow(FIELD_HOST_STAYCONNECTED); - +			COL_STAYCONNECTED = c.getColumnIndexOrThrow(FIELD_HOST_STAYCONNECTED), +			COL_QUICKDISCONNECT = c.getColumnIndexOrThrow(FIELD_HOST_QUICKDISCONNECT);  		while (c.moveToNext()) {  			HostBean host = new HostBean(); @@ -400,6 +412,7 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  			host.setCompression(Boolean.valueOf(c.getString(COL_COMPRESSION)));  			host.setEncoding(c.getString(COL_ENCODING));  			host.setStayConnected(Boolean.valueOf(c.getString(COL_STAYCONNECTED))); +			host.setQuickDisconnect(Boolean.valueOf(c.getString(COL_QUICKDISCONNECT)));  			hosts.add(host);  		} @@ -408,8 +421,8 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	}  	/** -	 * @param c -	 * @return +	 * @param c cursor with zero or more hosts +	 * @return the first host from the cursor or {@code null} if none.  	 */  	private HostBean getFirstHostBean(Cursor c) {  		HostBean host = null; @@ -424,13 +437,8 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	}  	/** -	 * @param nickname -	 * @param protocol -	 * @param username -	 * @param hostname -	 * @param hostname2 -	 * @param port -	 * @return +	 * @param selection parameters describing the desired host +	 * @return host matching selection or {@code null}.  	 */  	public HostBean findHost(Map<String, String> selection) {  		StringBuilder selectionBuilder = new StringBuilder(); @@ -475,8 +483,8 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	}  	/** -	 * @param hostId -	 * @return +	 * @param hostId host id for the host +	 * @return host matching the hostId or {@code null} if none match  	 */  	public HostBean findHostById(long hostId) {  		HostBean host; @@ -496,10 +504,10 @@ public class HostDatabase extends RobustSQLiteOpenHelper {  	/**  	 * Record the given hostkey into database under this nickname. -	 * @param hostname -	 * @param port -	 * @param hostkeyalgo -	 * @param hostkey +	 * @param hostname hostname to match +	 * @param port port to match +	 * @param hostkeyalgo algorithm for host key +	 * @param hostkey the bytes of the host key itself  	 */  	public void saveKnownHost(String hostname, int port, String hostkeyalgo, byte[] hostkey) {  		ContentValues values = new ContentValues(); diff --git a/src/org/connectbot/util/PreferenceConstants.java b/src/org/connectbot/util/PreferenceConstants.java index ad29c39..d3cd832 100644 --- a/src/org/connectbot/util/PreferenceConstants.java +++ b/src/org/connectbot/util/PreferenceConstants.java @@ -30,11 +30,6 @@ public class PreferenceConstants {  	public static final boolean PRE_HONEYCOMB = SDK_INT < 11;  	public static final String MEMKEYS = "memkeys"; -	public static final String UPDATE = "update"; - -	public static final String UPDATE_DAILY = "Daily"; -	public static final String UPDATE_WEEKLY = "Weekly"; -	public static final String UPDATE_NEVER = "Never";  	public static final String LAST_CHECKED = "lastchecked"; @@ -56,6 +51,7 @@ public class PreferenceConstants {  	public static final String KEYMODE_RIGHT = "Use right-side keys";  	public static final String KEYMODE_LEFT = "Use left-side keys"; +	public static final String KEYMODE_NONE = "none";  	public static final String CAMERA = "camera"; @@ -85,6 +81,10 @@ public class PreferenceConstants {  	public static final String SHIFT_FKEYS = "shiftfkeys";  	public static final String CTRL_FKEYS = "ctrlfkeys";  	public static final String VOLUME_FONT = "volumefont"; +	public static final String STICKY_MODIFIERS = "stickymodifiers"; +	public static final String YES = "yes"; +	public static final String NO = "no"; +	public static final String ALT = "alt";  	/* Backup identifiers */  	public static final String BACKUP_PREF_KEY = "prefs"; diff --git a/src/org/connectbot/util/UberColorPickerDialog.java b/src/org/connectbot/util/UberColorPickerDialog.java index 2c01b30..dc36bcb 100644 --- a/src/org/connectbot/util/UberColorPickerDialog.java +++ b/src/org/connectbot/util/UberColorPickerDialog.java @@ -33,6 +33,8 @@  package org.connectbot.util; +import org.connectbot.R; +  import android.app.Dialog;  import android.content.Context;  import android.graphics.Bitmap; @@ -80,7 +82,6 @@ public class UberColorPickerDialog extends Dialog {  	 * @param context  	 * @param listener  	 * @param initialColor -	 * @param showTitle If true, a title is shown across the top of the dialog.  If false a toast is shown instead.  	 */  	public UberColorPickerDialog(Context context,  							OnColorChangedListener listener, @@ -109,7 +110,7 @@ public class UberColorPickerDialog extends Dialog {  		int screenWidth = dm.widthPixels;  		int screenHeight = dm.heightPixels; -		setTitle("Pick a color (try the trackball)"); +		setTitle(getContext().getResources().getString(R.string.title_color_picker));  		try {  			setContentView(new ColorPickerView(getContext(), l, screenWidth, screenHeight, mInitialColor)); @@ -132,20 +133,13 @@ public class UberColorPickerDialog extends Dialog {  	 * I highly recommend adding new methods to the end of the list.  If you want to try to reorder the list, you're on your own.  	 */  	private static class ColorPickerView extends View { -		private static int SWATCH_WIDTH = 95; -		private static final int SWATCH_HEIGHT = 60; - -		private static int PALETTE_POS_X = 0; -		private static int PALETTE_POS_Y = SWATCH_HEIGHT; -		private static final int PALETTE_DIM = SWATCH_WIDTH * 2; -		private static final int PALETTE_RADIUS = PALETTE_DIM / 2; -		private static final int PALETTE_CENTER_X = PALETTE_RADIUS; -		private static final int PALETTE_CENTER_Y = PALETTE_RADIUS; +		private static int SWATCH_WIDTH_PORTRAIT_DP = 95; +		private static int SWATCH_WIDTH_LANDSCAPE_DP = 110; +		private static final int SWATCH_HEIGHT_DP = 60; -		private static final int SLIDER_THICKNESS = 40; +		private static final int PALETTE_DIM_DP = SWATCH_WIDTH_PORTRAIT_DP * 2; -		private static int VIEW_DIM_X = PALETTE_DIM; -		private static int VIEW_DIM_Y = SWATCH_HEIGHT; +		private static final int SLIDER_THICKNESS_DP = 40;  		//NEW_METHOD_WORK_NEEDED_HERE  		private static final int METHOD_HS_V_PALETTE = 0; @@ -158,7 +152,11 @@ public class UberColorPickerDialog extends Dialog {  		private static final int TRACK_HS_PALETTE = 30;  		private static final int TRACK_VER_VALUE_SLIDER = 31; -		private static final int TEXT_SIZE = 12; +		private static final int TEXT_SIZE_DP = 12; +		private static final int TEXT_SIZE_LABEL_DP = 12; + +		private static final int BUTTON_TEXT_MARGIN_DP = 16; +  		private static int[] TEXT_HSV_POS = new int[2];  		private static int[] TEXT_RGB_POS = new int[2];  		private static int[] TEXT_YUV_POS = new int[2]; @@ -166,6 +164,19 @@ public class UberColorPickerDialog extends Dialog {  		private static final float PI = 3.141592653589793f; +		private final int mSwatchWidthPx; +		private final int mTextSizePx; +		private final int mTextSizeLabelPx; +		private final int mPalettePosX; +		private final int mPalettePosY; +		private final int mPaletteDimPx; +		private final int mPaletteRadiusPx; +		private final int mSliderThicknessPx; +		private final int mViewDimXPx; +		private final int mViewDimYPx; +		private final int mPaletteCenterPx; +		private final int mButtonTextMarginPx; +  		private int mMethod = METHOD_HS_V_PALETTE;  		private int mTracking = TRACKED_NONE;	//What object on screen is currently being tracked for movement @@ -224,6 +235,10 @@ public class UberColorPickerDialog extends Dialog {  		throws Exception {  			super(c); +			DisplayMetrics metrics = c.getResources().getDisplayMetrics(); +			mTextSizePx = (int) (TEXT_SIZE_DP * metrics.density + 0.5f); +			mTextSizeLabelPx = (int) (TEXT_SIZE_LABEL_DP * metrics.density + 0.5f); +  			//We need to make the dialog focusable to retrieve trackball events.  			setFocusable(true); @@ -235,56 +250,64 @@ public class UberColorPickerDialog extends Dialog {  			updateAllFromHSV(); +			mPaletteDimPx = (int) (PALETTE_DIM_DP * metrics.density + 0.5f); +			mSliderThicknessPx = (int) (SLIDER_THICKNESS_DP * metrics.density + 0.5f); +			mButtonTextMarginPx = (int) (BUTTON_TEXT_MARGIN_DP * metrics.density + 0.5f); +  			//Setup the layout based on whether this is a portrait or landscape orientation. -			if (width <= height) {	//Portrait layout -				SWATCH_WIDTH = (PALETTE_DIM + SLIDER_THICKNESS) / 2; +			if (width <= height) {        //Portrait layout +				mSwatchWidthPx = (int) (((PALETTE_DIM_DP + SLIDER_THICKNESS_DP) / 2) * metrics.density + 0.5f); +				final int swatchHeightPx = (int) (SWATCH_HEIGHT_DP * metrics.density + 0.5f); -				PALETTE_POS_X = 0; -				PALETTE_POS_Y = TEXT_SIZE * 4 + SWATCH_HEIGHT; +				mPalettePosX = 0; +				mPalettePosY = mTextSizePx * 4 + swatchHeightPx;  				//Set more rects, lots of rects -				mOldSwatchRect.set(0, TEXT_SIZE * 4, SWATCH_WIDTH, TEXT_SIZE * 4 + SWATCH_HEIGHT); -				mNewSwatchRect.set(SWATCH_WIDTH, TEXT_SIZE * 4, SWATCH_WIDTH * 2, TEXT_SIZE * 4 + SWATCH_HEIGHT); -				mPaletteRect.set(0, PALETTE_POS_Y, PALETTE_DIM, PALETTE_POS_Y + PALETTE_DIM); -				mVerSliderRect.set(PALETTE_DIM, PALETTE_POS_Y, PALETTE_DIM + SLIDER_THICKNESS, PALETTE_POS_Y + PALETTE_DIM); +				mOldSwatchRect.set(0, mTextSizePx * 4, mSwatchWidthPx, mTextSizePx * 4 + swatchHeightPx); +				mNewSwatchRect.set(mSwatchWidthPx, mTextSizePx * 4, mSwatchWidthPx * 2, mTextSizePx * 4 + swatchHeightPx); +				mPaletteRect.set(0, mPalettePosY, mPaletteDimPx, mPalettePosY + mPaletteDimPx); +				mVerSliderRect.set(mPaletteDimPx, mPalettePosY, mPaletteDimPx + mSliderThicknessPx, mPalettePosY + mPaletteDimPx); -				TEXT_HSV_POS[0] = 3; +				TEXT_HSV_POS[0] = (int) (3 * metrics.density + 0.5f);  				TEXT_HSV_POS[1] = 0; -				TEXT_RGB_POS[0] = TEXT_HSV_POS[0] + 50; +				TEXT_RGB_POS[0] = TEXT_HSV_POS[0] + (int) (50 * metrics.density + 0.5f);  				TEXT_RGB_POS[1] = TEXT_HSV_POS[1]; -				TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + 100; +				TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + (int) (100 * metrics.density + 0.5f);  				TEXT_YUV_POS[1] = TEXT_HSV_POS[1]; -				TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + 150; +				TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + (int) (150 * metrics.density + 0.5f);  				TEXT_HEX_POS[1] = TEXT_HSV_POS[1]; -				VIEW_DIM_X = PALETTE_DIM + SLIDER_THICKNESS; -				VIEW_DIM_Y = SWATCH_HEIGHT + PALETTE_DIM + TEXT_SIZE * 4; -			} -			else {	//Landscape layout -				SWATCH_WIDTH = 110; +				mViewDimXPx = mPaletteDimPx + mSliderThicknessPx; +				mViewDimYPx = swatchHeightPx + mPaletteDimPx + mTextSizePx * 4; +			} else {        //Landscape layout +				mSwatchWidthPx = (int) (SWATCH_WIDTH_LANDSCAPE_DP * metrics.density + 0.5f); +				final int swatchHeightPx = (int) (SWATCH_HEIGHT_DP * metrics.density + 0.5f); -				PALETTE_POS_X = SWATCH_WIDTH; -				PALETTE_POS_Y = 0; +				mPalettePosX = mSwatchWidthPx; +				mPalettePosY = 0;  				//Set more rects, lots of rects -				mOldSwatchRect.set(0, TEXT_SIZE * 7, SWATCH_WIDTH, TEXT_SIZE * 7 + SWATCH_HEIGHT); -				mNewSwatchRect.set(0, TEXT_SIZE * 7 + SWATCH_HEIGHT, SWATCH_WIDTH, TEXT_SIZE * 7 + SWATCH_HEIGHT * 2); -				mPaletteRect.set(SWATCH_WIDTH, PALETTE_POS_Y, SWATCH_WIDTH + PALETTE_DIM, PALETTE_POS_Y + PALETTE_DIM); -				mVerSliderRect.set(SWATCH_WIDTH + PALETTE_DIM, PALETTE_POS_Y, SWATCH_WIDTH + PALETTE_DIM + SLIDER_THICKNESS, PALETTE_POS_Y + PALETTE_DIM); +				mOldSwatchRect.set(0, mTextSizePx * 7, mSwatchWidthPx, mTextSizePx * 7 + swatchHeightPx); +				mNewSwatchRect.set(0, mTextSizePx * 7 + mSliderThicknessPx, mSwatchWidthPx, mTextSizePx * 7 + swatchHeightPx * 2); +				mPaletteRect.set(mSwatchWidthPx, mPalettePosY, mSwatchWidthPx + mPaletteDimPx, mPalettePosY + mPaletteDimPx); +				mVerSliderRect.set(mSwatchWidthPx + mPaletteDimPx, mPalettePosY, mSwatchWidthPx + mPaletteDimPx + mSliderThicknessPx, mPalettePosY + mPaletteDimPx); -				TEXT_HSV_POS[0] = 3; +				TEXT_HSV_POS[0] = (int) (3 * metrics.density + 0.5f);  				TEXT_HSV_POS[1] = 0;  				TEXT_RGB_POS[0] = TEXT_HSV_POS[0]; -				TEXT_RGB_POS[1] = (int)(TEXT_HSV_POS[1] + TEXT_SIZE * 3.5); -				TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + 50; -				TEXT_YUV_POS[1] = (int)(TEXT_HSV_POS[1] + TEXT_SIZE * 3.5); -				TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + 50; +				TEXT_RGB_POS[1] = (int) (TEXT_HSV_POS[1] + mTextSizePx * 3.5); +				TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + (int) (50 * metrics.density + 0.5f); +				TEXT_YUV_POS[1] = (int) (TEXT_HSV_POS[1] + mTextSizePx * 3.5); +				TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + (int) (50 * metrics.density + 0.5f);  				TEXT_HEX_POS[1] = TEXT_HSV_POS[1]; -				VIEW_DIM_X = PALETTE_POS_X + PALETTE_DIM + SLIDER_THICKNESS; -				VIEW_DIM_Y = Math.max(mNewSwatchRect.bottom, PALETTE_DIM); +				mViewDimXPx = mPalettePosX + mPaletteDimPx + mSliderThicknessPx; +				mViewDimYPx = Math.max(mNewSwatchRect.bottom, mPaletteDimPx);  			} +			mPaletteCenterPx = mPaletteDimPx / 2; +			mPaletteRadiusPx = mPaletteDimPx / 2; +  			//Rainbows make everybody happy!  			mSpectrumColorsRev = new int[] {  				0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, @@ -305,18 +328,18 @@ public class UberColorPickerDialog extends Dialog {  			mSwatchNew.setColor(Color.HSVToColor(mHSV));  			Shader shaderA = new SweepGradient(0, 0, mSpectrumColorsRev, null); -			Shader shaderB = new RadialGradient(0, 0, PALETTE_CENTER_X, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP); +			Shader shaderB = new RadialGradient(0, 0, mPaletteCenterPx, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP);  			Shader shader = new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SCREEN);  			mOvalHueSat = new Paint(Paint.ANTI_ALIAS_FLAG);  			mOvalHueSat.setShader(shader);  			mOvalHueSat.setStyle(Paint.Style.FILL);  			mOvalHueSat.setDither(true); -			mVerSliderBM = Bitmap.createBitmap(SLIDER_THICKNESS, PALETTE_DIM, Bitmap.Config.RGB_565); +			mVerSliderBM = Bitmap.createBitmap(mSliderThicknessPx, mPaletteDimPx, Bitmap.Config.RGB_565);  			mVerSliderCv = new Canvas(mVerSliderBM);  			for (int i = 0; i < 3; i++) { -				mHorSlidersBM[i] = Bitmap.createBitmap(PALETTE_DIM, SLIDER_THICKNESS, Bitmap.Config.RGB_565); +				mHorSlidersBM[i] = Bitmap.createBitmap(mPaletteDimPx, mSliderThicknessPx, Bitmap.Config.RGB_565);  				mHorSlidersCv[i] = new Canvas(mHorSlidersBM[i]);  			} @@ -332,7 +355,7 @@ public class UberColorPickerDialog extends Dialog {  			//Add Paints to represent the icon for the new method  			shaderA = new SweepGradient(0, 0, mSpectrumColorsRev, null); -			shaderB = new RadialGradient(0, 0, PALETTE_DIM / 2, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP); +			shaderB = new RadialGradient(0, 0, mPaletteDimPx / 2, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP);  			shader = new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SCREEN);  			mOvalHueSatSmall = new Paint(Paint.ANTI_ALIAS_FLAG);  			mOvalHueSatSmall.setShader(shader); @@ -345,7 +368,7 @@ public class UberColorPickerDialog extends Dialog {  			//Make a basic text Paint.  			mText = new Paint(Paint.ANTI_ALIAS_FLAG); -			mText.setTextSize(TEXT_SIZE); +			mText.setTextSize(mTextSizePx);  			mText.setColor(Color.WHITE);  			//Kickstart @@ -375,7 +398,7 @@ public class UberColorPickerDialog extends Dialog {  		private void drawSwatches(Canvas canvas) {  			float[] hsv = new float[3]; -			mText.setTextSize(16); +			mText.setTextSize(mTextSizePx);  			//Draw the original swatch  			canvas.drawRect(mOldSwatchRect, mSwatchOld); @@ -384,17 +407,17 @@ public class UberColorPickerDialog extends Dialog {  			//	hsv[1] = 0;  			if (hsv[2] > .5)  				mText.setColor(Color.BLACK); -			canvas.drawText("Revert", mOldSwatchRect.left + SWATCH_WIDTH / 2 - mText.measureText("Revert") / 2, mOldSwatchRect.top + 16, mText); +			canvas.drawText("Revert", mOldSwatchRect.left + mSwatchWidthPx / 2 - mText.measureText("Revert") / 2, mOldSwatchRect.top + mButtonTextMarginPx, mText);  			mText.setColor(Color.WHITE);  			//Draw the new swatch  			canvas.drawRect(mNewSwatchRect, mSwatchNew);  			if (mHSV[2] > .5)  				mText.setColor(Color.BLACK); -			canvas.drawText("Accept", mNewSwatchRect.left + SWATCH_WIDTH / 2 - mText.measureText("Accept") / 2, mNewSwatchRect.top + 16, mText); +			canvas.drawText("Accept", mNewSwatchRect.left + mSwatchWidthPx / 2 - mText.measureText("Accept") / 2, mNewSwatchRect.top + mButtonTextMarginPx, mText);  			mText.setColor(Color.WHITE); -			mText.setTextSize(TEXT_SIZE); +			mText.setTextSize(mTextSizePx);  		}  		/** @@ -403,25 +426,25 @@ public class UberColorPickerDialog extends Dialog {  		 */  		private void writeColorParams(Canvas canvas) {  			if (mHSVenabled) { -				canvas.drawText("H: " + Integer.toString((int)(mHSV[0] / 360.0f * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE, mText); -				canvas.drawText("S: " + Integer.toString((int)(mHSV[1] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE * 2, mText); -				canvas.drawText("V: " + Integer.toString((int)(mHSV[2] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE * 3, mText); +				canvas.drawText("H: " + Integer.toString((int) (mHSV[0] / 360.0f * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + mTextSizePx, mText); +				canvas.drawText("S: " + Integer.toString((int) (mHSV[1] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + mTextSizePx * 2, mText); +				canvas.drawText("V: " + Integer.toString((int) (mHSV[2] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + mTextSizePx * 3, mText);  			}  			if (mRGBenabled) { -				canvas.drawText("R: " + mRGB[0], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE, mText); -				canvas.drawText("G: " + mRGB[1], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE * 2, mText); -				canvas.drawText("B: " + mRGB[2], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE * 3, mText); +				canvas.drawText("R: " + mRGB[0], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + mTextSizePx, mText); +				canvas.drawText("G: " + mRGB[1], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + mTextSizePx * 2, mText); +				canvas.drawText("B: " + mRGB[2], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + mTextSizePx * 3, mText);  			}  			if (mYUVenabled) { -				canvas.drawText("Y: " + Integer.toString((int)(mYUV[0] * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE, mText); -				canvas.drawText("U: " + Integer.toString((int)((mYUV[1] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE * 2, mText); -				canvas.drawText("V: " + Integer.toString((int)((mYUV[2] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE * 3, mText); +				canvas.drawText("Y: " + Integer.toString((int) (mYUV[0] * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + mTextSizePx, mText); +				canvas.drawText("U: " + Integer.toString((int) ((mYUV[1] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + mTextSizePx * 2, mText); +				canvas.drawText("V: " + Integer.toString((int) ((mYUV[2] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + mTextSizePx * 3, mText);  			}  			if (mHexenabled) -				canvas.drawText("#" + mHexStr, TEXT_HEX_POS[0], TEXT_HEX_POS[1] + TEXT_SIZE, mText); +				canvas.drawText("#" + mHexStr, TEXT_HEX_POS[0], TEXT_HEX_POS[1] + mTextSizePx, mText);  		}  		/** @@ -444,9 +467,9 @@ public class UberColorPickerDialog extends Dialog {  		 */  		private void markVerSlider(Canvas canvas, int markerPos) {  			mPosMarker.setColor(Color.BLACK); -			canvas.drawRect(new Rect(0, markerPos - 2, SLIDER_THICKNESS, markerPos + 3), mPosMarker); +			canvas.drawRect(new Rect(0, markerPos - 2, mSliderThicknessPx, markerPos + 3), mPosMarker);  			mPosMarker.setColor(Color.WHITE); -			canvas.drawRect(new Rect(0, markerPos, SLIDER_THICKNESS, markerPos + 1), mPosMarker); +			canvas.drawRect(new Rect(0, markerPos, mSliderThicknessPx, markerPos + 1), mPosMarker);  		}  		/** @@ -455,9 +478,9 @@ public class UberColorPickerDialog extends Dialog {  		 */  		private void hilightFocusedVerSlider(Canvas canvas) {  			mPosMarker.setColor(Color.WHITE); -			canvas.drawRect(new Rect(0, 0, SLIDER_THICKNESS, PALETTE_DIM), mPosMarker); +			canvas.drawRect(new Rect(0, 0, mSliderThicknessPx, mPaletteDimPx), mPosMarker);  			mPosMarker.setColor(Color.BLACK); -			canvas.drawRect(new Rect(2, 2, SLIDER_THICKNESS - 2, PALETTE_DIM - 2), mPosMarker); +			canvas.drawRect(new Rect(2, 2, mSliderThicknessPx - 2, mPaletteDimPx - 2), mPosMarker);  		}  		/** @@ -466,9 +489,9 @@ public class UberColorPickerDialog extends Dialog {  		 */  		private void hilightFocusedOvalPalette(Canvas canvas) {  			mPosMarker.setColor(Color.WHITE); -			canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mPosMarker); +			canvas.drawOval(new RectF(-mPaletteRadiusPx, -mPaletteRadiusPx, mPaletteRadiusPx, mPaletteRadiusPx), mPosMarker);  			mPosMarker.setColor(Color.BLACK); -			canvas.drawOval(new RectF(-PALETTE_RADIUS + 2, -PALETTE_RADIUS + 2, PALETTE_RADIUS - 2, PALETTE_RADIUS - 2), mPosMarker); +			canvas.drawOval(new RectF(-mPaletteRadiusPx + 2, -mPaletteRadiusPx + 2, mPaletteRadiusPx - 2, mPaletteRadiusPx - 2), mPosMarker);  		}  		//NEW_METHOD_WORK_NEEDED_HERE @@ -480,19 +503,19 @@ public class UberColorPickerDialog extends Dialog {  		private void drawHSV1Palette(Canvas canvas) {  			canvas.save(); -			canvas.translate(PALETTE_POS_X, PALETTE_POS_Y); +			canvas.translate(mPalettePosX, mPalettePosY);  			//Draw the 2D palette -			canvas.translate(PALETTE_CENTER_X, PALETTE_CENTER_Y); -			canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mOvalHueSat); -			canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mValDimmer); +			canvas.translate(mPaletteCenterPx, mPaletteCenterPx); +			canvas.drawOval(new RectF(-mPaletteRadiusPx, -mPaletteRadiusPx, mPaletteRadiusPx, mPaletteRadiusPx), mOvalHueSat); +			canvas.drawOval(new RectF(-mPaletteRadiusPx, -mPaletteRadiusPx, mPaletteRadiusPx, mPaletteRadiusPx), mValDimmer);  			if (mFocusedControl == 0)  				hilightFocusedOvalPalette(canvas);  			mark2DPalette(canvas, mCoord[0], mCoord[1]); -			canvas.translate(-PALETTE_CENTER_X, -PALETTE_CENTER_Y); +			canvas.translate(-mPaletteCenterPx, -mPaletteCenterPx);  			//Draw the 1D slider -			canvas.translate(PALETTE_DIM, 0); +			canvas.translate(mPaletteDimPx, 0);  			canvas.drawBitmap(mVerSliderBM, 0, 0, null);  			if (mFocusedControl == 1)  				hilightFocusedVerSlider(canvas); @@ -520,12 +543,12 @@ public class UberColorPickerDialog extends Dialog {  			setOvalValDimmer();  			setVerValSlider(); -			float angle = 2*PI - mHSV[0] / (180 / 3.1415927f); -			float radius = mHSV[1] * PALETTE_RADIUS; -			mCoord[0] = (int)(Math.cos(angle) * radius); -			mCoord[1] = (int)(Math.sin(angle) * radius); +			float angle = 2 * PI - mHSV[0] / (180 / 3.1415927f); +			float radius = mHSV[1] * mPaletteRadiusPx; +			mCoord[0] = (int) (Math.cos(angle) * radius); +			mCoord[1] = (int) (Math.sin(angle) * radius); -			mCoord[2] = PALETTE_DIM - (int)(mHSV[2] * PALETTE_DIM); +			mCoord[2] = mPaletteDimPx - (int) (mHSV[2] * mPaletteDimPx);  		}  		//NEW_METHOD_WORK_NEEDED_HERE @@ -558,7 +581,7 @@ public class UberColorPickerDialog extends Dialog {  			GradientDrawable gradDraw = new GradientDrawable(Orientation.TOP_BOTTOM, colors);  			gradDraw.setDither(true);  			gradDraw.setLevel(10000); -			gradDraw.setBounds(0, 0, SLIDER_THICKNESS, PALETTE_DIM); +			gradDraw.setBounds(0, 0, mSliderThicknessPx, mPaletteDimPx);  			gradDraw.draw(mVerSliderCv);  		} @@ -567,7 +590,7 @@ public class UberColorPickerDialog extends Dialog {  		 */  		@Override  		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { -			setMeasuredDimension(VIEW_DIM_X, VIEW_DIM_Y); +			setMeasuredDimension(mViewDimXPx, mViewDimYPx);  		}  		/** @@ -744,18 +767,18 @@ public class UberColorPickerDialog extends Dialog {  		 	mCoord[0] += x2;  		 	mCoord[1] += y2; -		 	if (mCoord[0] < -PALETTE_RADIUS) -		 		mCoord[0] = -PALETTE_RADIUS; -		 	else if (mCoord[0] > PALETTE_RADIUS) -		 		mCoord[0] = PALETTE_RADIUS; -		 	if (mCoord[1] < -PALETTE_RADIUS) -		 		mCoord[1] = -PALETTE_RADIUS; -		 	else if (mCoord[1] > PALETTE_RADIUS) -		 		mCoord[1] = PALETTE_RADIUS; +			if (mCoord[0] < -mPaletteRadiusPx) +				mCoord[0] = -mPaletteRadiusPx; +			else if (mCoord[0] > mPaletteRadiusPx) +				mCoord[0] = mPaletteRadiusPx; +			if (mCoord[1] < -mPaletteRadiusPx) +				mCoord[1] = -mPaletteRadiusPx; +			else if (mCoord[1] > mPaletteRadiusPx) +				mCoord[1] = mPaletteRadiusPx; -			float radius = (float)java.lang.Math.sqrt(mCoord[0] * mCoord[0] + mCoord[1] * mCoord[1]); -			if (radius > PALETTE_RADIUS) -				radius = PALETTE_RADIUS; +			float radius = (float) java.lang.Math.sqrt(mCoord[0] * mCoord[0] + mCoord[1] * mCoord[1]); +			if (radius > mPaletteRadiusPx) +				radius = mPaletteRadiusPx;  			float angle = (float)java.lang.Math.atan2(mCoord[1], mCoord[0]);  			// need to turn angle [-PI ... PI] into unit [0....1] @@ -771,7 +794,7 @@ public class UberColorPickerDialog extends Dialog {  			float[] hsv = new float[3];  			Color.colorToHSV(c, hsv);  			mHSV[0] = hsv[0]; -			mHSV[1] = radius / PALETTE_RADIUS; +			mHSV[1] = radius / mPaletteRadiusPx;  			updateAllFromHSV();  			mSwatchNew.setColor(Color.HSVToColor(mHSV)); @@ -797,7 +820,7 @@ public class UberColorPickerDialog extends Dialog {  				mHSV[2] += (increase ? jump : -jump) / 256.0f;  				mHSV[2] = pinToUnit(mHSV[2]);  				updateAllFromHSV(); -				mCoord[2] = PALETTE_DIM - (int)(mHSV[2] * PALETTE_DIM); +				mCoord[2] = mPaletteDimPx - (int) (mHSV[2] * mPaletteDimPx);  				mSwatchNew.setColor(Color.HSVToColor(mHSV)); @@ -872,11 +895,11 @@ public class UberColorPickerDialog extends Dialog {  			float y = event.getY();  			//Generate coordinates which are palette=local with the origin at the upper left of the main 2D palette -			int y2 = (int)(pin(round(y - PALETTE_POS_Y), PALETTE_DIM)); +			int y2 = (int) (pin(round(y - mPalettePosY), mPaletteDimPx));  			//Generate coordinates which are palette-local with the origin at the center of the main 2D palette -			float circlePinnedX = x - PALETTE_POS_X - PALETTE_CENTER_X; -			float circlePinnedY = y - PALETTE_POS_Y - PALETTE_CENTER_Y; +			float circlePinnedX = x - mPalettePosX - mPaletteCenterPx; +			float circlePinnedY = y - mPalettePosY - mPaletteCenterPx;  			//Is the event in a swatch?  			boolean inSwatchOld = ptInRect(round(x), round(y), mOldSwatchRect); @@ -886,11 +909,11 @@ public class UberColorPickerDialog extends Dialog {  			float radius = (float)java.lang.Math.sqrt(circlePinnedX * circlePinnedX + circlePinnedY * circlePinnedY);  			//Is the event in a circle-pinned 2D palette? -			boolean inOvalPalette = radius <= PALETTE_RADIUS; +			boolean inOvalPalette = radius <= mPaletteRadiusPx;  			//Pin the radius -			if (radius > PALETTE_RADIUS) -				radius = PALETTE_RADIUS; +			if (radius > mPaletteRadiusPx) +				radius = mPaletteRadiusPx;  			//Is the event in a vertical slider to the right of the main 2D palette  			boolean inVerSlider = ptInRect(round(x), round(y), mVerSliderRect); @@ -935,7 +958,7 @@ public class UberColorPickerDialog extends Dialog {  						float[] hsv = new float[3];  						Color.colorToHSV(c, hsv);  						mHSV[0] = hsv[0]; -						mHSV[1] = radius / PALETTE_RADIUS; +						mHSV[1] = radius / mPaletteRadiusPx;  						updateAllFromHSV();  						mSwatchNew.setColor(Color.HSVToColor(mHSV)); @@ -946,7 +969,7 @@ public class UberColorPickerDialog extends Dialog {  					else if (mTracking == TRACK_VER_VALUE_SLIDER) {  						if (mCoord[2] != y2) {  							mCoord[2] = y2; -							float value = 1.0f - (float)y2 / (float)PALETTE_DIM; +							float value = 1.0f - (float) y2 / (float) mPaletteDimPx;  							mHSV[2] = value;  							updateAllFromHSV(); | 
