New script to build two versions of the package for Max 8 and Max 9 based on prefix in filenames.

This commit is contained in:
2025-10-09 15:05:37 +02:00
parent ea35d06437
commit a003206b63
7 changed files with 310 additions and 200 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
.AppleDouble
.LSOverride
media/
dist/

109
build.sh Executable file
View File

@@ -0,0 +1,109 @@
#!/bin/bash
# Max Package Build Script
# Builds version-specific packages for Max 8 and Max 9
# Generated by Claude Sonnet 4.5
set -e # Exit on error
# Configuration
PACKAGE_NAME="tc.preset"
DIST_DIR="./dist"
MAX8_DIR="$DIST_DIR/Max 8/$PACKAGE_NAME"
MAX9_DIR="$DIST_DIR/Max 9/$PACKAGE_NAME"
INSTALL_MAX8="$HOME/Documents/Max 8/Packages/$PACKAGE_NAME"
INSTALL_MAX9="$HOME/Documents/Max 9/Packages/$PACKAGE_NAME"
echo "Building Max packages..."
# Clean and create dist directories
rm -rf "$DIST_DIR"
mkdir -p "$MAX8_DIR"
mkdir -p "$MAX9_DIR"
# Function to copy files recursively
copy_files() {
local target_dir=$1
local prefix=$2
# Find all files (not directories) in the repo
find . -type f \
-not -path "*/.*" \
-not -path "./dist/*" \
-not -name "build.sh" | while read -r file; do
# Get filename without path
local filename=$(basename "$file")
# Get relative path from repo root
local relpath="${file#./}"
local dirpath=$(dirname "$relpath")
# Determine if file should be copied to this version
if [[ $filename == max8.* ]] && [[ $prefix == "max8" ]]; then
# Remove max8. prefix and copy
local newname="${filename#max8.}"
local target="$target_dir/$dirpath/$newname"
mkdir -p "$(dirname "$target")"
cp "$file" "$target"
echo "$relpath (as $dirpath/$newname) [Max 8]"
elif [[ $filename == max9.* ]] && [[ $prefix == "max9" ]]; then
# Remove max9. prefix and copy
local newname="${filename#max9.}"
local target="$target_dir/$dirpath/$newname"
mkdir -p "$(dirname "$target")"
cp "$file" "$target"
echo "$relpath (as $dirpath/$newname) [Max 9]"
elif [[ $filename != max8.* ]] && [[ $filename != max9.* ]]; then
# Copy shared files to both versions
local target="$target_dir/$relpath"
mkdir -p "$(dirname "$target")"
cp "$file" "$target"
echo "$relpath [shared]"
fi
done
}
echo ""
echo "Building Max 8 version..."
copy_files "$MAX8_DIR" "max8"
echo ""
echo "Building Max 9 version..."
copy_files "$MAX9_DIR" "max9"
echo ""
echo "Build complete!"
echo ""
echo "Max 8 package: $MAX8_DIR"
echo "Max 9 package: $MAX9_DIR"
echo ""
# Ask to install
read -p "Install to Max Packages folders (~/Documents/Max <8|9>/Packages)? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Installing packages..."
# Create Packages directories if they don't exist
mkdir -p "$HOME/Documents/Max 8/Packages"
mkdir -p "$HOME/Documents/Max 9/Packages"
# Copy to Max 8
if [ -d "$INSTALL_MAX8" ]; then
rm -rf "$INSTALL_MAX8"
fi
cp -r "$MAX8_DIR" "$INSTALL_MAX8"
echo "✓ Installed to $INSTALL_MAX8"
# Copy to Max 9
if [ -d "$INSTALL_MAX9" ]; then
rm -rf "$INSTALL_MAX9"
fi
cp -r "$MAX9_DIR" "$INSTALL_MAX9"
echo "✓ Installed to $INSTALL_MAX9"
echo ""
echo "Installation complete!"
else
echo "Skipped installation."
fi

View File

@@ -6,7 +6,7 @@
A jsui replacement for the preset object.
</digest>
<description>
tc.preset is a jsui clone of the preset object, but loaded with more features, such as preset organization through drag and drop, display as a scrollable list, colored slots...
tc.preset is a <o>jsui</o>/<o>v8ui</o> clone of the <o>preset</o> object, but loaded with more features, such as preset organization through drag and drop, display as a scrollable list, colored slots...
Contrary to the preset object, tc.preset doesn't work alone and has to be used in conjonction with a pattrstorage object.<modification class=""></modification>
</description>

View File

@@ -0,0 +1,3 @@
max setdefinepackage tc.preset pattrstorage;
max definesubstitution tc.preset jsui @filename tc.preset;
max setdefinepackage "" "";

View File

@@ -0,0 +1,3 @@
max setdefinepackage tc.preset pattrstorage;
max define tc.preset v8ui @filename tc.preset;
max setdefinepackage "" "";

View File

