window.rs

   1use crate::{
   2    elements::AnyRootElement,
   3    geometry::rect::RectF,
   4    json::{self, ToJson},
   5    keymap_matcher::{Keystroke, MatchResult},
   6    platform::{
   7        self, Appearance, CursorStyle, Event, KeyDownEvent, KeyUpEvent, ModifiersChangedEvent,
   8        MouseButton, MouseMovedEvent, PromptLevel, WindowBounds,
   9    },
  10    scene::{
  11        CursorRegion, MouseClick, MouseDown, MouseDownOut, MouseDrag, MouseEvent, MouseHover,
  12        MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, Scene,
  13    },
  14    text_layout::TextLayoutCache,
  15    util::post_inc,
  16    AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, Drawable, Entity, ModelContext,
  17    ModelHandle, MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams, SceneBuilder,
  18    UpdateModel, UpdateView, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakViewHandle,
  19    WindowInvalidation,
  20};
  21use anyhow::bail;
  22use collections::{HashMap, HashSet};
  23use pathfinder_geometry::vector::{vec2f, Vector2F};
  24use postage::oneshot;
  25use serde_json::json;
  26use smallvec::SmallVec;
  27use sqlez::{
  28    bindable::{Bind, Column, StaticColumnCount},
  29    statement::Statement,
  30};
  31use std::ops::{Deref, DerefMut, Range};
  32use util::ResultExt;
  33use uuid::Uuid;
  34
  35use super::Reference;
  36
  37pub struct Window {
  38    pub(crate) root_view: Option<AnyViewHandle>,
  39    pub(crate) focused_view_id: Option<usize>,
  40    pub(crate) is_active: bool,
  41    pub(crate) is_fullscreen: bool,
  42    pub(crate) invalidation: Option<WindowInvalidation>,
  43    pub(crate) platform_window: Box<dyn platform::Window>,
  44    pub(crate) rendered_views: HashMap<usize, Box<dyn AnyRootElement>>,
  45    titlebar_height: f32,
  46    appearance: Appearance,
  47    cursor_regions: Vec<CursorRegion>,
  48    mouse_regions: Vec<(MouseRegion, usize)>,
  49    last_mouse_moved_event: Option<Event>,
  50    pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
  51    pub(crate) clicked_region_ids: HashSet<MouseRegionId>,
  52    pub(crate) clicked_button: Option<MouseButton>,
  53    mouse_position: Vector2F,
  54    text_layout_cache: TextLayoutCache,
  55}
  56
  57impl Window {
  58    pub fn new<V, F>(
  59        window_id: usize,
  60        platform_window: Box<dyn platform::Window>,
  61        cx: &mut AppContext,
  62        build_view: F,
  63    ) -> Self
  64    where
  65        F: FnOnce(&mut ViewContext<V>) -> V,
  66        V: View,
  67    {
  68        let titlebar_height = platform_window.titlebar_height();
  69        let appearance = platform_window.appearance();
  70        let mut window = Self {
  71            root_view: None,
  72            focused_view_id: None,
  73            is_active: false,
  74            invalidation: None,
  75            is_fullscreen: false,
  76            platform_window,
  77            rendered_views: cx.render_views(window_id, titlebar_height, appearance),
  78            cursor_regions: Default::default(),
  79            mouse_regions: Default::default(),
  80            text_layout_cache: TextLayoutCache::new(cx.font_system.clone()),
  81            last_mouse_moved_event: None,
  82            hovered_region_ids: Default::default(),
  83            clicked_region_ids: Default::default(),
  84            clicked_button: None,
  85            mouse_position: vec2f(0., 0.),
  86            titlebar_height,
  87            appearance,
  88        };
  89
  90        let mut window_context = WindowContext::mutable(cx, &mut window, window_id);
  91        let root_view = window_context
  92            .build_and_insert_view(ParentId::Root, |cx| Some(build_view(cx)))
  93            .unwrap();
  94        window.focused_view_id = Some(root_view.id());
  95        window.root_view = Some(root_view.into_any());
  96        window
  97    }
  98
  99    pub fn root_view(&self) -> &AnyViewHandle {
 100        &self
 101            .root_view
 102            .as_ref()
 103            .expect("root_view called during window construction")
 104    }
 105}
 106
 107pub struct WindowContext<'a: 'b, 'b> {
 108    pub(crate) app_context: Reference<'a, AppContext>,
 109    pub(crate) window: Reference<'b, Window>,
 110    pub(crate) window_id: usize,
 111    pub(crate) refreshing: bool,
 112}
 113
 114impl Deref for WindowContext<'_, '_> {
 115    type Target = AppContext;
 116
 117    fn deref(&self) -> &Self::Target {
 118        &self.app_context
 119    }
 120}
 121
 122impl DerefMut for WindowContext<'_, '_> {
 123    fn deref_mut(&mut self) -> &mut Self::Target {
 124        &mut self.app_context
 125    }
 126}
 127
 128impl UpdateModel for WindowContext<'_, '_> {
 129    fn update_model<T: Entity, R>(
 130        &mut self,
 131        handle: &ModelHandle<T>,
 132        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> R,
 133    ) -> R {
 134        self.app_context.update_model(handle, update)
 135    }
 136}
 137
 138impl ReadView for WindowContext<'_, '_> {
 139    fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
 140        self.app_context.read_view(handle)
 141    }
 142}
 143
 144impl UpdateView for WindowContext<'_, '_> {
 145    fn update_view<T, S>(
 146        &mut self,
 147        handle: &ViewHandle<T>,
 148        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 149    ) -> S
 150    where
 151        T: View,
 152    {
 153        self.app_context.update_view(handle, update)
 154    }
 155}
 156
 157impl UpgradeViewHandle for WindowContext<'_, '_> {
 158    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
 159        self.app_context.upgrade_view_handle(handle)
 160    }
 161
 162    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
 163        self.app_context.upgrade_any_view_handle(handle)
 164    }
 165}
 166
 167impl<'a: 'b, 'b> WindowContext<'a, 'b> {
 168    pub fn mutable(
 169        app_context: &'a mut AppContext,
 170        window: &'b mut Window,
 171        window_id: usize,
 172    ) -> Self {
 173        Self {
 174            app_context: Reference::Mutable(app_context),
 175            window: Reference::Mutable(window),
 176            window_id,
 177            refreshing: false,
 178        }
 179    }
 180
 181    pub fn immutable(app_context: &'a AppContext, window: &'b Window, window_id: usize) -> Self {
 182        Self {
 183            app_context: Reference::Immutable(app_context),
 184            window: Reference::Immutable(window),
 185            window_id,
 186            refreshing: false,
 187        }
 188    }
 189
 190    pub fn window_id(&self) -> usize {
 191        self.window_id
 192    }
 193
 194    pub fn app_context(&mut self) -> &mut AppContext {
 195        &mut self.app_context
 196    }
 197
 198    pub fn root_view(&self) -> &AnyViewHandle {
 199        self.window.root_view()
 200    }
 201
 202    pub fn window_size(&self) -> Vector2F {
 203        self.window.platform_window.content_size()
 204    }
 205
 206    pub fn text_layout_cache(&self) -> &TextLayoutCache {
 207        &self.window.text_layout_cache
 208    }
 209
 210    pub(crate) fn update_any_view<F, T>(&mut self, view_id: usize, f: F) -> Option<T>
 211    where
 212        F: FnOnce(&mut dyn AnyView, &mut Self) -> T,
 213    {
 214        let window_id = self.window_id;
 215        let mut view = self.views.remove(&(window_id, view_id))?;
 216        let result = f(view.as_mut(), self);
 217        self.views.insert((window_id, view_id), view);
 218        Some(result)
 219    }
 220
 221    pub fn dispatch_keystroke(&mut self, keystroke: &Keystroke) -> bool {
 222        let window_id = self.window_id;
 223        if let Some(focused_view_id) = self.focused_view_id() {
 224            let dispatch_path = self
 225                .ancestors(window_id, focused_view_id)
 226                .filter_map(|view_id| {
 227                    self.views
 228                        .get(&(window_id, view_id))
 229                        .map(|view| (view_id, view.keymap_context(self)))
 230                })
 231                .collect();
 232
 233            let match_result = self
 234                .keystroke_matcher
 235                .push_keystroke(keystroke.clone(), dispatch_path);
 236            let mut handled_by = None;
 237
 238            let keystroke_handled = match &match_result {
 239                MatchResult::None => false,
 240                MatchResult::Pending => true,
 241                MatchResult::Matches(matches) => {
 242                    for (view_id, action) in matches {
 243                        if self.handle_dispatch_action_from_effect(
 244                            window_id,
 245                            Some(*view_id),
 246                            action.as_ref(),
 247                        ) {
 248                            self.keystroke_matcher.clear_pending();
 249                            handled_by = Some(action.boxed_clone());
 250                            break;
 251                        }
 252                    }
 253                    handled_by.is_some()
 254                }
 255            };
 256
 257            self.keystroke(
 258                window_id,
 259                keystroke.clone(),
 260                handled_by,
 261                match_result.clone(),
 262            );
 263            keystroke_handled
 264        } else {
 265            self.keystroke(window_id, keystroke.clone(), None, MatchResult::None);
 266            false
 267        }
 268    }
 269
 270    pub fn dispatch_event(&mut self, event: Event, event_reused: bool) -> bool {
 271        let mut mouse_events = SmallVec::<[_; 2]>::new();
 272        let mut notified_views: HashSet<usize> = Default::default();
 273        let window_id = self.window_id;
 274
 275        // 1. Handle platform event. Keyboard events get dispatched immediately, while mouse events
 276        //    get mapped into the mouse-specific MouseEvent type.
 277        //  -> These are usually small: [Mouse Down] or [Mouse up, Click] or [Mouse Moved, Mouse Dragged?]
 278        //  -> Also updates mouse-related state
 279        match &event {
 280            Event::KeyDown(e) => return self.dispatch_key_down(window_id, e),
 281
 282            Event::KeyUp(e) => return self.dispatch_key_up(window_id, e),
 283
 284            Event::ModifiersChanged(e) => return self.dispatch_modifiers_changed(window_id, e),
 285
 286            Event::MouseDown(e) => {
 287                // Click events are weird because they can be fired after a drag event.
 288                // MDN says that browsers handle this by starting from 'the most
 289                // specific ancestor element that contained both [positions]'
 290                // So we need to store the overlapping regions on mouse down.
 291
 292                // If there is already clicked_button stored, don't replace it.
 293                if self.window.clicked_button.is_none() {
 294                    self.window.clicked_region_ids = self
 295                        .window
 296                        .mouse_regions
 297                        .iter()
 298                        .filter_map(|(region, _)| {
 299                            if region.bounds.contains_point(e.position) {
 300                                Some(region.id())
 301                            } else {
 302                                None
 303                            }
 304                        })
 305                        .collect();
 306
 307                    self.window.clicked_button = Some(e.button);
 308                }
 309
 310                mouse_events.push(MouseEvent::Down(MouseDown {
 311                    region: Default::default(),
 312                    platform_event: e.clone(),
 313                }));
 314                mouse_events.push(MouseEvent::DownOut(MouseDownOut {
 315                    region: Default::default(),
 316                    platform_event: e.clone(),
 317                }));
 318            }
 319
 320            Event::MouseUp(e) => {
 321                // NOTE: The order of event pushes is important! MouseUp events MUST be fired
 322                // before click events, and so the MouseUp events need to be pushed before
 323                // MouseClick events.
 324                mouse_events.push(MouseEvent::Up(MouseUp {
 325                    region: Default::default(),
 326                    platform_event: e.clone(),
 327                }));
 328                mouse_events.push(MouseEvent::UpOut(MouseUpOut {
 329                    region: Default::default(),
 330                    platform_event: e.clone(),
 331                }));
 332                mouse_events.push(MouseEvent::Click(MouseClick {
 333                    region: Default::default(),
 334                    platform_event: e.clone(),
 335                }));
 336            }
 337
 338            Event::MouseMoved(
 339                e @ MouseMovedEvent {
 340                    position,
 341                    pressed_button,
 342                    ..
 343                },
 344            ) => {
 345                let mut style_to_assign = CursorStyle::Arrow;
 346                for region in self.window.cursor_regions.iter().rev() {
 347                    if region.bounds.contains_point(*position) {
 348                        style_to_assign = region.style;
 349                        break;
 350                    }
 351                }
 352
 353                if self
 354                    .window
 355                    .platform_window
 356                    .is_topmost_for_position(*position)
 357                {
 358                    self.platform().set_cursor_style(style_to_assign);
 359                }
 360
 361                if !event_reused {
 362                    if pressed_button.is_some() {
 363                        mouse_events.push(MouseEvent::Drag(MouseDrag {
 364                            region: Default::default(),
 365                            prev_mouse_position: self.window.mouse_position,
 366                            platform_event: e.clone(),
 367                        }));
 368                    } else if let Some(clicked_button) = self.window.clicked_button {
 369                        // Mouse up event happened outside the current window. Simulate mouse up button event
 370                        let button_event = e.to_button_event(clicked_button);
 371                        mouse_events.push(MouseEvent::Up(MouseUp {
 372                            region: Default::default(),
 373                            platform_event: button_event.clone(),
 374                        }));
 375                        mouse_events.push(MouseEvent::UpOut(MouseUpOut {
 376                            region: Default::default(),
 377                            platform_event: button_event.clone(),
 378                        }));
 379                        mouse_events.push(MouseEvent::Click(MouseClick {
 380                            region: Default::default(),
 381                            platform_event: button_event.clone(),
 382                        }));
 383                    }
 384
 385                    mouse_events.push(MouseEvent::Move(MouseMove {
 386                        region: Default::default(),
 387                        platform_event: e.clone(),
 388                    }));
 389                }
 390
 391                mouse_events.push(MouseEvent::Hover(MouseHover {
 392                    region: Default::default(),
 393                    platform_event: e.clone(),
 394                    started: false,
 395                }));
 396                mouse_events.push(MouseEvent::MoveOut(MouseMoveOut {
 397                    region: Default::default(),
 398                }));
 399
 400                self.window.last_mouse_moved_event = Some(event.clone());
 401            }
 402
 403            Event::MouseExited(event) => {
 404                // When the platform sends a MouseExited event, synthesize
 405                // a MouseMoved event whose position is outside the window's
 406                // bounds so that hover and cursor state can be updated.
 407                return self.dispatch_event(
 408                    Event::MouseMoved(MouseMovedEvent {
 409                        position: event.position,
 410                        pressed_button: event.pressed_button,
 411                        modifiers: event.modifiers,
 412                    }),
 413                    event_reused,
 414                );
 415            }
 416
 417            Event::ScrollWheel(e) => mouse_events.push(MouseEvent::ScrollWheel(MouseScrollWheel {
 418                region: Default::default(),
 419                platform_event: e.clone(),
 420            })),
 421        }
 422
 423        if let Some(position) = event.position() {
 424            self.window.mouse_position = position;
 425        }
 426
 427        // 2. Dispatch mouse events on regions
 428        let mut any_event_handled = false;
 429        for mut mouse_event in mouse_events {
 430            let mut valid_regions = Vec::new();
 431
 432            // GPUI elements are arranged by z_index but sibling elements can register overlapping
 433            // mouse regions. As such, hover events are only fired on overlapping elements which
 434            // are at the same z-index as the topmost element which overlaps with the mouse.
 435            match &mouse_event {
 436                MouseEvent::Hover(_) => {
 437                    let mut highest_z_index = None;
 438                    let mouse_position = self.window.mouse_position.clone();
 439                    let window = &mut *self.window;
 440                    for (region, z_index) in window.mouse_regions.iter().rev() {
 441                        // Allow mouse regions to appear transparent to hovers
 442                        if !region.hoverable {
 443                            continue;
 444                        }
 445
 446                        let contains_mouse = region.bounds.contains_point(mouse_position);
 447
 448                        if contains_mouse && highest_z_index.is_none() {
 449                            highest_z_index = Some(z_index);
 450                        }
 451
 452                        // This unwrap relies on short circuiting boolean expressions
 453                        // The right side of the && is only executed when contains_mouse
 454                        // is true, and we know above that when contains_mouse is true
 455                        // highest_z_index is set.
 456                        if contains_mouse && z_index == highest_z_index.unwrap() {
 457                            //Ensure that hover entrance events aren't sent twice
 458                            if window.hovered_region_ids.insert(region.id()) {
 459                                valid_regions.push(region.clone());
 460                                if region.notify_on_hover {
 461                                    notified_views.insert(region.id().view_id());
 462                                }
 463                            }
 464                        } else {
 465                            // Ensure that hover exit events aren't sent twice
 466                            if window.hovered_region_ids.remove(&region.id()) {
 467                                valid_regions.push(region.clone());
 468                                if region.notify_on_hover {
 469                                    notified_views.insert(region.id().view_id());
 470                                }
 471                            }
 472                        }
 473                    }
 474                }
 475
 476                MouseEvent::Down(_) | MouseEvent::Up(_) => {
 477                    for (region, _) in self.window.mouse_regions.iter().rev() {
 478                        if region.bounds.contains_point(self.window.mouse_position) {
 479                            valid_regions.push(region.clone());
 480                            if region.notify_on_click {
 481                                notified_views.insert(region.id().view_id());
 482                            }
 483                        }
 484                    }
 485                }
 486
 487                MouseEvent::Click(e) => {
 488                    // Only raise click events if the released button is the same as the one stored
 489                    if self
 490                        .window
 491                        .clicked_button
 492                        .map(|clicked_button| clicked_button == e.button)
 493                        .unwrap_or(false)
 494                    {
 495                        // Clear clicked regions and clicked button
 496                        let clicked_region_ids = std::mem::replace(
 497                            &mut self.window.clicked_region_ids,
 498                            Default::default(),
 499                        );
 500                        self.window.clicked_button = None;
 501
 502                        // Find regions which still overlap with the mouse since the last MouseDown happened
 503                        for (mouse_region, _) in self.window.mouse_regions.iter().rev() {
 504                            if clicked_region_ids.contains(&mouse_region.id()) {
 505                                if mouse_region
 506                                    .bounds
 507                                    .contains_point(self.window.mouse_position)
 508                                {
 509                                    valid_regions.push(mouse_region.clone());
 510                                }
 511                            }
 512                        }
 513                    }
 514                }
 515
 516                MouseEvent::Drag(_) => {
 517                    for (mouse_region, _) in self.window.mouse_regions.iter().rev() {
 518                        if self.window.clicked_region_ids.contains(&mouse_region.id()) {
 519                            valid_regions.push(mouse_region.clone());
 520                        }
 521                    }
 522                }
 523
 524                MouseEvent::MoveOut(_) | MouseEvent::UpOut(_) | MouseEvent::DownOut(_) => {
 525                    for (mouse_region, _) in self.window.mouse_regions.iter().rev() {
 526                        // NOT contains
 527                        if !mouse_region
 528                            .bounds
 529                            .contains_point(self.window.mouse_position)
 530                        {
 531                            valid_regions.push(mouse_region.clone());
 532                        }
 533                    }
 534                }
 535
 536                _ => {
 537                    for (mouse_region, _) in self.window.mouse_regions.iter().rev() {
 538                        // Contains
 539                        if mouse_region
 540                            .bounds
 541                            .contains_point(self.window.mouse_position)
 542                        {
 543                            valid_regions.push(mouse_region.clone());
 544                        }
 545                    }
 546                }
 547            }
 548
 549            //3. Fire region events
 550            let hovered_region_ids = self.window.hovered_region_ids.clone();
 551            for valid_region in valid_regions.into_iter() {
 552                let mut handled = false;
 553                mouse_event.set_region(valid_region.bounds);
 554                if let MouseEvent::Hover(e) = &mut mouse_event {
 555                    e.started = hovered_region_ids.contains(&valid_region.id())
 556                }
 557                // Handle Down events if the MouseRegion has a Click or Drag handler. This makes the api more intuitive as you would
 558                // not expect a MouseRegion to be transparent to Down events if it also has a Click handler.
 559                // This behavior can be overridden by adding a Down handler
 560                if let MouseEvent::Down(e) = &mouse_event {
 561                    let has_click = valid_region
 562                        .handlers
 563                        .contains(MouseEvent::click_disc(), Some(e.button));
 564                    let has_drag = valid_region
 565                        .handlers
 566                        .contains(MouseEvent::drag_disc(), Some(e.button));
 567                    let has_down = valid_region
 568                        .handlers
 569                        .contains(MouseEvent::down_disc(), Some(e.button));
 570                    if !has_down && (has_click || has_drag) {
 571                        handled = true;
 572                    }
 573                }
 574
 575                // `event_consumed` should only be true if there are any handlers for this event.
 576                let mut event_consumed = handled;
 577                if let Some(callbacks) = valid_region.handlers.get(&mouse_event.handler_key()) {
 578                    for callback in callbacks {
 579                        handled = true;
 580                        let view_id = valid_region.id().view_id();
 581                        self.update_any_view(view_id, |view, cx| {
 582                            handled = callback(mouse_event.clone(), view.as_any_mut(), cx, view_id);
 583                        });
 584                        event_consumed |= handled;
 585                        any_event_handled |= handled;
 586                    }
 587                }
 588
 589                any_event_handled |= handled;
 590
 591                // For bubbling events, if the event was handled, don't continue dispatching.
 592                // This only makes sense for local events which return false from is_capturable.
 593                if event_consumed && mouse_event.is_capturable() {
 594                    break;
 595                }
 596            }
 597        }
 598
 599        for view_id in notified_views {
 600            self.notify_view(window_id, view_id);
 601        }
 602
 603        any_event_handled
 604    }
 605
 606    pub fn dispatch_key_down(&mut self, window_id: usize, event: &KeyDownEvent) -> bool {
 607        if let Some(focused_view_id) = self.window.focused_view_id {
 608            for view_id in self
 609                .ancestors(window_id, focused_view_id)
 610                .collect::<Vec<_>>()
 611            {
 612                if let Some(mut view) = self.views.remove(&(window_id, view_id)) {
 613                    let handled = view.key_down(event, self, view_id);
 614                    self.views.insert((window_id, view_id), view);
 615                    if handled {
 616                        return true;
 617                    }
 618                } else {
 619                    log::error!("view {} does not exist", view_id)
 620                }
 621            }
 622        }
 623
 624        false
 625    }
 626
 627    pub fn dispatch_key_up(&mut self, window_id: usize, event: &KeyUpEvent) -> bool {
 628        if let Some(focused_view_id) = self.window.focused_view_id {
 629            for view_id in self
 630                .ancestors(window_id, focused_view_id)
 631                .collect::<Vec<_>>()
 632            {
 633                if let Some(mut view) = self.views.remove(&(window_id, view_id)) {
 634                    let handled = view.key_up(event, self, view_id);
 635                    self.views.insert((window_id, view_id), view);
 636                    if handled {
 637                        return true;
 638                    }
 639                } else {
 640                    log::error!("view {} does not exist", view_id)
 641                }
 642            }
 643        }
 644
 645        false
 646    }
 647
 648    pub fn dispatch_modifiers_changed(
 649        &mut self,
 650        window_id: usize,
 651        event: &ModifiersChangedEvent,
 652    ) -> bool {
 653        if let Some(focused_view_id) = self.window.focused_view_id {
 654            for view_id in self
 655                .ancestors(window_id, focused_view_id)
 656                .collect::<Vec<_>>()
 657            {
 658                if let Some(mut view) = self.views.remove(&(window_id, view_id)) {
 659                    let handled = view.modifiers_changed(event, self, view_id);
 660                    self.views.insert((window_id, view_id), view);
 661                    if handled {
 662                        return true;
 663                    }
 664                } else {
 665                    log::error!("view {} does not exist", view_id)
 666                }
 667            }
 668        }
 669
 670        false
 671    }
 672
 673    pub fn invalidate(&mut self, invalidation: &mut WindowInvalidation, appearance: Appearance) {
 674        self.start_frame();
 675        self.window.appearance = appearance;
 676        for view_id in &invalidation.removed {
 677            invalidation.updated.remove(view_id);
 678            self.window.rendered_views.remove(view_id);
 679        }
 680        for view_id in &invalidation.updated {
 681            let window_id = self.window_id;
 682            let titlebar_height = self.window.titlebar_height;
 683            let hovered_region_ids = self.window.hovered_region_ids.clone();
 684            let clicked_region_ids = self
 685                .window
 686                .clicked_button
 687                .map(|button| (self.window.clicked_region_ids.clone(), button));
 688
 689            let element = self
 690                .render_view(RenderParams {
 691                    window_id,
 692                    view_id: *view_id,
 693                    titlebar_height,
 694                    hovered_region_ids,
 695                    clicked_region_ids,
 696                    refreshing: false,
 697                    appearance,
 698                })
 699                .unwrap();
 700            self.window.rendered_views.insert(*view_id, element);
 701        }
 702    }
 703
 704    pub fn refresh(&mut self, invalidation: &mut WindowInvalidation, appearance: Appearance) {
 705        self.invalidate(invalidation, appearance);
 706
 707        let view_ids = self
 708            .window
 709            .rendered_views
 710            .keys()
 711            .copied()
 712            .collect::<Vec<_>>();
 713
 714        for view_id in view_ids {
 715            if !invalidation.updated.contains(&view_id) {
 716                let window_id = self.window_id;
 717                let titlebar_height = self.window.titlebar_height;
 718                let hovered_region_ids = self.window.hovered_region_ids.clone();
 719                let clicked_region_ids = self
 720                    .window
 721                    .clicked_button
 722                    .map(|button| (self.window.clicked_region_ids.clone(), button));
 723                let element = self
 724                    .render_view(RenderParams {
 725                        window_id,
 726                        view_id,
 727                        titlebar_height,
 728                        hovered_region_ids,
 729                        clicked_region_ids,
 730                        refreshing: true,
 731                        appearance,
 732                    })
 733                    .unwrap();
 734                self.window.rendered_views.insert(view_id, element);
 735            }
 736        }
 737    }
 738
 739    pub fn build_scene(&mut self) -> Scene {
 740        let window_size = self.window.platform_window.content_size();
 741        let scale_factor = self.window.platform_window.scale_factor();
 742
 743        let root_view_id = self.window.root_view().id();
 744        let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
 745        rendered_root.layout(SizeConstraint::strict(window_size), self);
 746
 747        let mut scene_builder = SceneBuilder::new(scale_factor);
 748        rendered_root.paint(
 749            &mut scene_builder,
 750            Vector2F::zero(),
 751            RectF::from_points(Vector2F::zero(), window_size),
 752            self,
 753        );
 754
 755        self.window.text_layout_cache.finish_frame();
 756        let scene = scene_builder.build();
 757        self.window.cursor_regions = scene.cursor_regions();
 758        self.window.mouse_regions = scene.mouse_regions();
 759
 760        if self.window_is_active() {
 761            if let Some(event) = self.window.last_mouse_moved_event.clone() {
 762                self.dispatch_event(event, true);
 763            }
 764        }
 765
 766        scene
 767    }
 768
 769    pub fn rect_for_text_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
 770        let root_view_id = self.window.root_view().id();
 771        self.window
 772            .rendered_views
 773            .get(&root_view_id)?
 774            .rect_for_text_range(range_utf16, self)
 775            .log_err()
 776            .flatten()
 777    }
 778
 779    pub fn debug_elements(&self) -> Option<json::Value> {
 780        let view = self.window.root_view();
 781        Some(json!({
 782            "root_view": view.debug_json(self),
 783            "root_element": self.window.rendered_views.get(&view.id())
 784                .and_then(|root_element| {
 785                    root_element.debug(self).log_err()
 786                })
 787        }))
 788    }
 789
 790    pub fn set_window_title(&mut self, title: &str) {
 791        self.window.platform_window.set_title(title);
 792    }
 793
 794    pub fn set_window_edited(&mut self, edited: bool) {
 795        self.window.platform_window.set_edited(edited);
 796    }
 797
 798    pub fn is_topmost_window_for_position(&self, position: Vector2F) -> bool {
 799        self.window
 800            .platform_window
 801            .is_topmost_for_position(position)
 802    }
 803
 804    pub fn activate_window(&self) {
 805        self.window.platform_window.activate();
 806    }
 807
 808    pub fn window_is_active(&self) -> bool {
 809        self.window.is_active
 810    }
 811
 812    pub fn window_is_fullscreen(&self) -> bool {
 813        self.window.is_fullscreen
 814    }
 815
 816    pub fn focused_view_id(&self) -> Option<usize> {
 817        self.window.focused_view_id
 818    }
 819
 820    pub fn window_bounds(&self) -> WindowBounds {
 821        self.window.platform_window.bounds()
 822    }
 823
 824    pub fn window_appearance(&self) -> Appearance {
 825        self.window.appearance
 826    }
 827
 828    pub fn window_display_uuid(&self) -> Option<Uuid> {
 829        self.window.platform_window.screen().display_uuid()
 830    }
 831
 832    pub fn show_character_palette(&self) {
 833        self.window.platform_window.show_character_palette();
 834    }
 835
 836    pub fn minimize_window(&self) {
 837        self.window.platform_window.minimize();
 838    }
 839
 840    pub fn zoom_window(&self) {
 841        self.window.platform_window.zoom();
 842    }
 843
 844    pub fn toggle_full_screen(&self) {
 845        self.window.platform_window.toggle_full_screen();
 846    }
 847
 848    pub fn prompt(
 849        &self,
 850        level: PromptLevel,
 851        msg: &str,
 852        answers: &[&str],
 853    ) -> oneshot::Receiver<usize> {
 854        self.window.platform_window.prompt(level, msg, answers)
 855    }
 856
 857    fn add_view<T, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<T>
 858    where
 859        T: View,
 860        F: FnOnce(&mut ViewContext<T>) -> T,
 861    {
 862        if parent.window_id == self.window_id {
 863            self.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx)))
 864                .unwrap()
 865        } else {
 866            self.app_context.add_view(parent, build_view)
 867        }
 868    }
 869
 870    fn add_option_view<T, F>(
 871        &mut self,
 872        parent_handle: impl Into<AnyViewHandle>,
 873        build_view: F,
 874    ) -> Option<ViewHandle<T>>
 875    where
 876        T: View,
 877        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 878    {
 879        let parent_handle = parent_handle.into();
 880        self.build_and_insert_view(ParentId::View(parent_handle.view_id), build_view)
 881    }
 882
 883    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
 884    where
 885        V: View,
 886        F: FnOnce(&mut ViewContext<V>) -> V,
 887    {
 888        let root_view = self
 889            .build_and_insert_view(ParentId::Root, |cx| Some(build_root_view(cx)))
 890            .unwrap();
 891        self.window.root_view = Some(root_view.clone().into_any());
 892        self.window.focused_view_id = Some(root_view.id());
 893        root_view
 894    }
 895
 896    pub(crate) fn build_and_insert_view<T, F>(
 897        &mut self,
 898        parent_id: ParentId,
 899        build_view: F,
 900    ) -> Option<ViewHandle<T>>
 901    where
 902        T: View,
 903        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 904    {
 905        let window_id = self.window_id;
 906        let view_id = post_inc(&mut self.next_entity_id);
 907        // Make sure we can tell child views about their parentu
 908        self.parents.insert((window_id, view_id), parent_id);
 909        let mut cx = ViewContext::mutable(self, view_id);
 910        let handle = if let Some(view) = build_view(&mut cx) {
 911            self.views.insert((window_id, view_id), Box::new(view));
 912            self.window
 913                .invalidation
 914                .get_or_insert_with(Default::default)
 915                .updated
 916                .insert(view_id);
 917            Some(ViewHandle::new(window_id, view_id, &self.ref_counts))
 918        } else {
 919            self.parents.remove(&(window_id, view_id));
 920            None
 921        };
 922        handle
 923    }
 924}
 925
 926#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
 927pub enum Axis {
 928    #[default]
 929    Horizontal,
 930    Vertical,
 931}
 932
 933impl Axis {
 934    pub fn invert(self) -> Self {
 935        match self {
 936            Self::Horizontal => Self::Vertical,
 937            Self::Vertical => Self::Horizontal,
 938        }
 939    }
 940
 941    pub fn component(&self, point: Vector2F) -> f32 {
 942        match self {
 943            Self::Horizontal => point.x(),
 944            Self::Vertical => point.y(),
 945        }
 946    }
 947}
 948
 949impl ToJson for Axis {
 950    fn to_json(&self) -> serde_json::Value {
 951        match self {
 952            Axis::Horizontal => json!("horizontal"),
 953            Axis::Vertical => json!("vertical"),
 954        }
 955    }
 956}
 957
 958impl StaticColumnCount for Axis {}
 959impl Bind for Axis {
 960    fn bind(&self, statement: &Statement, start_index: i32) -> anyhow::Result<i32> {
 961        match self {
 962            Axis::Horizontal => "Horizontal",
 963            Axis::Vertical => "Vertical",
 964        }
 965        .bind(statement, start_index)
 966    }
 967}
 968
 969impl Column for Axis {
 970    fn column(statement: &mut Statement, start_index: i32) -> anyhow::Result<(Self, i32)> {
 971        String::column(statement, start_index).and_then(|(axis_text, next_index)| {
 972            Ok((
 973                match axis_text.as_str() {
 974                    "Horizontal" => Axis::Horizontal,
 975                    "Vertical" => Axis::Vertical,
 976                    _ => bail!("Stored serialized item kind is incorrect"),
 977                },
 978                next_index,
 979            ))
 980        })
 981    }
 982}
 983
 984pub trait Vector2FExt {
 985    fn along(self, axis: Axis) -> f32;
 986}
 987
 988impl Vector2FExt for Vector2F {
 989    fn along(self, axis: Axis) -> f32 {
 990        match axis {
 991            Axis::Horizontal => self.x(),
 992            Axis::Vertical => self.y(),
 993        }
 994    }
 995}
 996
 997#[derive(Copy, Clone, Debug)]
 998pub struct SizeConstraint {
 999    pub min: Vector2F,
1000    pub max: Vector2F,
1001}
1002
1003impl SizeConstraint {
1004    pub fn new(min: Vector2F, max: Vector2F) -> Self {
1005        Self { min, max }
1006    }
1007
1008    pub fn strict(size: Vector2F) -> Self {
1009        Self {
1010            min: size,
1011            max: size,
1012        }
1013    }
1014
1015    pub fn strict_along(axis: Axis, max: f32) -> Self {
1016        match axis {
1017            Axis::Horizontal => Self {
1018                min: vec2f(max, 0.0),
1019                max: vec2f(max, f32::INFINITY),
1020            },
1021            Axis::Vertical => Self {
1022                min: vec2f(0.0, max),
1023                max: vec2f(f32::INFINITY, max),
1024            },
1025        }
1026    }
1027
1028    pub fn max_along(&self, axis: Axis) -> f32 {
1029        match axis {
1030            Axis::Horizontal => self.max.x(),
1031            Axis::Vertical => self.max.y(),
1032        }
1033    }
1034
1035    pub fn min_along(&self, axis: Axis) -> f32 {
1036        match axis {
1037            Axis::Horizontal => self.min.x(),
1038            Axis::Vertical => self.min.y(),
1039        }
1040    }
1041
1042    pub fn constrain(&self, size: Vector2F) -> Vector2F {
1043        vec2f(
1044            size.x().min(self.max.x()).max(self.min.x()),
1045            size.y().min(self.max.y()).max(self.min.y()),
1046        )
1047    }
1048}
1049
1050impl Default for SizeConstraint {
1051    fn default() -> Self {
1052        SizeConstraint {
1053            min: Vector2F::zero(),
1054            max: Vector2F::splat(f32::INFINITY),
1055        }
1056    }
1057}
1058
1059impl ToJson for SizeConstraint {
1060    fn to_json(&self) -> serde_json::Value {
1061        json!({
1062            "min": self.min.to_json(),
1063            "max": self.max.to_json(),
1064        })
1065    }
1066}
1067
1068pub struct ChildView {
1069    view_id: usize,
1070    view_name: &'static str,
1071}
1072
1073impl ChildView {
1074    pub fn new(view: &AnyViewHandle, cx: &AppContext) -> Self {
1075        let view_name = cx.view_ui_name(view.window_id(), view.id()).unwrap();
1076        Self {
1077            view_id: view.id(),
1078            view_name,
1079        }
1080    }
1081}
1082
1083impl<V: View> Drawable<V> for ChildView {
1084    type LayoutState = ();
1085    type PaintState = ();
1086
1087    fn layout(
1088        &mut self,
1089        constraint: SizeConstraint,
1090        _: &mut V,
1091        cx: &mut ViewContext<V>,
1092    ) -> (Vector2F, Self::LayoutState) {
1093        if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
1094            let size = rendered_view
1095                .layout(constraint, cx)
1096                .log_err()
1097                .unwrap_or(Vector2F::zero());
1098            cx.window.rendered_views.insert(self.view_id, rendered_view);
1099            (size, ())
1100        } else {
1101            log::error!(
1102                "layout called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
1103                self.view_id,
1104                self.view_name
1105            );
1106            (Vector2F::zero(), ())
1107        }
1108    }
1109
1110    fn paint(
1111        &mut self,
1112        scene: &mut SceneBuilder,
1113        bounds: RectF,
1114        visible_bounds: RectF,
1115        _: &mut Self::LayoutState,
1116        _: &mut V,
1117        cx: &mut ViewContext<V>,
1118    ) {
1119        if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
1120            rendered_view
1121                .paint(scene, bounds.origin(), visible_bounds, cx)
1122                .log_err();
1123            cx.window.rendered_views.insert(self.view_id, rendered_view);
1124        } else {
1125            log::error!(
1126                "paint called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
1127                self.view_id,
1128                self.view_name
1129            );
1130        }
1131    }
1132
1133    fn rect_for_text_range(
1134        &self,
1135        range_utf16: Range<usize>,
1136        _: RectF,
1137        _: RectF,
1138        _: &Self::LayoutState,
1139        _: &Self::PaintState,
1140        _: &V,
1141        cx: &ViewContext<V>,
1142    ) -> Option<RectF> {
1143        if let Some(rendered_view) = cx.window.rendered_views.get(&self.view_id) {
1144            rendered_view
1145                .rect_for_text_range(range_utf16, &cx.window_context)
1146                .log_err()
1147                .flatten()
1148        } else {
1149            log::error!(
1150                "rect_for_text_range called on a ChildView element whose underlying view was dropped (view_id: {}, name: {:?})",
1151                self.view_id,
1152                self.view_name
1153            );
1154            None
1155        }
1156    }
1157
1158    fn debug(
1159        &self,
1160        bounds: RectF,
1161        _: &Self::LayoutState,
1162        _: &Self::PaintState,
1163        _: &V,
1164        cx: &ViewContext<V>,
1165    ) -> serde_json::Value {
1166        json!({
1167            "type": "ChildView",
1168            "view_id": self.view_id,
1169            "bounds": bounds.to_json(),
1170            "view": if let Some(view) = cx.views.get(&(cx.window_id, self.view_id))  {
1171                view.debug_json(cx)
1172            } else {
1173                json!(null)
1174            },
1175            "child": if let Some(element) = cx.window.rendered_views.get(&self.view_id) {
1176                element.debug(&cx.window_context).log_err().unwrap_or_else(|| json!(null))
1177            } else {
1178                json!(null)
1179            }
1180        })
1181    }
1182}