Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions modules/colorpicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
exports.show = function(options) {
var colors;
var isPicking=true;
var previewTimeout;
if (!options.colors||options.colors.length==0) {
colors = [
"#000000", "#808080", "#AAAAAA", "#FFFFFF",
"#FF9999", "#FFCC99", "#FFFF99", "#99FF99", "#99FFFF", "#9999FF", "#FF99FF",
"#FF0000", "#FF8800", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF", "#FF00FF",
"#880000", "#884400", "#888800", "#008800", "#008888", "#000088", "#880088"
];
} else {
colors = options.colors;
}
if(colors.length>36) throw new Error("More than 36 colors provided, cannot display");

if(!options.onSelect) throw new Error("No onSelect function provided");
if(!options.back) throw new Error("No back function provided");

var rect = Bangle.appRect;
var W = rect.w;
var H = rect.h;
var n = colors.length;
var COLS = Math.round(Math.sqrt(n));
var ROWS = Math.ceil(n / COLS);
var CW = (W / COLS) | 0;
var CH = (H / ROWS) | 0;
var selectedColors=options.startingSelection?options.startingSelection:[];
var insetX = (CW * 0.15) | 0;
var insetY = (CH * 0.15) | 0;
function draw() {
g.clearRect(rect);
for (var i = 0; i < n; i++) {
var col = i % COLS;
var row = (i / COLS) | 0;
var x = rect.x + col * CW;
var y = rect.y + row * CH;
var oldCH=CH;
var oldCW=CW;
if(options.multiSelect){
if(selectedColors.includes(colors[i])){
x += insetX;
y += insetY;
CW -= insetX * 2;
CH -= insetY * 2;
}
}
g.setColor(colors[i])
.fillRect(x + 1, y + 1, x + CW - 1, y + CH - 1)
.setColor(g.theme.fg)
.drawRect(x, y, x + CW, y + CH);
CH=oldCH;
CW=oldCW;
}

}

function colorAt(x, y) {
if(y<rect.y)return null;
var col = ((x - rect.x) / CW) | 0;
var row = ((y - rect.y) / CH) | 0;
var i = row * COLS + col;
if (i < 0 || i >= n) return null;
return colors[i];
}

function remove() {
if(previewTimeout){
clearTimeout(previewTimeout);
previewTimeout=null;
}
options.back();
}

function onTouch(btn, xy) {
if(isPicking){
var col = colorAt(xy.x, xy.y);
if (!col) return;
if(!options.multiSelect){
isPicking=false;
if(Bangle.haptic) Bangle.haptic();
options.onSelect(col);
if (options.showPreview === undefined || options.showPreview) {
g.setColor(col)
.fillRect(rect);
if(previewTimeout){
clearTimeout(previewTimeout);
previewTimeout=null;
}
previewTimeout=setTimeout(remove, 0.7 * 1000);
} else {
remove();
}
}else{
if(Bangle.haptic) Bangle.haptic();
if(selectedColors.includes(col)){
//unselect
selectedColors=selectedColors.filter(color => color !== col);
}else{
selectedColors.push(col)
}
options.onSelect(selectedColors);
draw()
}
}
}

Bangle.setUI({
mode: "custom",
touch: function(n, e) { onTouch(n, e); },
btn: function(n) { remove(); },
back: remove,
remove: remove,
redraw: draw
});

draw();
};
38 changes: 38 additions & 0 deletions modules/colorpicker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Color Picker
A module for showing a color picker for easy picking and setting of colors.

<img width="176" height="176" alt="d" src="https://github.com/user-attachments/assets/1fbde2f8-e25a-4a9b-9ce8-40803ae14adb" />

## Usage
Example usage:
```javascript
var menu={
"Color Picker" : function(){
require("colorpicker").show({
onSelect:function(color){
print(color);
},
showPreview:true,
back:function(){
E.showMenu(menu);
}

});
}
}
E.showMenu(menu);

```
<b>Options:</b>

`require("colorpicker").show(opts)` takes in an object of options, listed below:
* `colors`: (Optional), specify a select list of colors to show instead of the default. Must not exceed 36 colors.
* `showPreview`: (Optional), choose whether or not to show a full-screen preview of the color you selected.
* `onSelect`: (Required), function that is called whenever the user changes the selection (selects or unselects a color). Saving logic goes here. In multi-select mode, this is called on every toggle and is passed the current list of selected colors.
* `back`: (Required), function that is called to return to previous state. Color picker listeners are automatically removed.
* `multiSelect` (Optional), if true, then the color picker allows the user to select multiple colors and returns a list of colors in `onSelect`
* `startingSelection` (Optional, only for multi-select mode), array of colors selected at the start, for setting restoration.

## Author
RKBoss6

Loading