Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc

Issue 27458002: Allow setting different hit test bounds overrides for mouse and touch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" 5 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/wm/window_properties.h" 12 #include "ash/wm/window_state.h"
13 #include "base/command_line.h"
14 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" 14 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
16 #include "chrome/browser/ui/immersive_fullscreen_configuration.h" 15 #include "chrome/browser/ui/immersive_fullscreen_configuration.h"
17 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 16 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
18 #include "chrome/browser/ui/views/frame/top_container_view.h" 17 #include "chrome/browser/ui/views/frame/top_container_view.h"
19 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/browser/web_contents_view.h"
22 #include "ui/aura/client/activation_client.h" 19 #include "ui/aura/client/activation_client.h"
23 #include "ui/aura/client/aura_constants.h" 20 #include "ui/aura/client/aura_constants.h"
24 #include "ui/aura/client/capture_client.h" 21 #include "ui/aura/client/capture_client.h"
25 #include "ui/aura/client/cursor_client.h" 22 #include "ui/aura/client/cursor_client.h"
26 #include "ui/aura/client/screen_position_client.h" 23 #include "ui/aura/client/screen_position_client.h"
27 #include "ui/aura/env.h" 24 #include "ui/aura/env.h"
28 #include "ui/aura/root_window.h" 25 #include "ui/aura/root_window.h"
29 #include "ui/aura/window.h" 26 #include "ui/aura/window.h"
30 #include "ui/gfx/animation/slide_animation.h" 27 #include "ui/gfx/animation/slide_animation.h"
31 #include "ui/views/bubble/bubble_delegate.h" 28 #include "ui/views/bubble/bubble_delegate.h"
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 //////////////////////////////////////////////////////////////////////////////// 257 ////////////////////////////////////////////////////////////////////////////////
261 258
262 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh() 259 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh()
263 : delegate_(NULL), 260 : delegate_(NULL),
264 widget_(NULL), 261 widget_(NULL),
265 top_container_(NULL), 262 top_container_(NULL),
266 observers_enabled_(false), 263 observers_enabled_(false),
267 enabled_(false), 264 enabled_(false),
268 reveal_state_(CLOSED), 265 reveal_state_(CLOSED),
269 revealed_lock_count_(0), 266 revealed_lock_count_(0),
270 tab_indicator_visibility_(TAB_INDICATORS_HIDE),
271 mouse_x_when_hit_top_in_screen_(-1), 267 mouse_x_when_hit_top_in_screen_(-1),
272 gesture_begun_(false), 268 gesture_begun_(false),
273 native_window_(NULL), 269 native_window_(NULL),
274 animation_(new gfx::SlideAnimation(this)), 270 animation_(new gfx::SlideAnimation(this)),
275 animations_disabled_for_test_(false), 271 animations_disabled_for_test_(false),
276 weak_ptr_factory_(this) { 272 weak_ptr_factory_(this) {
277 } 273 }
278 274
279 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() { 275 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() {
280 // The browser view is being destroyed so there's no need to update its 276 // The browser view is being destroyed so there's no need to update its
(...skipping 27 matching lines...) Expand all
308 void ImmersiveModeControllerAsh::Init( 304 void ImmersiveModeControllerAsh::Init(
309 Delegate* delegate, 305 Delegate* delegate,
310 views::Widget* widget, 306 views::Widget* widget,
311 views::View* top_container) { 307 views::View* top_container) {
312 delegate_ = delegate; 308 delegate_ = delegate;
313 widget_ = widget; 309 widget_ = widget;
314 // Browser view is detached from its widget during destruction. Cache the 310 // Browser view is detached from its widget during destruction. Cache the
315 // window pointer so |this| can stop observing during destruction. 311 // window pointer so |this| can stop observing during destruction.
316 native_window_ = widget_->GetNativeWindow(); 312 native_window_ = widget_->GetNativeWindow();
317 top_container_ = top_container; 313 top_container_ = top_container;
318
319 // Optionally allow the tab indicators to be hidden.
320 if (CommandLine::ForCurrentProcess()->
321 HasSwitch(ash::switches::kAshImmersiveHideTabIndicators)) {
322 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE;
323 }
324 } 314 }
325 315
326 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) { 316 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) {
327 DCHECK(native_window_) << "Must initialize before enabling"; 317 DCHECK(native_window_) << "Must initialize before enabling";
328 if (enabled_ == enabled) 318 if (enabled_ == enabled)
329 return; 319 return;
330 enabled_ = enabled; 320 enabled_ = enabled;
331 321
332 EnableWindowObservers(enabled_); 322 EnableWindowObservers(enabled_);
333 323
334 UpdateUseMinimalChrome(LAYOUT_NO); 324 if (enabled_) {
325 UpdateUseMinimalChrome(LAYOUT_NO);
335 326
336 if (enabled_) {
337 // Animate enabling immersive mode by sliding out the top-of-window views. 327 // Animate enabling immersive mode by sliding out the top-of-window views.
338 // No animation occurs if a lock is holding the top-of-window views open. 328 // No animation occurs if a lock is holding the top-of-window views open.
339 329
340 // Do a reveal to set the initial state for the animation. (And any 330 // Do a reveal to set the initial state for the animation. (And any
341 // required state in case the animation cannot run because of a lock holding 331 // required state in case the animation cannot run because of a lock holding
342 // the top-of-window views open.) This call has the side effect of relaying 332 // the top-of-window views open.) This call has the side effect of relaying
343 // out |browser_view_|'s root view. 333 // out |browser_view_|'s root view.
344 MaybeStartReveal(ANIMATE_NO); 334 MaybeStartReveal(ANIMATE_NO);
345 335
346 // Reset the located event and the focus revealed locks so that they do not 336 // Reset the located event and the focus revealed locks so that they do not
347 // affect whether the top-of-window views are hidden. 337 // affect whether the top-of-window views are hidden.
348 located_event_revealed_lock_.reset(); 338 located_event_revealed_lock_.reset();
349 focus_revealed_lock_.reset(); 339 focus_revealed_lock_.reset();
350 340
351 // Try doing the animation. 341 // Try doing the animation.
352 MaybeEndReveal(ANIMATE_SLOW); 342 MaybeEndReveal(ANIMATE_SLOW);
353 343
354 if (reveal_state_ == REVEALED) { 344 if (reveal_state_ == REVEALED) {
355 // Reveal was unsuccessful. Reacquire the revealed locks if appropriate. 345 // Reveal was unsuccessful. Reacquire the revealed locks if appropriate.
356 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 346 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
357 UpdateFocusRevealedLock(); 347 UpdateFocusRevealedLock();
358 } 348 }
359 } else { 349 } else {
360 // Stop cursor-at-top tracking. 350 // Stop cursor-at-top tracking.
361 top_edge_hover_timer_.Stop(); 351 top_edge_hover_timer_.Stop();
362 // Snap immediately to the closed state. 352 // Snap immediately to the closed state.
363 reveal_state_ = CLOSED; 353 reveal_state_ = CLOSED;
364 EnablePaintToLayer(false); 354 EnablePaintToLayer(false);
365 delegate_->SetImmersiveStyle(false); 355 delegate_->SetImmersiveStyle(false);
366 SetRenderWindowTopInsetsForTouch(0);
367 356
368 // Layout the root view so that incognito avatar icon, if any, gets laid 357 // Layout the root view so that incognito avatar icon, if any, gets laid
369 // out. 358 // out.
370 LayoutBrowserRootView(); 359 LayoutBrowserRootView();
371 } 360 }
372 } 361 }
373 362
374 bool ImmersiveModeControllerAsh::IsEnabled() const { 363 bool ImmersiveModeControllerAsh::IsEnabled() const {
375 return enabled_; 364 return enabled_;
376 } 365 }
377 366
378 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const { 367 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const {
379 return tab_indicator_visibility_ != TAB_INDICATORS_SHOW; 368 return ash::wm::GetWindowState(native_window_)->fullscreen_type() !=
369 ash::wm::FULLSCREEN_TYPE_IMMERSIVE_MINIMAL_CHROME;
380 } 370 }
381 371
382 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const { 372 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const {
383 return enabled_ && reveal_state_ == CLOSED; 373 return enabled_ && reveal_state_ == CLOSED;
384 } 374 }
385 375
386 bool ImmersiveModeControllerAsh::IsRevealed() const { 376 bool ImmersiveModeControllerAsh::IsRevealed() const {
387 return enabled_ && reveal_state_ != CLOSED; 377 return enabled_ && reveal_state_ != CLOSED;
388 } 378 }
389 379
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 587
598 void ImmersiveModeControllerAsh::OnRemoveTransientChild( 588 void ImmersiveModeControllerAsh::OnRemoveTransientChild(
599 aura::Window* window, 589 aura::Window* window,
600 aura::Window* transient) { 590 aura::Window* transient) {
601 bubble_manager_->StopObserving(transient); 591 bubble_manager_->StopObserving(transient);
602 } 592 }
603 593
604 //////////////////////////////////////////////////////////////////////////////// 594 ////////////////////////////////////////////////////////////////////////////////
605 // Testing interface: 595 // Testing interface:
606 596
607 void ImmersiveModeControllerAsh::SetForceHideTabIndicatorsForTest(bool force) {
608 if (force)
609 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE;
610 else if (tab_indicator_visibility_ == TAB_INDICATORS_FORCE_HIDE)
611 tab_indicator_visibility_ = TAB_INDICATORS_HIDE;
612 UpdateUseMinimalChrome(LAYOUT_YES);
613 }
614
615 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) { 597 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) {
616 MaybeStartReveal(ANIMATE_NO); 598 MaybeStartReveal(ANIMATE_NO);
617 MoveMouse(top_container_, hovered); 599 MoveMouse(top_container_, hovered);
618 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 600 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
619 } 601 }
620 602
621 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) { 603 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) {
622 MoveMouse(top_container_, hovered); 604 MoveMouse(top_container_, hovered);
623 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 605 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
624 } 606 }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 877
896 // Ending the reveal was unsuccessful. Reaquire the locks if appropriate. 878 // Ending the reveal was unsuccessful. Reaquire the locks if appropriate.
897 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 879 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
898 UpdateFocusRevealedLock(); 880 UpdateFocusRevealedLock();
899 } 881 }
900 } 882 }
901 return false; 883 return false;
902 } 884 }
903 885
904 void ImmersiveModeControllerAsh::UpdateUseMinimalChrome(Layout layout) { 886 void ImmersiveModeControllerAsh::UpdateUseMinimalChrome(Layout layout) {
887 if (!enabled_)
888 return;
889
890 ash::wm::FullscreenType previous_fullscreen_type =
891 ash::wm::GetWindowState(native_window_)->fullscreen_type();
892
905 // May be NULL in tests. 893 // May be NULL in tests.
906 FullscreenController* fullscreen_controller = 894 FullscreenController* fullscreen_controller =
907 delegate_->GetFullscreenController(); 895 delegate_->GetFullscreenController();
908 bool in_tab_fullscreen = fullscreen_controller ? 896 bool in_tab_fullscreen = fullscreen_controller ?
909 fullscreen_controller->IsFullscreenForTabOrPending() : false; 897 fullscreen_controller->IsFullscreenForTabOrPending() : false;
910 bool use_minimal_chrome = !in_tab_fullscreen && enabled_; 898 ash::wm::FullscreenType fullscreen_type = in_tab_fullscreen ?
911 native_window_->SetProperty(ash::internal::kFullscreenUsesMinimalChromeKey, 899 ash::wm::FULLSCREEN_TYPE_IMMERSIVE_NO_CHROME :
912 use_minimal_chrome); 900 ash::wm::FULLSCREEN_TYPE_IMMERSIVE_MINIMAL_CHROME;
913 901
914 TabIndicatorVisibility previous_tab_indicator_visibility = 902 if (fullscreen_type == previous_fullscreen_type)
915 tab_indicator_visibility_; 903 return;
916 if (tab_indicator_visibility_ != TAB_INDICATORS_FORCE_HIDE) { 904 ash::wm::GetWindowState(native_window_)->SetFullscreenType(fullscreen_type);
917 tab_indicator_visibility_ = use_minimal_chrome ?
918 TAB_INDICATORS_SHOW : TAB_INDICATORS_HIDE;
919 }
920 905
921 // Ash on Windows may not have a shell. 906 // Ash on Windows may not have a shell.
922 if (ash::Shell::HasInstance()) { 907 if (ash::Shell::HasInstance()) {
923 // When using minimal chrome, the shelf is auto-hidden. The auto-hidden 908 // When using minimal chrome, the shelf is auto-hidden. The auto-hidden
924 // shelf displays a 3px 'light bar' when it is closed. 909 // shelf displays a 3px 'light bar' when it is closed.
925 ash::Shell::GetInstance()->UpdateShelfVisibility(); 910 ash::Shell::GetInstance()->UpdateShelfVisibility();
926 } 911 }
927 912
928 if (tab_indicator_visibility_ != previous_tab_indicator_visibility) { 913 // If the top-of-window views are revealed or animating, the change will take
929 // If the top-of-window views are revealed or animating, the change will 914 // effect with the layout once the top-of-window views are closed.
930 // take effect with the layout once the top-of-window views are closed. 915 if (layout == LAYOUT_YES && reveal_state_ == CLOSED)
931 if (layout == LAYOUT_YES && reveal_state_ == CLOSED) 916 LayoutBrowserRootView();
932 LayoutBrowserRootView();
933 }
934 } 917 }
935 918
936 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const { 919 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const {
937 switch (animate) { 920 switch (animate) {
938 case ANIMATE_NO: 921 case ANIMATE_NO:
939 return 0; 922 return 0;
940 case ANIMATE_SLOW: 923 case ANIMATE_SLOW:
941 return kRevealSlowAnimationDurationMs; 924 return kRevealSlowAnimationDurationMs;
942 case ANIMATE_FAST: 925 case ANIMATE_FAST:
943 return kRevealFastAnimationDurationMs; 926 return kRevealFastAnimationDurationMs;
(...skipping 20 matching lines...) Expand all
964 reveal_state_ = SLIDING_OPEN; 947 reveal_state_ = SLIDING_OPEN;
965 if (previous_reveal_state == CLOSED) { 948 if (previous_reveal_state == CLOSED) {
966 // Turn on layer painting so that we can overlap the web contents. 949 // Turn on layer painting so that we can overlap the web contents.
967 EnablePaintToLayer(true); 950 EnablePaintToLayer(true);
968 951
969 // Ensure window caption buttons are updated and the view bounds are 952 // Ensure window caption buttons are updated and the view bounds are
970 // computed at normal (non-immersive-style) size. The layout call moves the 953 // computed at normal (non-immersive-style) size. The layout call moves the
971 // top-of-window views to their initial offscreen position for the 954 // top-of-window views to their initial offscreen position for the
972 // animation. 955 // animation.
973 delegate_->SetImmersiveStyle(false); 956 delegate_->SetImmersiveStyle(false);
974 SetRenderWindowTopInsetsForTouch(0);
975 LayoutBrowserRootView(); 957 LayoutBrowserRootView();
976 958
977 // Do not do any more processing if LayoutBrowserView() changed 959 // Do not do any more processing if LayoutBrowserView() changed
978 // |reveal_state_|. 960 // |reveal_state_|.
979 if (reveal_state_ != SLIDING_OPEN) { 961 if (reveal_state_ != SLIDING_OPEN) {
980 if (reveal_state_ == REVEALED) 962 if (reveal_state_ == REVEALED)
981 FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted()); 963 FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
982 return; 964 return;
983 } 965 }
984 } 966 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 } 1044 }
1063 } 1045 }
1064 1046
1065 void ImmersiveModeControllerAsh::OnSlideClosedAnimationCompleted() { 1047 void ImmersiveModeControllerAsh::OnSlideClosedAnimationCompleted() {
1066 DCHECK_EQ(SLIDING_CLOSED, reveal_state_); 1048 DCHECK_EQ(SLIDING_CLOSED, reveal_state_);
1067 reveal_state_ = CLOSED; 1049 reveal_state_ = CLOSED;
1068 // Layers aren't needed after animation completes. 1050 // Layers aren't needed after animation completes.
1069 EnablePaintToLayer(false); 1051 EnablePaintToLayer(false);
1070 // Update tabstrip for closed state. 1052 // Update tabstrip for closed state.
1071 delegate_->SetImmersiveStyle(true); 1053 delegate_->SetImmersiveStyle(true);
1072 SetRenderWindowTopInsetsForTouch(kNearTopContainerDistance);
1073 LayoutBrowserRootView(); 1054 LayoutBrowserRootView();
1074 } 1055 }
1075 1056
1076 bool ImmersiveModeControllerAsh::ShouldExitImmersiveFullscreen() const { 1057 bool ImmersiveModeControllerAsh::ShouldExitImmersiveFullscreen() const {
1077 if (!native_window_) 1058 if (!native_window_)
1078 return false; 1059 return false;
1079 1060
1080 ui::WindowShowState show_state = static_cast<ui::WindowShowState>( 1061 ui::WindowShowState show_state = static_cast<ui::WindowShowState>(
1081 native_window_->GetProperty(aura::client::kShowStateKey)); 1062 native_window_->GetProperty(aura::client::kShowStateKey));
1082 return IsEnabled() && 1063 return IsEnabled() &&
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 // the closest screen ensures that the event is from a valid bezel and can be 1123 // the closest screen ensures that the event is from a valid bezel and can be
1143 // interpreted as such. 1124 // interpreted as such.
1144 gfx::Rect screen_bounds = 1125 gfx::Rect screen_bounds =
1145 ash::Shell::GetScreen()->GetDisplayNearestPoint(location).bounds(); 1126 ash::Shell::GetScreen()->GetDisplayNearestPoint(location).bounds();
1146 return (!screen_bounds.Contains(location) && 1127 return (!screen_bounds.Contains(location) &&
1147 location.y() < top_container_bounds_in_screen.y() && 1128 location.y() < top_container_bounds_in_screen.y() &&
1148 location.x() >= top_container_bounds_in_screen.x() && 1129 location.x() >= top_container_bounds_in_screen.x() &&
1149 location.x() < top_container_bounds_in_screen.right()); 1130 location.x() < top_container_bounds_in_screen.right());
1150 } 1131 }
1151 1132
1152 void ImmersiveModeControllerAsh::SetRenderWindowTopInsetsForTouch(
1153 int top_inset) {
1154 content::WebContents* contents = delegate_->GetWebContents();
1155 if (contents) {
1156 aura::Window* window = contents->GetView()->GetContentNativeView();
1157 // |window| is NULL if the renderer crashed.
1158 if (window) {
1159 gfx::Insets inset(top_inset, 0, 0, 0);
1160 window->SetHitTestBoundsOverrideOuter(
1161 window->hit_test_bounds_override_outer_mouse(),
1162 inset);
1163 }
1164 }
1165 }
1166
1167 void ImmersiveModeControllerAsh::RecreateBubbleManager() { 1133 void ImmersiveModeControllerAsh::RecreateBubbleManager() {
1168 bubble_manager_.reset(new BubbleManager(this)); 1134 bubble_manager_.reset(new BubbleManager(this));
1169 const std::vector<aura::Window*> transient_children = 1135 const std::vector<aura::Window*> transient_children =
1170 native_window_->transient_children(); 1136 native_window_->transient_children();
1171 for (size_t i = 0; i < transient_children.size(); ++i) { 1137 for (size_t i = 0; i < transient_children.size(); ++i) {
1172 aura::Window* transient_child = transient_children[i]; 1138 aura::Window* transient_child = transient_children[i];
1173 views::BubbleDelegateView* bubble_delegate = 1139 views::BubbleDelegateView* bubble_delegate =
1174 AsBubbleDelegate(transient_child); 1140 AsBubbleDelegate(transient_child);
1175 if (bubble_delegate && 1141 if (bubble_delegate &&
1176 bubble_delegate->GetAnchorView() && 1142 bubble_delegate->GetAnchorView() &&
1177 top_container_->Contains(bubble_delegate->GetAnchorView())) { 1143 top_container_->Contains(bubble_delegate->GetAnchorView())) {
1178 bubble_manager_->StartObserving(transient_child); 1144 bubble_manager_->StartObserving(transient_child);
1179 } 1145 }
1180 } 1146 }
1181 } 1147 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698