Message 1 of 2
Palette not showing and data problem
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi y'all. I've read through a ton of palette and data transit problems and I can't seem to get this right. I've messed with it a variety of ways.
Problem #1. I can get the palette to show, but when I try to send data, it doesn't seem to fire the notify handler. That only works if I don't have a stop(context) method
Problem #2. If I add the stop(context) method, the palette doesn't show. Via logging I can tell it's just very quickly running the palette and destroying it.
Would love any ideas for one or the other.
I think these are the key pieces of code.
Palette HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Jitter size configuration</title>
<script>
function logDebugMessage(message) {
const debugDiv = document.getElementById('debugMessages');
debugDiv.innerHTML += `<p>${message}</p>`;
}
function sendValues() {
const minSize = document.getElementById('minSize').value;
const maxSize = document.getElementById('maxSize').value;
var args = {
minSize : minSize,
maxSize : maxSize
};
logDebugMessage(`Sending data: ${JSON.stringify(args)}`);
adsk.fusionSendData("send", JSON.stringify(args));
logDebugMessage("Data sent");
// adsk.fusionSendData("send", JSON.stringify(args)).then((result) =>
// document.getElementById('returnValue').innerHTML = `Result: ${result}`
// );
}
window.fusionJavaScriptHandler = {handle: function(action, data){
try {
if (action == 'send') {
document.getElementById('p1').innerHTML = data;
}
else if (action == 'debugger') {
debugger;
}
else {
return 'Unexpected command type: ' + action;
}
} catch (e) {
console.log(e);
console.log('exception caught with command: ' + action + ', data: ' + data);
}
return 'OK';
}};
</script>
</head>
<body>
<p id="xxx">Active Document Name</p>
<label for="minSize">Minimum cut size (cm):</label>
<input type="number" id="minSize" name="minSize" min="1" max="50" value="10" step="1">
<br />
<label for="maxSize">Maximum cut size (cm):</label>
<input type="number" id="maxSize" name="maxSize" min="1" max="100" value="20" step="1">
<br />
<button onclick="sendValues()">Submit</button>
<br />
<div id="returnValue" style="margin-top: 20px; color: red; font-size: small;">
</div>
<br />
<div id="p1" style="margin-top: 20px; color: green; font-size: small;">
</div>
<br />
<div id="debugMessages" style="margin-top: 20px; color: blue; font-size: small;">
<strong>Debug Messages:</strong>
</div>
</body>
</html>
Python script:
class JitterProcessor:
def __init__(self, ui):
...
self.ui = ui
self.palette = None
self.handlers = []
...
def getUserInputSize(self):
log_to_file("guis 1")
# Set up and display the web palette
htmlFilePath = 'file:///' + os.path.join(os.path.dirname(__file__), 'EdgeJitterPalette_sizeInput.html').replace('\\', '/')
self.palette = self.ui.palettes.itemById('cutSizePalette')
if not self.palette:
self.palette = self.ui.palettes.add('cutSizePalette', 'Jitter size configuration', htmlFilePath, True, True, True, 300, 150)
# Attach the event handler
log_to_file("guis 2a")
handler = self.UserInputEventHandler() #self.callbackFromSizeInput)
self.palette.incomingFromHTML.add(handler)
self.handlers.append(handler) # Keep a reference to avoid garbage collection
# Add handler to CloseEvent of the palette.
onClosed = self.UserInputCloseEventHandler()
self.palette.closed.add(onClosed)
self.handlers.append(onClosed)
else:
log_to_file("guis 2b")
self.palette.isVisible = True
...
def callbackFromSizeInput(self, minSize, maxSize):
if minSize is None or maxSize is None:
return # Handle error or invalid input
self.palette.isVisible = False
self.minSize = minSize
self.maxSize = maxSize
self.recursiveCut(self.selectedLine, self.startPoint, self.endPoint, self.dominantAxis,
self.minSize, self.maxSize)
def run(self):
...
log_to_file("getUserInputSize")
self.getUserInputSize()
def stop(self):
try:
# Delete the palette created by this add-in.
palette = self.ui.palettes.itemById('cutSizePalette')
if palette:
palette.deleteMe()
except:
if self.ui:
self.ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# ----- INNER CLASSES -----
class UserInputEventHandler(adsk.core.HTMLEventHandler):
def __init__(self):
log_to_file("eventHandler init")
super().__init__()
# self.callback = callback
def notify(self, args):
log_to_file("notify1")
try:
# This method will be called when an HTML event is fired
htmlArgs = adsk.core.HTMLEventArgs.cast(args)
data = json.loads(htmlArgs.data)
log_to_file("notify2: Data received:", data)
# Expected data format: 'minSize=10&maxSize=20'
minSize, maxSize = map(float, [x.split('=')[1] for x in data.split('&')])
# if minSize <= 0 or maxSize >= 100 or minSize > maxSize:
# ui = adsk.core.Application.get().userInterface
# ui.messageBox("Invalid input sizes. Ensure min is less than max and within the valid range.")
# else:
# self.callback(minSize, maxSize)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
return "hi"
# Event handler for the palette close event.
class UserInputCloseEventHandler(adsk.core.UserInterfaceGeneralEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
log_to_file("uic1")
try:
_ui.messageBox('Close button is clicked.')
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
## EVERYONE LOVES THE END OF CLASS
# This is Fusion 360's main method
def run(context):
log_to_file("run")
global _ui, _processor
_ui = adsk.core.Application.get().userInterface
_processor = JitterProcessor(_ui)
_processor.run()
def stop(context):
log_to_file("stop")
_processor.stop()
def log_to_file(message):
# Define the path for the log file
log_file_path = os.path.join(os.path.expanduser("~"), "fusion_debug_log.txt")
timestamp = datetime.now().strftime("%H:%M:%S")
# Write the message to the file
with open(log_file_path, "a") as log_file:
log_file.write(f"[{timestamp}] {message}\n")
Thank you!