-
-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android background_color
Transparency Fixes
#3118
Open
proneon267
wants to merge
17
commits into
beeware:main
Choose a base branch
from
proneon267:fix_android_background_color
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
2187bb2
Fix android background color
proneon267 0d2f4b6
Merge branch 'beeware:main' into fix_android_background_color
proneon267 2bc87f4
Added changenote
proneon267 489dab3
Restart CI
proneon267 a257295
Update android/src/toga_android/widgets/base.py
proneon267 e3c87d5
Fix pre commit issues
proneon267 d6c599b
Merge branch 'beeware:main' into fix_android_background_color
proneon267 802e9b1
Refactor according to review
proneon267 d697cda
Remove changes related to #3156 and disable setting Selection popup b…
proneon267 49a54f5
Remove unused method
proneon267 2faa335
Make DetailedList and ProgressBar use Widget class instead of Contain…
proneon267 7a621d0
Correct probe
proneon267 8959ff1
Remove stray code
proneon267 099ca07
Merge branch 'main' into fix_android_background_color
mhsmith 608dec1
Remove unnecessary call to `reapply`
mhsmith 7d8c6fe
Apply suggestions from review
proneon267 95c2ca4
Apply suggestions from review
proneon267 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,15 @@ | ||
from abc import ABC, abstractmethod | ||
from decimal import ROUND_HALF_EVEN, Decimal | ||
|
||
from android.graphics import PorterDuff, PorterDuffColorFilter, Rect | ||
from android.graphics.drawable import ColorDrawable, InsetDrawable | ||
from android.graphics import Color, PorterDuff, PorterDuffColorFilter | ||
from android.graphics.drawable import ColorDrawable | ||
from android.view import Gravity, View | ||
from android.widget import RelativeLayout | ||
from org.beeware.android import MainActivity | ||
from travertino.size import at_least | ||
|
||
from toga.constants import CENTER, JUSTIFY, LEFT, RIGHT, TRANSPARENT | ||
|
||
from ..colors import native_color | ||
from toga.constants import CENTER, JUSTIFY, LEFT, RIGHT | ||
from toga_android.colors import native_color | ||
|
||
|
||
class Scalable: | ||
|
@@ -54,6 +53,8 @@ def __init__(self, interface): | |
self.init_scale(self._native_activity) | ||
self.create() | ||
|
||
self.native_toplevel = self.native | ||
|
||
# Some widgets, e.g. TextView, may throw an exception if we call measure() | ||
# before setting LayoutParams. | ||
self.native.setLayoutParams( | ||
|
@@ -63,6 +64,8 @@ def __init__(self, interface): | |
) | ||
) | ||
|
||
self._default_background_color = Color.TRANSPARENT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
@abstractmethod | ||
def create(self): ... | ||
|
||
|
@@ -115,9 +118,9 @@ def set_bounds(self, x, y, width, height): | |
|
||
def set_hidden(self, hidden): | ||
if hidden: | ||
self.native.setVisibility(View.INVISIBLE) | ||
self.native_toplevel.setVisibility(View.INVISIBLE) | ||
else: | ||
self.native.setVisibility(View.VISIBLE) | ||
self.native_toplevel.setVisibility(View.VISIBLE) | ||
|
||
def set_font(self, font): | ||
# By default, font can't be changed | ||
|
@@ -128,33 +131,20 @@ def set_font(self, font): | |
# appearance. So each widget must decide how to implement this method, possibly | ||
# using one of the utility functions below. | ||
def set_background_color(self, color): | ||
pass | ||
self.set_background_simple(color) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be possible to simplify this even further:
|
||
|
||
def set_background_simple(self, value): | ||
if not hasattr(self, "_default_background"): | ||
self._default_background = self.native.getBackground() | ||
def set_background_simple(self, color): | ||
self.native_toplevel.setBackground( | ||
ColorDrawable( | ||
self._default_background_color if color is None else native_color(color) | ||
) | ||
) | ||
|
||
if value in (None, TRANSPARENT): | ||
self.native.setBackground(self._default_background) | ||
else: | ||
background = ColorDrawable(native_color(value)) | ||
if isinstance(self._default_background, InsetDrawable): | ||
outer_padding = Rect() | ||
inner_padding = Rect() | ||
self._default_background.getPadding(outer_padding) | ||
self._default_background.getDrawable().getPadding(inner_padding) | ||
insets = [ | ||
getattr(outer_padding, name) - getattr(inner_padding, name) | ||
for name in ["left", "top", "right", "bottom"] | ||
] | ||
background = InsetDrawable(background, *insets) | ||
self.native.setBackground(background) | ||
|
||
def set_background_filter(self, value): | ||
def set_background_filter(self, color): | ||
self.native.getBackground().setColorFilter( | ||
None | ||
if value in (None, TRANSPARENT) | ||
else PorterDuffColorFilter(native_color(value), PorterDuff.Mode.SRC_IN) | ||
if color is None | ||
else PorterDuffColorFilter(native_color(color), PorterDuff.Mode.SRC_IN) | ||
) | ||
|
||
def set_text_align(self, alignment): | ||
|
@@ -194,3 +184,47 @@ def android_text_align(value): | |
CENTER: Gravity.CENTER_HORIZONTAL, | ||
JUSTIFY: Gravity.LEFT, | ||
}[value] | ||
|
||
|
||
# Most of the Android Widget have different effects applied them which provide | ||
# the native look and feel of Android. These widgets' background consists of | ||
# Drawables like ColorDrawable, InsetDrawable and other animation Effect Drawables | ||
# like RippleDrawable. Often when such Effect Drawables are used, they are stacked | ||
# along with other Drawables in a LayerDrawable. | ||
# | ||
# LayerDrawable once created cannot be modified and attempting to modify it or | ||
# creating a new LayerDrawable using the elements of the original LayerDrawable | ||
# stack, will destroy the native look and feel of the widgets. The original | ||
# LayerDrawable cannot also be properly cloned. Using `getConstantState()` on the | ||
# Drawable will produce an erroneous version of the original Drawable. | ||
# | ||
# These widgets also draw some of their background effects on their native parent. | ||
# But in the Widget base class, the native parent is actually the root Box of the | ||
# layout, and the parent Box is stacked under its children without any native | ||
# parent/child relationship. So if the parent Box has a background color, it may | ||
# conceal some of the background elements of its children. | ||
# | ||
# Hence, the best option to preserve the native look and feel of the these widgets is | ||
# to contain them in a `RelativeLayout` and set the background color to the layout | ||
# instead of the widget itself. | ||
# | ||
# ContainedWidget should act as a drop-in replacement against the Widget class for | ||
# such widgets, without requiring the widgets to do anything extra on their part. | ||
# It should be used for widgets that have an animated Effect Drawable as background | ||
# and their native look and feel needs to be preserved. | ||
class ContainedWidget(Widget): | ||
def __init__(self, interface): | ||
super().__init__(interface) | ||
|
||
self.native_toplevel = RelativeLayout(self._native_activity) | ||
self.native_toplevel.addView(self.native) | ||
|
||
self.native.setLayoutParams( | ||
RelativeLayout.LayoutParams( | ||
RelativeLayout.LayoutParams.MATCH_PARENT, | ||
RelativeLayout.LayoutParams.MATCH_PARENT, | ||
) | ||
) | ||
# Immediately re-apply styles. Some widgets may defer style application until | ||
# they have been added to a container. | ||
self.interface.style.reapply() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
from android.widget import RelativeLayout | ||
|
||
from toga.colors import TRANSPARENT | ||
|
||
from .base import Widget | ||
|
||
|
||
class Box(Widget): | ||
def create(self): | ||
self.native = RelativeLayout(self._native_activity) | ||
|
||
def set_background_color(self, value): | ||
self.set_background_simple(value) | ||
def set_background_color(self, color): | ||
self.set_background_simple(TRANSPARENT if color is None else color) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need for this reformatting.