@@ -1,2 +0,0 @@
max objectfile tc.preset tc.preset;
max definesubstitution tc.preset jsui @filename tc.preset;

View File

@@ -380,34 +380,32 @@ function paint_base() {
bg_width = layout == 0 ? columns * (slot_size + spacing) - spacing + 2 * margin : ui_width;
bg_height = rows * (slot_size + spacing) - spacing + 2 * margin;
mg = new MGraphics(ui_width*2, bg_height*2);
with(mg) {
set_source_rgba(background_color);
rectangle(0, 0, bg_width*2, bg_height*2);
fill();
mg.set_source_rgba(background_color);
mg.rectangle(0, 0, bg_width*2, bg_height*2);
mg.fill();
select_font_face(font_name);
set_font_size(font_size);
mg.select_font_face(font_name);
mg.set_font_size(font_size);
// All slots
for (var i = 1; i <= true_slots_count_display; i++) {
if (i != drag_slot) { //We mask the slot that is currently dragged as it is drawn at the mouse position already
if (slots[i].name != null) {
if (color_mode == 1) {
set_source_rgba(color_wheel_custom[i % color_wheel_size]);
mg.set_source_rgba(color_wheel_custom[i % color_wheel_size]);
} else if (color_mode == 2) {
set_source_rgba(color_wheel_custom[Math.abs(slots[i].color_index) % color_wheel_size]);
mg.set_source_rgba(color_wheel_custom[Math.abs(slots[i].color_index) % color_wheel_size]);
} else if (color_mode == 3) {
set_source_rgba(slots[i].color_custom);
mg.set_source_rgba(slots[i].color_custom);
} else {
set_source_rgba(stored_slot_color);
mg.set_source_rgba(stored_slot_color);
}
} else {
set_source_rgba(empty_slot_color);
mg.set_source_rgba(empty_slot_color);
}
draw_slot(i, 2, mg);
}
}
}
is_painting_base = 0;
update_umenu();
base_drawing = new Image(mg);
@@ -423,58 +421,57 @@ function paint()
onresize(cur_size[0], cur_size[1]);
} else {
// post("redraw\n");
with (mgraphics) {
select_font_face(font_name);
set_font_size(font_size);
translate(0, y_offset);
mgraphics.select_font_face(font_name);
mgraphics.set_font_size(font_size);
mgraphics.translate(0, y_offset);
// Draw the base, which includes empty and filled slots
// It is first rendered at twice the size in order to make texts look nice and cripsy on hidpi discplays
// So we need to scale it down here
scale(0.5, 0.5);
image_surface_draw(base_drawing);
scale(2, 2);
mgraphics.scale(0.5, 0.5);
mgraphics.image_surface_draw(base_drawing);
mgraphics.scale(2, 2);
set_line_width(1);
mgraphics.set_line_width(1);
// Active slot
if (is_dragging == 0 && active_slot > 0 && active_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
mgraphics.set_source_rgba(active_slot_color);
if (color_mode) {
draw_slot_bubble(slots[active_slot].left+1.5, slots[active_slot].top+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
mgraphics.set_line_width(3);
mgraphics.stroke();
} else {
draw_slot_bubble(slots[active_slot].left, slots[active_slot].top, slot_size, slot_size);
fill();
mgraphics.fill();
}
}
// Previous active slot
if (is_dragging == 0 && previous_active_slot > 0 && previous_active_slot <= slots_count_display) {
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], active_slot_color[3] * 0.5);
mgraphics.set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], active_slot_color[3] * 0.5);
if (color_mode) {
draw_slot_bubble(slots[previous_active_slot].left+1.5, slots[previous_active_slot].top+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
mgraphics.set_line_width(3);
mgraphics.stroke();
} else {
draw_slot_bubble(slots[previous_active_slot].left, slots[previous_active_slot].top, slot_size, slot_size);
fill();
mgraphics.fill();
}
}
//Hide dragged slot
if (is_dragging) {
set_source_rgba(empty_slot_color);
mgraphics.set_source_rgba(empty_slot_color);
draw_slot_bubble(slots[drag_slot].left, slots[drag_slot].top, slot_size, slot_size);
fill();
mgraphics.fill();
}
// Selected slot
if (selected_slot > 0 && selected_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
set_line_width(1);
mgraphics.set_source_rgba(active_slot_color);
mgraphics.set_line_width(1);
draw_slot_bubble(slots[selected_slot].left - 0.5, slots[selected_slot].top - 0.5, slot_size + 1, slot_size + 1);
stroke();
mgraphics.stroke();
}
// Interpolated slots
@@ -483,20 +480,20 @@ function paint()
for (var i = 1; i <= slots_count_display; i++) {
var interp = slots[i].interp;
if (interp >= 0) {
set_source_rgba(interp_slot_color);
mgraphics.set_source_rgba(interp_slot_color);
draw_slot_bubble(slots[i].left, slots[i].top, slot_size, slot_size);
stroke();
mgraphics.stroke();
draw_slot_bubble(slots[i].left, slots[i].top + slot_size * (1-interp), slot_size, slot_size * interp);
fill();
mgraphics.fill();
}
}
}
//Edited dot
if (active_slot_edited && active_slot > 0 && selected_slot <= slots_count_display) {
set_source_rgba(edited_color);
ellipse(slots[active_slot].left + 1, slots[active_slot].top + 1, slot_size/3, slot_size/3);
fill();
mgraphics.set_source_rgba(edited_color);
mgraphics.ellipse(slots[active_slot].left + 1, slots[active_slot].top + 1, slot_size/3, slot_size/3);
mgraphics.fill();
}
// Hovered slot
@@ -504,21 +501,21 @@ function paint()
if (shift_hold && last_hovered_is_preset_slot) {
if (option_hold) {
// About to delete
set_source_rgba(empty_slot_color[0], empty_slot_color[1], empty_slot_color[2], 0.8);
mgraphics.set_source_rgba(empty_slot_color[0], empty_slot_color[1], empty_slot_color[2], 0.8);
draw_slot_bubble(slots[last_hovered].left + 1, slots[last_hovered].top + 1, slot_size-2, slot_size-2);
fill();
mgraphics.fill();
} else {
// About to store
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], 0.7);
mgraphics.set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], 0.7);
draw_slot_bubble(slots[last_hovered].left + 1, slots[last_hovered].top + 1, slot_size-2, slot_size-2);
fill();
mgraphics.fill();
}
}
// Slot border
set_source_rgba(1, 1, 1, 0.8);
mgraphics.set_source_rgba(1, 1, 1, 0.8);
draw_slot_bubble(slots[last_hovered].left, slots[last_hovered].top, slot_size, slot_size);
stroke();
mgraphics.stroke();
if (layout == 0) {
//Text (slot number and name)
@@ -532,7 +529,7 @@ function paint()
} else {
text = format_slot_name(last_hovered);
}
var text_dim = text_measure(text);
var text_dim = mgraphics.text_measure(text);
// If the text is too big or a slot is being dragged, display the text on top of the next slot.
// Otherwise, it gets displayed on the hovered slot.
@@ -551,14 +548,14 @@ function paint()
var txt_pos_y = bg_txt_pos_y + (bg_txt_dim_h + text_dim[1]) / 2 - text_dim[1]*0.18;
// Bubble background
set_source_rgba(text_bg_color);
rectangle_rounded(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, 4, 4);
fill();
mgraphics.set_source_rgba(text_bg_color);
mgraphics.rectangle_rounded(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, 4, 4);
mgraphics.fill();
// Buble text
set_source_rgba(text_color);
move_to(txt_pos_x, txt_pos_y);
show_text(text.toString());
mgraphics.set_source_rgba(text_color);
mgraphics.move_to(txt_pos_x, txt_pos_y);
mgraphics.show_text(text.toString());
}
}
@@ -566,43 +563,40 @@ function paint()
// Drag slot
if (is_dragging) {
if (layout == 0) {
translate(last_x, last_y );
rotate(0.15);
scale(1.1, 1.1);
mgraphics.translate(last_x, last_y );
mgraphics.rotate(0.15);
mgraphics.scale(1.1, 1.1);
// Slot shadow
set_source_rgba(0, 0, 0, 0.15);
mgraphics.set_source_rgba(0, 0, 0, 0.15);
for (var i = 0; i<4; i++) {
draw_slot_bubble( i*0.4 + 1-slot_size/2, i*0.4 + 1-slot_size/2, slot_size + i*0.8, slot_size+i*0.8);
fill();
mgraphics.fill();
}
draw_slot_bubble( 2-slot_size/2, 2-slot_size/2, slot_size, slot_size);
fill();
mgraphics.fill();
//Flying slot
set_source_rgba(active_slot_color);
mgraphics.set_source_rgba(active_slot_color);
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
mgraphics.fill();
} else {
translate(last_x, last_y );
mgraphics.translate(last_x, last_y );
// rotate(0.15);
set_source_rgba(active_slot_color);
mgraphics.set_source_rgba(active_slot_color);
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
mgraphics.fill();
// slot name
var text = format_slot_name(drag_slot);
var bg_txt_pos_x = slot_size/2+ spacing;
var bg_txt_pos_y = -slot_size/2;
var bg_txt_dim_w = ui_width - (2*margin + slot_size + spacing);
var bg_txt_dim_h = slot_size;
set_source_rgba(stored_slot_color);
mgraphics.set_source_rgba(stored_slot_color);
draw_text_bubble(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, text);
}
}
}
}
}
@@ -1725,8 +1719,10 @@ function get_prect(prect) {
get_prect.local = 1;
function notifydeleted(){
if (poll_edited_task.valid) {
poll_edited_task.freepeer();
}
}
// ATTRIBUTES DECLARATION
// If loaded in JSUI, only the first 4 arguments passed in declareattribute() will be used (no attribute styling). V8UI will also use the latest object argument.