diff options
author | Stefan Niedermann <info@niedermann.it> | 2023-02-13 01:12:25 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2023-02-13 01:12:25 +0300 |
commit | c9685459faf73423e5f3ad885947e047cb962b06 (patch) | |
tree | 7f4562cf120604ca891031c72ad84bae34bf78f6 /app/src/main | |
parent | d530b6aa63bef653178c2ad28bb7a7fbc4f55d34 (diff) |
refactor(details): Reimplement with ConstraintLayout
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main')
5 files changed, 233 insertions, 188 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java index 4eb3f983c..0bc027ca8 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeAdapter.java @@ -3,9 +3,11 @@ package it.niedermann.nextcloud.deck.ui.card.details; import static androidx.recyclerview.widget.RecyclerView.NO_ID; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.util.Consumer; import androidx.recyclerview.widget.RecyclerView; @@ -19,6 +21,8 @@ import it.niedermann.nextcloud.deck.model.User; @SuppressWarnings("WeakerAccess") public class AssigneeAdapter extends RecyclerView.Adapter<AssigneeViewHolder> { + @Nullable + private RecyclerView recyclerView; private final Account account; @NonNull private final List<User> users = new ArrayList<>(); @@ -41,6 +45,18 @@ public class AssigneeAdapter extends RecyclerView.Adapter<AssigneeViewHolder> { return id == null ? NO_ID : id; } + @Override + public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + this.recyclerView = recyclerView; + } + + @Override + public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { + super.onDetachedFromRecyclerView(recyclerView); + this.recyclerView = null; + } + @NonNull @Override public AssigneeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -62,18 +78,26 @@ public class AssigneeAdapter extends RecyclerView.Adapter<AssigneeViewHolder> { public void setUsers(@NonNull List<User> users) { this.users.clear(); this.users.addAll(users); + updateRecylcerViewVisibility(); notifyDataSetChanged(); } public void addUser(@NonNull User user) { this.users.add(user); + updateRecylcerViewVisibility(); notifyItemInserted(this.users.size()); } public void removeUser(@NonNull User user) { final int index = this.users.indexOf(user); this.users.remove(user); + updateRecylcerViewVisibility(); notifyItemRemoved(index); } + private void updateRecylcerViewVisibility() { + if (this.recyclerView != null) { + this.recyclerView.setVisibility(this.getItemCount() > 0 ? View.VISIBLE : View.GONE); + } + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java index 096dcfa53..03db28095 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/AssigneeDecoration.java @@ -9,20 +9,24 @@ import androidx.recyclerview.widget.RecyclerView; public class AssigneeDecoration extends RecyclerView.ItemDecoration { + private final int spanCount; private final int gutter; - public AssigneeDecoration(@Px int gutter) { + public AssigneeDecoration(int spanCount, @Px int gutter) { + this.spanCount = spanCount; this.gutter = gutter; } @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { - final int position = parent.getChildAdapterPosition(view); + int position = parent.getChildAdapterPosition(view); + int column = position % spanCount; - if (position >= 0) { - // All columns get some spacing at the bottom and at the right side - outRect.right = gutter; - outRect.bottom = gutter; + outRect.left = column * gutter / spanCount; + outRect.right = gutter - (column + 1) * gutter / spanCount; + + if (position >= spanCount) { + outRect.top = gutter; } } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java index 4eec53ece..b76fae043 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/details/CardDetailsFragment.java @@ -315,10 +315,11 @@ public class CardDetailsFragment extends Fragment implements OnDateSetListener, binding.assignees.setAdapter(adapter); binding.assignees.post(() -> { @Px final int gutter = DimensionUtil.INSTANCE.dpToPx(requireContext(), R.dimen.spacer_1x); - final int spanCount = (int) (float) binding.assignees.getWidth() / (DimensionUtil.INSTANCE.dpToPx(requireContext(), R.dimen.avatar_size) + gutter); + final int spanCount = (int) (float) binding.labelsWrapper.getWidth() / (DimensionUtil.INSTANCE.dpToPx(requireContext(), R.dimen.avatar_size) + gutter); binding.assignees.setLayoutManager(new GridLayoutManager(getContext(), spanCount)); - binding.assignees.addItemDecoration(new AssigneeDecoration(gutter)); + binding.assignees.addItemDecoration(new AssigneeDecoration(spanCount, gutter)); }); + if (viewModel.canEdit()) { Long localCardId = viewModel.getFullCard().getCard().getLocalId(); localCardId = localCardId == null ? -1 : localCardId; @@ -330,16 +331,12 @@ public class CardDetailsFragment extends Fragment implements OnDateSetListener, adapter.addUser(user); binding.people.setText(""); }); - - if (this.viewModel.getFullCard().getAssignedUsers() != null) { - adapter.setUsers(this.viewModel.getFullCard().getAssignedUsers()); - } } else { binding.people.setEnabled(false); + } - if (this.viewModel.getFullCard().getAssignedUsers() != null) { - adapter.setUsers(this.viewModel.getFullCard().getAssignedUsers()); - } + if (this.viewModel.getFullCard().getAssignedUsers() != null) { + adapter.setUsers(this.viewModel.getFullCard().getAssignedUsers()); } } @@ -408,13 +405,10 @@ public class CardDetailsFragment extends Fragment implements OnDateSetListener, viewModel.getFullCard().getAssignedUsers().remove(user); adapter.removeUser(user); ((UserAutoCompleteAdapter) binding.people.getAdapter()).include(user); - ThemedSnackbar.make( - requireView(), getString(R.string.unassigned_user, user.getDisplayname()), - Snackbar.LENGTH_LONG) - .setAction(R.string.simple_undo, v1 -> { - viewModel.getFullCard().getAssignedUsers().add(user); - ((UserAutoCompleteAdapter) binding.people.getAdapter()).exclude(user); - adapter.addUser(user); - }).show(); + ThemedSnackbar.make(requireView(), getString(R.string.unassigned_user, user.getDisplayname()), Snackbar.LENGTH_LONG).setAction(R.string.simple_undo, v1 -> { + viewModel.getFullCard().getAssignedUsers().add(user); + ((UserAutoCompleteAdapter) binding.people.getAdapter()).exclude(user); + adapter.addUser(user); + }).show(); } } diff --git a/app/src/main/res/layout/fragment_card_edit_tab_details.xml b/app/src/main/res/layout/fragment_card_edit_tab_details.xml index 347e990b8..3d5ed3be2 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_details.xml +++ b/app/src/main/res/layout/fragment_card_edit_tab_details.xml @@ -6,202 +6,221 @@ android:layout_height="wrap_content" android:fillViewport="true"> - <RelativeLayout + <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:padding="@dimen/spacer_2x"> - <LinearLayout - android:id="@+id/details" + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/labelsWrapper" + style="@style/textInputLayoutStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:padding="@dimen/spacer_2x"> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/labelsWrapper" - style="@style/textInputLayoutStyle" + android:hint="@string/label_labels" + app:layout_constraintBottom_toTopOf="@id/labelsGroup" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:startIconDrawable="@drawable/ic_label_grey600_24dp"> + + <it.niedermann.nextcloud.deck.ui.view.ToggleAutoCompleteTextView + android:id="@+id/labels" + style="@style/Widget.Material3.AutoCompleteTextView.OutlinedBox.Dense" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_2x" - android:hint="@string/label_labels" - app:startIconDrawable="@drawable/ic_label_grey600_24dp"> + android:completionThreshold="1" + android:inputType="text" /> + </com.google.android.material.textfield.TextInputLayout> - <it.niedermann.nextcloud.deck.ui.view.ToggleAutoCompleteTextView - android:id="@+id/labels" - style="@style/Widget.Material3.AutoCompleteTextView.OutlinedBox.Dense" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:completionThreshold="1" - android:inputType="text" /> - </com.google.android.material.textfield.TextInputLayout> - - <com.google.android.material.chip.ChipGroup - android:id="@+id/labelsGroup" + <com.google.android.material.chip.ChipGroup + android:id="@+id/labelsGroup" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:animateLayoutChanges="true" + app:layout_constraintBottom_toTopOf="@id/peopleWrapper" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/labelsWrapper" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/peopleWrapper" + style="@style/textInputLayoutStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacer_2x" + android:hint="@string/hint_assign_people" + app:layout_constraintBottom_toTopOf="@id/assignees" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/labelsGroup" + app:startIconDrawable="@drawable/ic_person_grey600_24dp"> + + <it.niedermann.nextcloud.deck.ui.view.ToggleAutoCompleteTextView + android:id="@+id/people" + style="@style/Widget.Material3.AutoCompleteTextView.OutlinedBox.Dense" android:layout_width="match_parent" android:layout_height="wrap_content" - android:animateLayoutChanges="true" /> + android:completionThreshold="1" + android:inputType="text" /> + </com.google.android.material.textfield.TextInputLayout> - <LinearLayout - android:id="@+id/colorPicker" + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/assignees" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacer_1x" + android:layout_marginBottom="@dimen/spacer_1hx" + app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" + app:layout_constraintBottom_toTopOf="@id/dueDateDateWrapper" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/peopleWrapper" + tools:listitem="@tools:sample/avatars" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/dueDateDateWrapper" + style="@style/textInputLayoutStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacer_2x" + android:layout_marginEnd="@dimen/spacer_2x" + android:hint="@string/hint_due_date_date" + android:labelFor="@id/dueDateDate" + app:layout_constraintBottom_toTopOf="@id/descriptionWrapper" + app:layout_constraintEnd_toStartOf="@id/dueDateTimeWrapper" + app:layout_constraintHorizontal_weight="2" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/assignees" + app:startIconDrawable="@drawable/calendar_blank_grey600_24dp"> + + <EditText + android:id="@+id/dueDateDate" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_2x"> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/dueDateDateWrapper" - style="@style/textInputLayoutStyle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="2" - android:hint="@string/hint_due_date_date" - android:labelFor="@id/dueDateDate" - android:paddingStart="0dp" - android:paddingEnd="@dimen/spacer_2x" - app:startIconDrawable="@drawable/calendar_blank_grey600_24dp"> - - <EditText - android:id="@+id/dueDateDate" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:enabled="true" - android:focusable="false" - android:importantForAutofill="no" - android:inputType="date" - android:maxLines="1" - tools:text="01/07/2020" /> - </com.google.android.material.textfield.TextInputLayout> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/dueDateTimeWrapper" - style="@style/textInputLayoutStyle" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_horizontal" - android:layout_weight="1" - android:hint="@string/hint_due_date_time" - android:labelFor="@id/dueDateTime"> - - <EditText - android:id="@+id/dueDateTime" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:enabled="true" - android:focusable="false" - android:importantForAutofill="no" - android:inputType="datetime" - android:maxLines="1" - android:minLines="0" - android:textAlignment="center" - tools:text="11:45" /> - </com.google.android.material.textfield.TextInputLayout> - - <ImageView - android:id="@+id/clearDueDate" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@string/label_clear_due_date" - android:paddingStart="@dimen/spacer_2x" - android:paddingTop="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1x" - android:paddingBottom="@dimen/spacer_1x" - android:translationY="@dimen/spacer_1hx" - app:srcCompat="@drawable/ic_close_circle_grey600" /> - </LinearLayout> + android:enabled="true" + android:focusable="false" + android:importantForAutofill="no" + android:inputType="date" + android:maxLines="1" + tools:text="01/07/2020" /> + </com.google.android.material.textfield.TextInputLayout> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/dueDateTimeWrapper" + style="@style/textInputLayoutStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/spacer_1hx" + android:hint="@string/hint_due_date_time" + android:labelFor="@id/dueDateTime" + app:layout_constraintBottom_toBottomOf="@id/dueDateDateWrapper" + app:layout_constraintEnd_toStartOf="@id/clearDueDate" + app:layout_constraintHorizontal_weight="1" + app:layout_constraintStart_toEndOf="@id/dueDateDateWrapper" + app:layout_constraintTop_toTopOf="@id/dueDateDateWrapper"> + + <EditText + android:id="@+id/dueDateTime" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:enabled="true" + android:focusable="false" + android:importantForAutofill="no" + android:inputType="datetime" + android:maxLines="1" + android:minLines="0" + android:textAlignment="center" + tools:text="11:45" /> + </com.google.android.material.textfield.TextInputLayout> + + <ImageView + android:id="@+id/clearDueDate" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginVertical="@dimen/spacer_1hx" + android:layout_marginStart="@dimen/spacer_1x" + android:layout_marginEnd="0dp" + android:contentDescription="@string/label_clear_due_date" + android:padding="@dimen/spacer_11qx" + android:translationY="@dimen/spacer_1hx" + app:layout_constraintBottom_toBottomOf="@id/dueDateTimeWrapper" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/dueDateTimeWrapper" + app:layout_constraintTop_toTopOf="@id/dueDateTimeWrapper" + app:srcCompat="@drawable/ic_close_circle_grey600" /> + + <RelativeLayout + android:id="@+id/descriptionWrapper" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacer_1x" + app:layout_constraintBottom_toTopOf="@id/projectsTitle" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/dueDateDateWrapper"> <com.google.android.material.textfield.TextInputLayout - android:id="@+id/peopleWrapper" + android:id="@+id/descriptionEditorWrapper" style="@style/textInputLayoutStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_2x" - android:hint="@string/hint_assign_people" - app:startIconDrawable="@drawable/ic_person_grey600_24dp"> + android:layout_marginTop="@dimen/spacer_1x" + android:hint="@string/label_description"> - <it.niedermann.nextcloud.deck.ui.view.ToggleAutoCompleteTextView - android:id="@+id/people" - style="@style/Widget.Material3.AutoCompleteTextView.OutlinedBox.Dense" + <it.niedermann.android.markdown.MarkdownEditorImpl + android:id="@+id/descriptionEditor" android:layout_width="match_parent" android:layout_height="wrap_content" - android:completionThreshold="1" - android:inputType="text" /> + android:padding="@dimen/spacer_2x" + android:textColor="?attr/colorAccent" + android:textSize="@dimen/font_size_description" /> + </com.google.android.material.textfield.TextInputLayout> - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/assignees" + <it.niedermann.android.markdown.MarkdownViewerImpl + android:id="@+id/descriptionViewer" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_1x" - app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" - tools:listitem="@tools:sample/avatars" /> - - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/descriptionEditorWrapper" - style="@style/textInputLayoutStyle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_1x" - android:hint="@string/label_description"> - - <it.niedermann.android.markdown.MarkdownEditorImpl - android:id="@+id/descriptionEditor" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacer_1x" - android:padding="@dimen/spacer_2x" - android:textColor="?attr/colorAccent" - android:textSize="@dimen/font_size_description" /> - - </com.google.android.material.textfield.TextInputLayout> - - <it.niedermann.android.markdown.MarkdownViewerImpl - android:id="@+id/descriptionViewer" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="12dp" - android:padding="@dimen/spacer_2x" - android:textColor="?attr/colorAccent" - android:textIsSelectable="true" - android:textSize="@dimen/font_size_description" - android:translationY="1dp" - android:visibility="gone" /> - - <ImageButton - android:id="@+id/descriptionToggle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentEnd="true" - android:layout_gravity="bottom" - android:layout_marginEnd="6dp" - android:background="?attr/colorPrimary" - android:contentDescription="@string/edit_description" - android:paddingStart="@dimen/spacer_1hx" - android:paddingTop="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1hx" - android:paddingBottom="@dimen/spacer_1hx" - android:translationY="-7dp" - android:visibility="invisible" - app:srcCompat="@drawable/ic_baseline_eye_24" - tools:visibility="visible" /> - </RelativeLayout> - </LinearLayout> + android:layout_marginTop="12dp" + android:padding="@dimen/spacer_2x" + android:textColor="?attr/colorAccent" + android:textIsSelectable="true" + android:textSize="@dimen/font_size_description" + android:translationY="1dp" + android:visibility="gone" /> + + <ImageButton + android:id="@+id/descriptionToggle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentEnd="true" + android:layout_gravity="bottom" + android:layout_marginEnd="6dp" + android:background="?attr/colorPrimary" + android:contentDescription="@string/edit_description" + android:paddingStart="@dimen/spacer_1hx" + android:paddingTop="@dimen/spacer_1x" + android:paddingEnd="@dimen/spacer_1hx" + android:paddingBottom="@dimen/spacer_1hx" + android:translationY="-7dp" + android:visibility="invisible" + app:srcCompat="@drawable/ic_baseline_eye_24" + tools:visibility="visible" /> + </RelativeLayout> <TextView android:id="@+id/projectsTitle" style="?attr/textAppearanceOverline" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/details" - android:layout_marginStart="@dimen/icon_size_details" - android:layout_marginTop="@dimen/spacer_2x" android:paddingStart="@dimen/spacer_4x" android:paddingEnd="@null" - android:text="@string/projects_title" /> + android:text="@string/projects_title" + app:layout_constraintBottom_toTopOf="@id/projects" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/descriptionWrapper" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/projects" @@ -209,6 +228,9 @@ android:layout_height="wrap_content" android:layout_below="@id/projectsTitle" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/projectsTitle" tools:listitem="@layout/item_project" /> - </RelativeLayout> + </androidx.constraintlayout.widget.ConstraintLayout> </ScrollView> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 6ea4d8de3..1acec4aaa 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,6 +2,7 @@ <dimen name="spacer_1qx">2dp</dimen> <dimen name="spacer_1hx">4dp</dimen> <dimen name="spacer_1x">8dp</dimen> + <dimen name="spacer_11qx">10dp</dimen> <dimen name="spacer_2x">16dp</dimen> <dimen name="spacer_3x">24dp</dimen> <dimen name="spacer_4x">32dp</dimen> |