Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
74dc224
mergeButtonOptions
swabbass Oct 19, 2021
d31e002
apply text
swabbass Oct 19, 2021
4b65a78
add new usecases
swabbass Oct 19, 2021
08ffdf5
refactor apply&merge buttons
swabbass Oct 19, 2021
d1e37c5
add more test cases
swabbass Oct 25, 2021
26361f9
rename measurer test
swabbass Oct 25, 2021
37bb90b
adopt new changes
swabbass Oct 25, 2021
7b9cc4e
delete unused code
swabbass Oct 25, 2021
713ce6b
add getButtonById
swabbass Oct 25, 2021
375c4cc
handle configuration changes
swabbass Oct 25, 2021
5928332
Update ButtonController.kt
swabbass Oct 25, 2021
ebf8ac5
remove unnecessary currentRight and currentLeft
swabbass Oct 25, 2021
846b13a
remove comment
swabbass Oct 25, 2021
62d1291
pass configuration changes to top bar controller
swabbass Oct 25, 2021
5f2d2d2
DEFAULT_BORDER_COLOR to topbarcontroller
swabbass Oct 25, 2021
1415288
rename map to be more clear
swabbass Oct 25, 2021
2736bb0
Update StackPresenter.java
swabbass Oct 25, 2021
5c81556
move merge buttons animations to merge buttons
swabbass Oct 25, 2021
184b388
Update StackPresenter.java
swabbass Oct 25, 2021
63fb47f
extract shared logic
swabbass Oct 25, 2021
f6915cb
Update StackPresenter.java
swabbass Oct 25, 2021
cb98a03
Update StackPresenter.java
swabbass Oct 25, 2021
e54e2b9
pass current child to presenter configuration handler
swabbass Oct 25, 2021
c83521d
host DEFAULT_BORDER_COLOR
swabbass Oct 25, 2021
cb64f9a
Update TopBarController.kt
swabbass Oct 25, 2021
54c0f50
remove unnecessary code
swabbass Oct 25, 2021
fdca0f9
Update TopBarController.kt
swabbass Oct 25, 2021
294f7ff
more readable apply
swabbass Oct 25, 2021
137470c
Update TopBarController.kt
swabbass Oct 25, 2021
db6d8a9
Update TopBarController.kt
swabbass Oct 25, 2021
61bd146
efficient readable merge buttons
swabbass Oct 25, 2021
c5eed83
add onConfiguration changed
swabbass Oct 25, 2021
6d252c6
Delete StressMergeOptions.tsx
swabbass Oct 25, 2021
1047b38
Merge branch 'master' into mergeOptions_frquentCalls
yogevbd Oct 25, 2021
8c270fb
fix units
swabbass Oct 26, 2021
fa6ad0c
move rebuild logic to function
swabbass Oct 26, 2021
d8bc2d6
Merge branch 'master' into mergeOptions_frquentCalls
yogevbd Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public StackController(Activity activity, List<ViewController<?>> children, Chil
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
presenter.onConfigurationChanged(resolveCurrentOptions());
presenter.onConfigurationChanged(resolveCurrentOptions(), getCurrentChild());
fabPresenter.onConfigurationChanged(resolveCurrentOptions());
}

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package com.reactnativenavigation.viewcontrollers.stack.topbar

import android.animation.Animator
import android.content.Context
import android.graphics.Color
import android.view.MenuItem
import android.view.View
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import androidx.viewpager.widget.ViewPager
import com.reactnativenavigation.options.Alignment
import com.reactnativenavigation.options.AnimationOptions
import com.reactnativenavigation.options.ButtonOptions
import com.reactnativenavigation.options.Options
import com.reactnativenavigation.utils.CollectionUtils.forEachIndexed
import com.reactnativenavigation.utils.ViewUtils
import com.reactnativenavigation.utils.resetViewProperties
import com.reactnativenavigation.viewcontrollers.stack.topbar.button.ButtonController
Expand All @@ -17,12 +20,13 @@ import com.reactnativenavigation.views.stack.StackLayout
import com.reactnativenavigation.views.stack.topbar.TopBar
import com.reactnativenavigation.views.stack.topbar.titlebar.ButtonBar

const val DEFAULT_BORDER_COLOR = Color.BLACK

open class TopBarController(private val animator: TopBarAnimator = TopBarAnimator()) {
lateinit var view: TopBar
private lateinit var leftButtonBar: ButtonBar
private lateinit var rightButtonBar: ButtonBar

private val buttonsTransition = AutoTransition()

val height: Int
get() = view.height
Expand Down Expand Up @@ -54,26 +58,26 @@ open class TopBarController(private val animator: TopBarAnimator = TopBarAnimato
fun getPushAnimation(appearingOptions: Options, additionalDy: Float = 0f): Animator? {
if (appearingOptions.topBar.animate.isFalse) return null
return animator.getPushAnimation(
appearingOptions.animations.push.topBar,
appearingOptions.topBar.visible,
additionalDy
appearingOptions.animations.push.topBar,
appearingOptions.topBar.visible,
additionalDy
)
}

fun getPopAnimation(appearingOptions: Options, disappearingOptions: Options): Animator? {
if (appearingOptions.topBar.animate.isFalse) return null
return animator.getPopAnimation(
disappearingOptions.animations.pop.topBar,
appearingOptions.topBar.visible
disappearingOptions.animations.pop.topBar,
appearingOptions.topBar.visible
)
}

fun getSetStackRootAnimation(appearingOptions: Options, additionalDy: Float = 0f): Animator? {
if (appearingOptions.topBar.animate.isFalse) return null
return animator.getSetStackRootAnimation(
appearingOptions.animations.setStackRoot.topBar,
appearingOptions.topBar.visible,
additionalDy
appearingOptions.animations.setStackRoot.topBar,
appearingOptions.topBar.visible,
additionalDy
)
}

Expand Down Expand Up @@ -105,25 +109,182 @@ open class TopBarController(private val animator: TopBarAnimator = TopBarAnimato
view.alignTitleComponent(alignment)
}

fun applyRightButtons(toAdd: List<ButtonController>) {
fun clearRightButtons() {
view.clearRightButtons()
toAdd.reversed().forEachIndexed { i, b -> b.addToMenu(rightButtonBar, i * 10) }
}

fun mergeRightButtons(toAdd: List<ButtonController>, toRemove: List<ButtonController>) {
toRemove.forEach { view.removeRightButton(it) }
toAdd.reversed().forEachIndexed { i, b -> b.addToMenu(rightButtonBar, i * 10) }
fun clearLeftButtons() {
view.clearLeftButtons()
}

open fun applyLeftButtons(toAdd: List<ButtonController>) {
fun clearBackButton() {
view.clearBackButton()
view.clearLeftButtons()
forEachIndexed(toAdd) { b: ButtonController, i: Int -> b.addToMenu(leftButtonBar, i * 10) }
}

open fun mergeLeftButtons(toAdd: List<ButtonController>, toRemove: List<ButtonController>) {
view.clearBackButton()
toRemove.forEach { view.removeLeftButton(it) }
forEachIndexed(toAdd) { b: ButtonController, i: Int -> b.addToMenu(leftButtonBar, i * 10) }
fun setBackButton(backButton: ButtonController?) {
backButton?.let { view.setBackButton(it) }
}

fun animateRightButtons(shouldAnimate: Boolean) {
view.animateRightButtons(shouldAnimate)
}

fun animateLeftButtons(shouldAnimate: Boolean) {
view.animateLeftButtons(shouldAnimate)
}

fun mergeRightButtonsOptions(
btnControllers: MutableMap<String, ButtonController>,
rightButtons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController
) {
mergeButtonOptions(btnControllers, rightButtons.reversed(), controllerCreator, rightButtonBar)
}

fun mergeLeftButtonsOptions(
btnControllers: MutableMap<String, ButtonController>,
leftButtons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController
) {
clearBackButton()
mergeButtonOptions(btnControllers, leftButtons, controllerCreator, leftButtonBar)
}

fun applyRightButtonsOptions(
btnControllers: MutableMap<String, ButtonController>,
rightButtons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController
) {
applyButtonsOptions(
btnControllers,
rightButtons.reversed(),
controllerCreator,
rightButtonBar
)
}

fun applyLeftButtonsOptions(
btnControllers: MutableMap<String, ButtonController>,
leftButtons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController
) {
applyButtonsOptions(btnControllers, leftButtons, controllerCreator, leftButtonBar)
}

private fun applyButtonsOptions(
btnControllers: MutableMap<String, ButtonController>,
buttons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController,
buttonBar: ButtonBar
) {
if (buttonBar.shouldAnimate)
TransitionManager.beginDelayedTransition(buttonBar, buttonsTransition)

buttonBar.clearButtons()
buttons.forEachIndexed { index, it ->
val order = index * 10
val newController = if (btnControllers.containsKey(it.id)) {
btnControllers.remove(it.id)
} else {
controllerCreator(it)
}!!

newController.addToMenu(buttonBar, order)
btnControllers[it.id] = newController
}
}


private fun mergeButtonOptions(
btnControllers: MutableMap<String, ButtonController>,
buttons: List<ButtonOptions>,
controllerCreator: (ButtonOptions) -> ButtonController,
buttonBar: ButtonBar
) {
fun hasChangedOrder(): Boolean {
val values = btnControllers.values
return buttons.filterIndexed { index, buttonOptions ->
val buttonController = btnControllers[buttonOptions.id]
values.indexOf(buttonController) == index
}.size != buttons.size
}

fun sameIdDifferentCompId(
toUpdate: MutableMap<String, Int>,
ctrl: Map.Entry<String, ButtonController>,
buttons: List<ButtonOptions>
) = if (toUpdate.containsKey(ctrl.key)
&& ctrl.value.button.hasComponent()
&& buttons[toUpdate[ctrl.key]!!].component.componentId != ctrl.value.button.component.componentId
) {
toUpdate.remove(ctrl.key)
true
} else false

val requestedButtons = buttons.mapIndexed { index, buttonOptions -> buttonOptions.id to index }.toMap()
var toUpdate = requestedButtons.filter {
btnControllers[it.key]?.areButtonOptionsChanged(buttons[it.value]) ?: false
}.toMutableMap()
var toAdd = requestedButtons.filter { !btnControllers.containsKey(it.key) }
var toRemove = btnControllers.filter { ctrl -> !requestedButtons.containsKey(ctrl.key) }
val toDestroy = btnControllers.filter { ctrl -> sameIdDifferentCompId(toUpdate, ctrl, buttons) }
.toMutableMap().apply { this.putAll(toRemove) }

fun needsRebuild(): Boolean {
return if (toUpdate.size == buttons.size) {
hasChangedOrder()
} else toAdd.isNotEmpty() || toRemove.isNotEmpty()
}

if (needsRebuild()) {
toUpdate = mutableMapOf()
toAdd = requestedButtons
toRemove = btnControllers.toMap()
if (buttonBar.shouldAnimate)
TransitionManager.beginDelayedTransition(buttonBar, buttonsTransition)
}

toUpdate.forEach {
val button = buttons[it.value]
btnControllers[button.id]?.mergeButtonOptions(button, buttonBar)
}
toRemove.forEach {
buttonBar.removeButton(it.value.buttonIntId)
btnControllers.remove(it.key)
}
toDestroy.values.forEach {
it.destroy()
}
toAdd.forEach {
val button = buttons[it.value]
val order = it.value * 10
val newController = btnControllers[button.id] ?: controllerCreator(button)
newController.addToMenu(buttonBar, order)
btnControllers[button.id] = newController
}
}


fun onConfigurationChanged(
options: Options,
leftBtnControllers: MutableMap<String, ButtonController>?,
rightBtnControllers: MutableMap<String, ButtonController>?
) {
leftBtnControllers?.values?.forEach {
it.onConfigurationChanged(leftButtonBar)
}
rightBtnControllers?.values?.forEach {
it.onConfigurationChanged(rightButtonBar)
}

view.setOverflowButtonColor(options.topBar.rightButtonColor.get(Color.BLACK)!!)
view.applyTopTabsColors(
options.topTabs.selectedTabColor,
options.topTabs.unselectedTabColor
)
view.setBorderColor(options.topBar.borderColor.get(DEFAULT_BORDER_COLOR)!!)
view.setBackgroundColor(options.topBar.background.color.get(Color.WHITE)!!)
view.setTitleTextColor(options.topBar.title.color.get(TopBar.DEFAULT_TITLE_COLOR)!!)
view.setSubtitleColor(options.topBar.subtitle.color.get(TopBar.DEFAULT_TITLE_COLOR)!!)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ open class ButtonController(activity: Activity,
return if (other.id != id) false else button.equals(other.button)
}

fun areButtonOptionsChanged(otherOptions:ButtonOptions):Boolean{
return otherOptions.id == id && !button.equals(otherOptions)
}

fun applyNavigationIcon(toolbar: Toolbar) {
presenter.applyNavigationIcon(toolbar) {
onPressListener.onPress(it)
Expand All @@ -83,13 +87,30 @@ open class ButtonController(activity: Activity,

fun addToMenu(buttonBar: ButtonBar, order: Int) {
if (button.component.hasValue() && buttonBar.containsButton(menuItem, order)) return
buttonBar.menu.removeItem(button.intId)
menuItem = buttonBar.addButton(Menu.NONE,
buttonBar.menu.removeItem(button.intId)
menuItem = buttonBar.addButton(Menu.NONE,
button.intId,
order,
presenter.styledText)?.also { menuItem ->
menuItem.setOnMenuItemClickListener(this@ButtonController)
presenter.applyOptions(buttonBar, menuItem, this@ButtonController::getView)
menuItem.setOnMenuItemClickListener(this@ButtonController)
presenter.applyOptions(buttonBar, menuItem, this@ButtonController::getView)
}
}

fun mergeButtonOptions(optionsToMerge: ButtonOptions,buttonBar: ButtonBar) {
button.mergeWith(optionsToMerge)
presenter.button = this.button
buttonBar.getButtonById(button.intId)?.let {
menuItem->
presenter.applyOptions(buttonBar,menuItem,this::getView)
}
}

fun onConfigurationChanged(buttonBar: ButtonBar) {
buttonBar.getButtonById(button.intId)?.let {
menuItem->
presenter.applyOptions(buttonBar,menuItem,this::getView)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import com.reactnativenavigation.utils.ViewUtils
import com.reactnativenavigation.views.stack.topbar.titlebar.IconBackgroundDrawable
import kotlin.math.max

open class ButtonPresenter(private val context: Context, private val button: ButtonOptions, private val iconResolver: IconResolver) {
open class ButtonPresenter(private val context: Context,var button: ButtonOptions, private val iconResolver:
IconResolver) {
companion object {
const val DISABLED_COLOR = Color.LTGRAY
}
Expand All @@ -47,6 +48,8 @@ open class ButtonPresenter(private val context: Context, private val button: But
applyComponent(menuItem, viewCreator)
applyAccessibilityLabel(menuItem)
applyIcon(menuItem)
applyText(menuItem)


applyOptionsDirectlyOnView(toolbar, menuItem) {
applyTestId(it)
Expand All @@ -55,6 +58,11 @@ open class ButtonPresenter(private val context: Context, private val button: But
}
}

private fun applyText(menuItem: MenuItem) {
if (button.text.hasValue())
menuItem.title = button.text.get()
}

fun applyColor(toolbar: Toolbar, menuItem: MenuItem, color: ThemeColour) {
button.color = color
applyIcon(menuItem)
Expand Down
Loading