@@ -248,7 +248,7 @@ function release_sceneitem()
248
248
sceneitem = nil
249
249
end
250
250
251
- if source ~= nil then
251
+ if source ~= nil then
252
252
obs .obs_source_release (source )
253
253
source = nil
254
254
end
@@ -267,36 +267,69 @@ function refresh_sceneitem(find_newest)
267
267
release_sceneitem ()
268
268
269
269
-- Get a matching source we can use for zooming in the current scene
270
+ log (" Finding sceneitem for Zoom Source '" .. source_name .. " '" )
270
271
if source_name ~= nil then
271
272
source = obs .obs_get_source_by_name (source_name )
272
273
if source ~= nil then
273
274
-- Get the source size, for some reason this works during load but the sceneitem source doesn't
274
275
source_raw .width = obs .obs_source_get_width (source )
275
276
source_raw .height = obs .obs_source_get_height (source )
276
277
278
+ -- Get the current scene
277
279
local scene_source = obs .obs_frontend_get_current_scene ()
278
280
if scene_source ~= nil then
279
- local scene = obs .obs_scene_from_source (scene_source )
280
- if scene ~= nil then
281
- sceneitem = obs .obs_scene_sceneitem_from_source (scene , source )
282
-
283
- local x = obs .obs_scene_find_source (scene , source_name )
284
-
285
- if not x then
286
- log (" Warning: Source not part of the current scene" )
287
- obs .obs_source_release (scene_source )
288
- obs .obs_sceneitem_release (sceneitem )
289
- obs .obs_source_release (source )
281
+ local function find_scene_item_by_name (root_scene )
282
+ local queue = {}
283
+ table.insert (queue , root_scene )
284
+
285
+ while # queue > 0 do
286
+ local s = table.remove (queue , 1 )
287
+ log (" Looking in scene '" .. obs .obs_source_get_name (obs .obs_scene_get_source (s )) .. " '" )
288
+
289
+ -- Check if the current scene has the target scene item
290
+ local found = obs .obs_scene_find_source (s , source_name )
291
+ if found ~= nil then
292
+ log (" Found sceneitem" )
293
+ obs .obs_sceneitem_addref (found )
294
+ return found
295
+ end
290
296
291
- sceneitem = nil
292
- source = nil
293
- return
297
+ -- If the current scene has nested scenes, enqueue them for later examination
298
+ local all_items = obs .obs_scene_enum_items (s )
299
+ if all_items then
300
+ for _ , item in pairs (all_items ) do
301
+ local nested = obs .obs_sceneitem_get_source (item )
302
+ if nested ~= nil and obs .obs_source_is_scene (nested ) then
303
+ local nested_scene = obs .obs_scene_from_source (nested )
304
+ table.insert (queue , nested_scene )
305
+ end
306
+ end
307
+ obs .sceneitem_list_release (all_items )
308
+ end
294
309
end
295
- monitor_info = get_monitor_info (source )
310
+
311
+ return nil
296
312
end
297
313
314
+ -- Find the sceneitem for the source_name by looking through all the items
315
+ -- We start at the current scene and use a BFS to look into any nested scenes
316
+ local current = obs .obs_scene_from_source (scene_source )
317
+ sceneitem = find_scene_item_by_name (current )
318
+
298
319
obs .obs_source_release (scene_source )
299
320
end
321
+
322
+ if not sceneitem then
323
+ log (" Warning: Source not part of the current scene hierarchy" )
324
+ obs .obs_sceneitem_release (sceneitem )
325
+ obs .obs_source_release (source )
326
+
327
+ sceneitem = nil
328
+ source = nil
329
+ return
330
+ end
331
+
332
+ monitor_info = get_monitor_info (source )
300
333
end
301
334
end
302
335
end
@@ -333,11 +366,13 @@ function refresh_sceneitem(find_newest)
333
366
log (" Source size determined as " .. source_width .. " , " .. source_height )
334
367
if source_width == 0 or source_height == 0 then
335
368
if monitor_info and monitor_info .height > 0 and monitor_info .height > 0 then
336
- log (" Warning: Something went wrong determining source size, defaulting to monitor size " .. monitor_info .width .. " , " .. monitor_info .height )
369
+ log (" Warning: Something went wrong determining source size, defaulting to monitor size " ..
370
+ monitor_info .width .. " , " .. monitor_info .height )
337
371
source_width = monitor_info .width
338
372
source_height = monitor_info .height
339
373
else
340
- log (" Error: Something went wrong determining source size, try using the 'Set manual monitor position' option and adding override values" )
374
+ log (" Error: Something went wrong determining source size," ..
375
+ " try using the 'Set manual monitor position' option and adding override values" )
341
376
end
342
377
end
343
378
@@ -508,11 +543,10 @@ function get_target_position(zoom_info)
508
543
}
509
544
510
545
-- Keep the zoom in bounds of the source so that we never show something outside that user is trying to hide with existing crop settings
511
- crop .x = clamp (0 , (zoom_info .source_size .width - new_size .width ), crop .x )
512
- crop .y = clamp (0 , (zoom_info .source_size .height - new_size .height ), crop .y )
513
-
546
+ crop .x = math.floor (clamp (0 , (zoom_info .source_size .width - new_size .width ), crop .x ))
547
+ crop .y = math.floor (clamp (0 , (zoom_info .source_size .height - new_size .height ), crop .y ))
514
548
515
- return { crop = crop , raw_center = mouse , clamped_center = { x = crop .x + crop .w * 0.5 , y = crop .y + crop .h * 0.5 } }
549
+ return { crop = crop , raw_center = mouse , clamped_center = { x = math.floor ( crop .x + crop .w * 0.5 ) , y = math.floor ( crop .y + crop .h * 0.5 ) } }
516
550
end
517
551
518
552
function on_toggle_follow (pressed )
@@ -542,6 +576,10 @@ function on_toggle_zoom(pressed)
542
576
zoom_time = 0
543
577
locked_center = nil
544
578
zoom_target = { crop = crop_filter_info_orig , c = sceneitem_crop_orig }
579
+ if is_following_mouse then
580
+ is_following_mouse = false
581
+ log (" Tracking mouse is off (due to zoom out)" )
582
+ end
545
583
else
546
584
log (" Zooming in" )
547
585
-- To zoom in, we get a new target based on where the mouse was when zoom was clicked
@@ -593,12 +631,12 @@ function on_timer()
593
631
end
594
632
595
633
if not skip_frame then
596
- -- If we have a locked_center it means we are currently in a locked zone and
634
+ -- If we have a locked_center it means we are currently in a locked zone and
597
635
-- shouldn't track the mouse until it moves out of the area
598
636
if locked_center ~= nil then
599
637
local diff = {
600
- x = math.abs ( zoom_target .raw_center .x - locked_center .x ) ,
601
- y = math.abs ( zoom_target .raw_center .y - locked_center .y )
638
+ x = zoom_target .raw_center .x - locked_center .x ,
639
+ y = zoom_target .raw_center .y - locked_center .y
602
640
}
603
641
604
642
local track = {
0 commit comments