Skip to content
Snippets Groups Projects
Commit 853a8e3e authored by Maryam Dehaini's avatar Maryam Dehaini
Browse files

Add hover support to maximize menu

Open maximize menu when user hovers over maximize window button in
caption.

Bug: 312748319
Test: Manual testing
Change-Id: Ie5bc94c02c5555ea99e6e42f9f6a00c65e348172
parent 19817c18
No related branches found
No related tags found
No related merge requests found
Showing
with 381 additions and 30 deletions
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_hovered="true"
android:color="@color/desktop_mode_caption_button_on_hover_dark"/>
<item android:color="@color/desktop_mode_caption_button"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_hovered="true"
android:color="@color/desktop_mode_caption_button_on_hover_light"/>
<item android:color="@color/desktop_mode_caption_button"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/progress">
<rotate
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="275"
android:toDegrees="275">
<shape
android:shape="ring"
android:thickness="3dp"
android:innerRadius="17dp"
android:useLevel="true">
</shape>
</rotate>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
</shape>
\ No newline at end of file
......@@ -74,17 +74,11 @@
android:layout_height="40dp"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/maximize_window"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="9dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/maximize_button_text"
android:src="@drawable/decor_desktop_mode_maximize_button_dark"
android:scaleType="fitCenter"
android:gravity="end"
android:background="@null"/>
<com.android.wm.shell.windowdecor.MaximizeButtonView
android:id="@+id/maximize_button_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"/>
<ImageButton
android:id="@+id/close_window"
......
......@@ -15,6 +15,7 @@
~ limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/maximize_menu"
style="?android:attr/buttonBarStyle"
android:layout_width="@dimen/desktop_mode_maximize_menu_width"
android:layout_height="@dimen/desktop_mode_maximize_menu_height"
......
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="@drawable/circular_progress"
android:layout_width="40dp"
android:layout_height="40dp"
android:indeterminate="false"
android:visibility="invisible"/>
<ImageButton
android:id="@+id/maximize_window"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="9dp"
android:contentDescription="@string/maximize_button_text"
android:src="@drawable/decor_desktop_mode_maximize_button_dark"
android:scaleType="fitCenter"
android:background="@drawable/rounded_button"/>
</merge>
\ No newline at end of file
......@@ -66,4 +66,9 @@
<color name="desktop_mode_maximize_menu_button_outline">#797869</color>
<color name="desktop_mode_maximize_menu_button_outline_on_hover">#606219</color>
<color name="desktop_mode_maximize_menu_button_on_hover">#E7E790</color>
<color name="desktop_mode_maximize_menu_progress_light">#33000000</color>
<color name="desktop_mode_maximize_menu_progress_dark">#33FFFFFF</color>
<color name="desktop_mode_caption_button_on_hover_light">#11000000</color>
<color name="desktop_mode_caption_button_on_hover_dark">#11FFFFFF</color>
<color name="desktop_mode_caption_button">#00000000</color>
</resources>
......@@ -22,6 +22,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.MotionEvent.ACTION_HOVER_ENTER;
import static android.view.MotionEvent.ACTION_HOVER_EXIT;
import static android.view.WindowInsets.Type.statusBars;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
......@@ -311,8 +313,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
DragDetector.MotionEventHandler {
View.OnGenericMotionListener , DragDetector.MotionEventHandler {
private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150;
private final int mTaskId;
private final WindowContainerToken mTaskToken;
private final DragPositioningCallback mDragPositioningCallback;
......@@ -323,6 +325,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
private boolean mHasLongClicked;
private boolean mShouldClick;
private int mDragPointerId = -1;
private final Runnable mCloseMaximizeWindowRunnable;
private DesktopModeTouchEventListener(
RunningTaskInfo taskInfo,
......@@ -332,6 +335,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDragPositioningCallback = dragPositioningCallback;
mDragDetector = new DragDetector(this);
mGestureDetector = new GestureDetector(mContext, this);
mCloseMaximizeWindowRunnable = () -> {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
if (decoration == null) return;
decoration.closeMaximizeMenu();
};
}
@Override
......@@ -387,13 +395,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDesktopTasksController.ifPresent(c -> c.moveToNextDisplay(mTaskId));
}
} else if (id == R.id.maximize_window) {
if (decoration.isMaximizeMenuActive()) {
decoration.closeMaximizeMenu();
return;
}
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
} else if (id == R.id.maximize_menu_maximize_button) {
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize(taskInfo));
......@@ -460,6 +465,36 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return false;
}
@Override
public boolean onGenericMotion(View v, MotionEvent ev) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
final int id = v.getId();
if (ev.getAction() == ACTION_HOVER_ENTER) {
if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
decoration.onMaximizeWindowHoverEnter();
} else if (id == R.id.maximize_window
|| MaximizeMenu.Companion.isMaximizeMenuView(id)) {
// Re-hovering over any of the maximize menu views should keep the menu open by
// cancelling any attempts to close the menu.
mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
}
return true;
} else if (ev.getAction() == ACTION_HOVER_EXIT) {
if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
decoration.onMaximizeWindowHoverExit();
} else if (id == R.id.maximize_window
|| MaximizeMenu.Companion.isMaximizeMenuView(id)) {
// Close menu if not hovering over maximize menu or maximize button after a
// delay to give user a chance to re-enter view or to move from one maximize
// menu view to another.
mMainHandler.postDelayed(mCloseMaximizeWindowRunnable,
CLOSE_MAXIMIZE_MENU_DELAY_MS);
}
return true;
}
return false;
}
private void moveTaskToFront(RunningTaskInfo taskInfo) {
if (!taskInfo.isFocused) {
mDesktopTasksController.ifPresent(c -> c.moveTaskToFront(taskInfo));
......@@ -990,7 +1025,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);
windowDecoration.setCaptionListeners(
touchEventListener, touchEventListener, touchEventListener);
touchEventListener, touchEventListener, touchEventListener, touchEventListener);
windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
windowDecoration.setDragPositioningCallback(dragPositioningCallback);
windowDecoration.setDragDetector(touchEventListener.mDragDetector);
......@@ -1036,6 +1071,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
return;
}
decoration.showResizeVeil(t, bounds);
decoration.setAnimatingTaskResize(true);
}
@Override
......@@ -1050,6 +1086,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) return;
decoration.hideResizeVeil();
decoration.setAnimatingTaskResize(false);
}
}
......
......@@ -60,6 +60,8 @@ import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowD
import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
import kotlin.Unit;
import java.util.function.Supplier;
/**
......@@ -79,6 +81,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
private View.OnLongClickListener mOnCaptionLongClickListener;
private View.OnGenericMotionListener mOnCaptionGenericMotionListener;
private DragPositioningCallback mDragPositioningCallback;
private DragResizeInputListener mDragResizeListener;
private DragDetector mDragDetector;
......@@ -152,10 +155,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
void setCaptionListeners(
View.OnClickListener onCaptionButtonClickListener,
View.OnTouchListener onCaptionTouchListener,
View.OnLongClickListener onLongClickListener) {
View.OnLongClickListener onLongClickListener,
View.OnGenericMotionListener onGenericMotionListener) {
mOnCaptionButtonClickListener = onCaptionButtonClickListener;
mOnCaptionTouchListener = onCaptionTouchListener;
mOnCaptionLongClickListener = onLongClickListener;
mOnCaptionGenericMotionListener = onGenericMotionListener;
}
void setExclusionRegionListener(ExclusionRegionListener exclusionRegionListener) {
......@@ -225,9 +230,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mOnCaptionTouchListener,
mOnCaptionButtonClickListener,
mOnCaptionLongClickListener,
mOnCaptionGenericMotionListener,
mAppName,
mAppIconBitmap
);
mAppIconBitmap,
() -> {
if (!isMaximizeMenuActive()) {
createMaximizeMenu();
}
return Unit.INSTANCE;
});
} else {
throw new IllegalArgumentException("Unexpected layout resource id");
}
......@@ -548,7 +559,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
*/
void createMaximizeMenu() {
mMaximizeMenu = new MaximizeMenu(mSyncQueue, mRootTaskDisplayAreaOrganizer,
mDisplayController, mTaskInfo, mOnCaptionButtonClickListener, mContext,
mDisplayController, mTaskInfo, mOnCaptionButtonClickListener,
mOnCaptionGenericMotionListener, mOnCaptionTouchListener, mContext,
calculateMaximizeMenuPosition(), mSurfaceControlTransactionSupplier);
mMaximizeMenu.show();
}
......@@ -776,6 +788,22 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
return R.id.desktop_mode_caption;
}
void setAnimatingTaskResize(boolean animatingTaskResize) {
if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) return;
((DesktopModeAppControlsWindowDecorationViewHolder) mWindowDecorViewHolder)
.setAnimatingTaskResize(animatingTaskResize);
}
void onMaximizeWindowHoverExit() {
((DesktopModeAppControlsWindowDecorationViewHolder) mWindowDecorViewHolder)
.onMaximizeWindowHoverExit();
}
void onMaximizeWindowHoverEnter() {
((DesktopModeAppControlsWindowDecorationViewHolder) mWindowDecorViewHolder)
.onMaximizeWindowHoverEnter();
}
@Override
public String toString() {
return "{"
......
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.windowdecor
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ProgressBar
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.content.ContextCompat
import com.android.wm.shell.R
private const val OPEN_MAXIMIZE_MENU_DELAY_ON_HOVER_MS = 350
private const val MAX_DRAWABLE_ALPHA = 255
class MaximizeButtonView(
context: Context,
attrs: AttributeSet
) : FrameLayout(context, attrs) {
lateinit var onHoverAnimationFinishedListener: () -> Unit
private val hoverProgressAnimatorSet = AnimatorSet()
var hoverDisabled = false
private val progressBar: ProgressBar
private val maximizeWindow: ImageButton
init {
LayoutInflater.from(context).inflate(R.layout.maximize_menu_button, this, true)
progressBar = requireViewById(R.id.progress_bar)
maximizeWindow = requireViewById(R.id.maximize_window)
}
fun startHoverAnimation() {
if (hoverDisabled) return
if (hoverProgressAnimatorSet.isRunning) {
cancelHoverAnimation()
}
maximizeWindow.background.alpha = 0
hoverProgressAnimatorSet.playSequentially(
ValueAnimator.ofInt(0, MAX_DRAWABLE_ALPHA)
.setDuration(50)
.apply {
addUpdateListener {
maximizeWindow.background.alpha = animatedValue as Int
}
},
ObjectAnimator.ofInt(progressBar, "progress", 100)
.setDuration(OPEN_MAXIMIZE_MENU_DELAY_ON_HOVER_MS.toLong())
.apply {
doOnStart {
progressBar.setProgress(0, false)
progressBar.visibility = View.VISIBLE
}
doOnEnd {
progressBar.visibility = View.INVISIBLE
onHoverAnimationFinishedListener()
}
}
)
hoverProgressAnimatorSet.start()
}
fun cancelHoverAnimation() {
hoverProgressAnimatorSet.removeAllListeners()
hoverProgressAnimatorSet.cancel()
progressBar.visibility = View.INVISIBLE
}
fun setAnimationTints(darkMode: Boolean) {
if (darkMode) {
progressBar.progressTintList = ColorStateList.valueOf(
resources.getColor(R.color.desktop_mode_maximize_menu_progress_dark))
maximizeWindow.background?.setTintList(ContextCompat.getColorStateList(context,
R.color.desktop_mode_caption_button_color_selector_dark))
} else {
progressBar.progressTintList = ColorStateList.valueOf(
resources.getColor(R.color.desktop_mode_maximize_menu_progress_light))
maximizeWindow.background?.setTintList(ContextCompat.getColorStateList(context,
R.color.desktop_mode_caption_button_color_selector_light))
}
}
}
......@@ -16,6 +16,7 @@
package com.android.wm.shell.windowdecor
import android.annotation.IdRes
import android.app.ActivityManager.RunningTaskInfo
import android.content.Context
import android.content.res.Resources
......@@ -27,6 +28,8 @@ import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.SurfaceControlViewHost
import android.view.View.OnClickListener
import android.view.View.OnGenericMotionListener
import android.view.View.OnTouchListener
import android.view.WindowManager
import android.view.WindowlessWindowManager
import android.widget.Button
......@@ -49,6 +52,8 @@ class MaximizeMenu(
private val displayController: DisplayController,
private val taskInfo: RunningTaskInfo,
private val onClickListener: OnClickListener,
private val onGenericMotionListener: OnGenericMotionListener,
private val onTouchListener: OnTouchListener,
private val decorWindowContext: Context,
private val menuPosition: PointF,
private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }
......@@ -142,15 +147,26 @@ class MaximizeMenu(
private fun setupMaximizeMenu() {
val maximizeMenuView = maximizeMenu?.mWindowViewHost?.view ?: return
maximizeMenuView.requireViewById<Button>(
maximizeMenuView.setOnGenericMotionListener(onGenericMotionListener)
maximizeMenuView.setOnTouchListener(onTouchListener)
val maximizeButton = maximizeMenuView.requireViewById<Button>(
R.id.maximize_menu_maximize_button
).setOnClickListener(onClickListener)
maximizeMenuView.requireViewById<Button>(
)
maximizeButton.setOnClickListener(onClickListener)
maximizeButton.setOnGenericMotionListener(onGenericMotionListener)
val snapRightButton = maximizeMenuView.requireViewById<Button>(
R.id.maximize_menu_snap_right_button
).setOnClickListener(onClickListener)
maximizeMenuView.requireViewById<Button>(
)
snapRightButton.setOnClickListener(onClickListener)
snapRightButton.setOnGenericMotionListener(onGenericMotionListener)
val snapLeftButton = maximizeMenuView.requireViewById<Button>(
R.id.maximize_menu_snap_left_button
).setOnClickListener(onClickListener)
)
snapLeftButton.setOnClickListener(onClickListener)
snapLeftButton.setOnGenericMotionListener(onGenericMotionListener)
}
/**
......@@ -173,4 +189,12 @@ class MaximizeMenu(
private fun viewsLaidOut(): Boolean {
return maximizeMenu?.mWindowViewHost?.view?.isLaidOut ?: false
}
companion object {
fun isMaximizeMenuView(@IdRes viewId: Int): Boolean {
return viewId == R.id.maximize_menu || viewId == R.id.maximize_menu_maximize_button ||
viewId == R.id.maximize_menu_snap_left_button ||
viewId == R.id.maximize_menu_snap_right_button
}
}
}
......@@ -21,6 +21,7 @@ import com.android.internal.R.attr.materialColorSurfaceContainerHigh
import com.android.internal.R.attr.materialColorSurfaceContainerLow
import com.android.internal.R.attr.materialColorSurfaceDim
import com.android.wm.shell.R
import com.android.wm.shell.windowdecor.MaximizeButtonView
/**
* A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
......@@ -32,8 +33,10 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder(
onCaptionTouchListener: View.OnTouchListener,
onCaptionButtonClickListener: View.OnClickListener,
onLongClickListener: OnLongClickListener,
onCaptionGenericMotionListener: View.OnGenericMotionListener,
appName: CharSequence,
appIconBitmap: Bitmap
appIconBitmap: Bitmap,
onMaximizeHoverAnimationFinishedListener: () -> Unit
) : DesktopModeWindowDecorationViewHolder(rootView) {
private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption)
......@@ -41,6 +44,8 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder(
private val openMenuButton: View = rootView.requireViewById(R.id.open_menu_button)
private val closeWindowButton: ImageButton = rootView.requireViewById(R.id.close_window)
private val expandMenuButton: ImageButton = rootView.requireViewById(R.id.expand_menu_button)
private val maximizeButtonView: MaximizeButtonView =
rootView.requireViewById(R.id.maximize_button_view)
private val maximizeWindowButton: ImageButton = rootView.requireViewById(R.id.maximize_window)
private val appNameTextView: TextView = rootView.requireViewById(R.id.application_name)
private val appIconImageView: ImageView = rootView.requireViewById(R.id.application_icon)
......@@ -55,10 +60,13 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder(
closeWindowButton.setOnClickListener(onCaptionButtonClickListener)
maximizeWindowButton.setOnClickListener(onCaptionButtonClickListener)
maximizeWindowButton.setOnTouchListener(onCaptionTouchListener)
maximizeWindowButton.setOnGenericMotionListener(onCaptionGenericMotionListener)
maximizeWindowButton.onLongClickListener = onLongClickListener
closeWindowButton.setOnTouchListener(onCaptionTouchListener)
appNameTextView.text = appName
appIconImageView.setImageBitmap(appIconBitmap)
maximizeButtonView.onHoverAnimationFinishedListener =
onMaximizeHoverAnimationFinishedListener
}
override fun bindData(taskInfo: RunningTaskInfo) {
......@@ -73,12 +81,30 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder(
maximizeWindowButton.imageAlpha = alpha
closeWindowButton.imageAlpha = alpha
expandMenuButton.imageAlpha = alpha
maximizeButtonView.setAnimationTints(isDarkMode())
}
override fun onHandleMenuOpened() {}
override fun onHandleMenuClosed() {}
fun setAnimatingTaskResize(animatingTaskResize: Boolean) {
// If animating a task resize, cancel any running hover animations
if (animatingTaskResize) {
maximizeButtonView.cancelHoverAnimation()
}
maximizeButtonView.hoverDisabled = animatingTaskResize
}
fun onMaximizeWindowHoverExit() {
maximizeButtonView.cancelHoverAnimation()
}
fun onMaximizeWindowHoverEnter() {
maximizeButtonView.startHoverAnimation()
}
@ColorInt
private fun getCaptionBackgroundColor(taskInfo: RunningTaskInfo): Int {
if (isTransparentBackgroundRequested(taskInfo)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment