From ffe91f8ca2ee92337ec100b0ee4f1ee730bd6c9d Mon Sep 17 00:00:00 2001 From: marcel7 <144210616+marcel7ag@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:17:01 +0100 Subject: [PATCH] [26442] Patientendetails scaling of elements (#734) --- .../contacts/preferences/UserSettings2.java | 9 + .../ui/contacts/views/Patientenblatt2.java | 155 +++++++++++++++++- .../core/ui/util/LabeledInputField.java | 6 + .../ch/elexis/core/constants/Preferences.java | 2 + 4 files changed, 166 insertions(+), 6 deletions(-) diff --git a/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/preferences/UserSettings2.java b/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/preferences/UserSettings2.java index 85f4a47d2b..def6d4f77e 100644 --- a/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/preferences/UserSettings2.java +++ b/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/preferences/UserSettings2.java @@ -28,6 +28,7 @@ import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.preference.RadioGroupFieldEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -86,6 +87,8 @@ public UserSettings2() { prefs.setDefault(Preferences.USR_PATLIST_SHOWDOB, true); prefs.setDefault(Preferences.USR_SUPPRESS_INTERACTION_CHECK, true); prefs.setDefault(Patientenblatt2.CFG_GLOBALFIELDS, false); + prefs.setDefault(Preferences.USR_PATDETAIL_MINWIDTH, 100); + prefs.setDefault(Preferences.USR_PATDETAIL_MINWIDTH_STATE, false); } @Override @@ -141,6 +144,12 @@ public void widgetSelected(SelectionEvent e) { } }); new Label(getFieldEditorParent(), SWT.NONE).setText(StringUtils.EMPTY); + Composite fwc = new Composite(getFieldEditorParent(), SWT.NONE); + fwc.setLayout(new GridLayout(2, true)); + addField(new BooleanFieldEditor(Preferences.USR_PATDETAIL_MINWIDTH_STATE, + "Feste Mindestbreite in Patientendetail-Felder nutzen", fwc)); + addField(new IntegerFieldEditor(Preferences.USR_PATDETAIL_MINWIDTH, "Breite: ", fwc)); + new Label(getFieldEditorParent(), SWT.NONE).setText(StringUtils.EMPTY); ComboFieldEditor editor = new ComboFieldEditor(Preferences.CFG_DECEASED_STICKER, "Sticker für verstorbene", getStickerComboItems(), getFieldEditorParent()); editor.setPreferenceStore(new ConfigServicePreferenceStore(Scope.GLOBAL)); diff --git a/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/views/Patientenblatt2.java b/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/views/Patientenblatt2.java index b267788cf1..b129bfb719 100644 --- a/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/views/Patientenblatt2.java +++ b/bundles/ch.elexis.core.ui.contacts/src/ch/elexis/core/ui/contacts/views/Patientenblatt2.java @@ -55,14 +55,21 @@ import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PlatformUI; @@ -72,6 +79,7 @@ import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.events.IExpansionListener; +import org.eclipse.ui.forms.widgets.ColumnLayoutData; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; @@ -82,6 +90,7 @@ import ch.elexis.core.ac.EvACE; import ch.elexis.core.ac.Right; import ch.elexis.core.common.ElexisEventTopics; +import ch.elexis.core.constants.Preferences; import ch.elexis.core.constants.StringConstants; import ch.elexis.core.constants.XidConstants; import ch.elexis.core.data.interfaces.IPersistentObject; @@ -497,6 +506,9 @@ public void reloadContent(Object po, InputData ltf) { refresh(); if (actPatient != null) { setPatient(actPatient); + } else { + setupFieldWidthsAndListeners(ipp.getAutoForm().getChildren()); + setToolTipTextListeners(); } layout(true); } @@ -519,6 +531,9 @@ public void controlResized(ControlEvent e) { } }); + form.getHorizontalBar().addListener(SWT.Selection, (e) -> updateExpandableLayoutWidth()); + form.getHorizontalBar().addListener(SWT.Hide, (e) -> updateExpandableLayoutWidth()); + stickerComposite = StickerComposite.createWrappedStickerComposite(form.getBody(), tk); cUserfields = new Composite(form.getBody(), SWT.NONE); @@ -987,6 +1002,7 @@ public void refreshUi() { dmd.reload(); updateExpandableLayoutWidth(); + setupFieldWidthsAndListeners(ipp.getAutoForm().getChildren()); refresh(); } @@ -1518,14 +1534,141 @@ public void run() { }; } + /** + * Adjusts the width of fields in the input panel based on user preferences or + * field label length. Iterates through controls, identifies + * {@code LabeledInputField} instances, and adjusts their layout data. The width + * is determined by either a user-configured width or label length. Also + * disables mouse wheel scrolling for combo boxes and calls + * setupStickerCompositeWidth to configure the width of the sticker components. + * + * @param controls array of {@code Control} elements to configure + */ + private void setupFieldWidthsAndListeners(Control[] controls) { + int fieldWidth = 0; + for (Control ctrl : controls) { + if (ctrl instanceof LabeledInputField) { + LabeledInputField field = (LabeledInputField) ctrl; + if (field != null) { + ColumnLayoutData data = (ColumnLayoutData) field.getLayoutData(); + if (data == null) { + data = new ColumnLayoutData(); + } + if (ConfigServiceHolder.getUser(Preferences.USR_PATDETAIL_MINWIDTH_STATE, false)) { + fieldWidth = ConfigServiceHolder.getUser(Preferences.USR_PATDETAIL_MINWIDTH, 100); + } else { + Point labelSize = CoreUiUtil.getStringExtent(field, field.getLabelComponent().getText()); + int extraWidth = 0; + if (field.getLayout() instanceof GridLayout) { + extraWidth = ((GridLayout) field.getLayout()).marginWidth + + ((GridLayout) field.getLayout()).horizontalSpacing; + } + fieldWidth = labelSize.x + extraWidth; + } + data.widthHint = fieldWidth; + field.setLayoutData(data); + + if (field.getControl() instanceof Combo) { + Combo combo = (Combo) field.getControl(); + combo.addListener(SWT.MouseWheel, event -> { + event.doit = false; + }); + } + } + updateToolTipText(field); + } + } + setupStickerCompositeWidth(fieldWidth); + refresh(); + } + + /** + * Configures the width of stickerComposite's child components. Ensures the + * overall view can be minimized correctly by setting the width hint. + * + * @param width the width to set for each child composite + */ + private void setupStickerCompositeWidth(int width) { + for (Control stickerCtrl : stickerComposite.getChildren()) { + if (stickerCtrl instanceof Composite) { + Composite sticker = (Composite) stickerCtrl; + ColumnLayoutData data = (ColumnLayoutData) sticker.getLayoutData(); + data.widthHint = width; + sticker.setLayoutData(data); + } + } + } + + /** + * Adds listeners to the {@link LabeledInputField} components to update the + * tooltip text when the content in the input field has been modified. + *

+ * This method only adds a Listener if the {@link LabeledInputField} type is of + * TEXT. + *

+ */ + private void setToolTipTextListeners() { + if (ipp.getAutoForm() != null && !ipp.getAutoForm().isDisposed()) { + Control[] children = ipp.getAutoForm().getChildren(); + for (Control child : children) { + if (child instanceof LabeledInputField) { + LabeledInputField field = (LabeledInputField) child; + if (!field.isFixedTooltip() && field.getControl() instanceof Text) { + ((Text) field.getControl()).addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + updateToolTipText(field); + } + }); + } + } + } + } + } + + /** + * Updates the {@code ToolTipText} of the {@link LabeledInputField} component + * within the form. The ToolTip is set to display the Text content of the + * {@link LabeledInputField}. + * + * @param editor {@link LabeledInputField} to update the {@code ToolTipText} + * of. + */ + private void updateToolTipText(LabeledInputField editor) { + if (ipp.getAutoForm() != null && !ipp.getAutoForm().isDisposed()) { + if (!editor.isFixedTooltip() && editor.getControl() instanceof Text) { + editor.getControl().setToolTipText(editor.getText()); + } + } + } + + /** + * Dynamically adjusts the width of {@link ExpandableComposite}'s based on the + * available client area.
+ * This method adjusts the LayoutData of each {@link ExpandableComposite} to + * either fill the space or if the horizontal ScrollBar is visible, maintain a + * calculated fixed width. + */ private void updateExpandableLayoutWidth() { if (ec != null && form != null && !form.isDisposed()) { - for (ExpandableComposite expandable : ec) { - if (expandable.getLayoutData() instanceof GridData) { - if (Patientenblatt2.this.getClientArea().width > 50) { - ((GridData) expandable.getLayoutData()).widthHint = Patientenblatt2.this.getClientArea().width; - } else { - ((GridData) expandable.getLayoutData()).widthHint = SWT.DEFAULT; + int clientAreaWidth = Patientenblatt2.this.getClientArea().width; + int barPos = form.getHorizontalBar().getSelection(); + boolean shouldFixWidth = clientAreaWidth > 50 && form.getHorizontalBar().isVisible(); + + Control[] body = form.getBody().getChildren(); + for (Control control : body) { + if (control instanceof ExpandableComposite) { + if (control.getLayoutData() instanceof GridData) { + GridData gridData = (GridData) control.getLayoutData(); + if (shouldFixWidth) { + gridData.grabExcessHorizontalSpace = false; + gridData.horizontalAlignment = SWT.DEFAULT; + gridData.widthHint = clientAreaWidth - 40 + barPos; + } else { + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + gridData.widthHint = SWT.DEFAULT; + } } } } diff --git a/bundles/ch.elexis.core.ui/src/ch/elexis/core/ui/util/LabeledInputField.java b/bundles/ch.elexis.core.ui/src/ch/elexis/core/ui/util/LabeledInputField.java index 5a1e580c63..9b4d21b694 100644 --- a/bundles/ch.elexis.core.ui/src/ch/elexis/core/ui/util/LabeledInputField.java +++ b/bundles/ch.elexis.core.ui/src/ch/elexis/core/ui/util/LabeledInputField.java @@ -86,6 +86,7 @@ static public enum Typ { StructuredViewer viewer; FormToolkit tk = UiDesk.getToolkit(); Typ inputFieldType; + boolean fixedTooltip; /** * simply creates a LabeledInputField of Type LabeledInputField.Typ.TEXT} @@ -324,6 +325,10 @@ public StructuredViewer getViewer() { return viewer; } + public boolean isFixedTooltip() { + return fixedTooltip; + } + @Override public void setEnabled(boolean enabled) { if (ctl != null && !ctl.isDisposed()) { @@ -550,6 +555,7 @@ public void setChoices(String... strings) { public void setTooltipText(String label) { if (mine != null && mine.ctl != null) { mine.ctl.setToolTipText(label); + mine.fixedTooltip = true; } } } diff --git a/bundles/ch.elexis.core/src/ch/elexis/core/constants/Preferences.java b/bundles/ch.elexis.core/src/ch/elexis/core/constants/Preferences.java index 3325b6bbed..9f801498df 100644 --- a/bundles/ch.elexis.core/src/ch/elexis/core/constants/Preferences.java +++ b/bundles/ch.elexis.core/src/ch/elexis/core/constants/Preferences.java @@ -149,6 +149,8 @@ public class Preferences { public static final String USR_PLAF = "anwender/plaf"; //$NON-NLS-1$ public static final String USR_DEFAULTFONT = "anwender/stdfont"; //$NON-NLS-1$ public static final String USR_SMALLFONT = "anwender/smallfont"; //$NON-NLS-1$ + public static final String USR_PATDETAIL_MINWIDTH = "view/patdetail/minwidth"; //$NON-NLS-1$ + public static final String USR_PATDETAIL_MINWIDTH_STATE = USR_PATDETAIL_MINWIDTH + "/state"; //$NON-NLS-1$ public static final String USR_PATLIST_SHOWPATNR = "anwender/patlist/zeigenr"; //$NON-NLS-1$ public static final String USR_PATLIST_SHOWNAME = "anwender/patlist/zeigename"; //$NON-NLS-1$ public static final String USR_PATLIST_SHOWFIRSTNAME = "anwender/patlist/zeigevorname"; //$NON-NLS-1$