SyncCoordinatesAspect.java
/*
** Module : SyncCoordinatesAspect.java
** Abstract : An aspect which intercepts assignment of coordinate fields.
**
** Copyright (c) 2014-2021, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------Description----------------------------------
** 001 HC 20141207 Created initial version.
** 002 HC 20150102 Fixed handling of uninitialized values for the coordinate fields.
** 003 HC 20150228 Referenced objects stored in local context.
** 004 HC 20150405 Refactoring of config coordinate fields.
** 005 HC 20150508 Improvements to GUI window scrolling support.
** 006 HC 20150513 Javadocs improved.
** 007 CA 20150722 Added a new exclusion in afterSetWidthChars: LabelConfig.setDefaults is called
** only from c'tors.
** 008 HC 20150803 Improved runtime support for WINDOW size attributes.
** 009 HC 20151110 Added client-side size fields.
** 010 HC 20160203 Improved runtime support of FRAME:VIRTUAL* attributes.
** 011 EVL 20160223 Javadoc fixes to make compatible with Oracle Java 8 for Solaris 10.
** 012 HC 20160308 Fixed coordinate conversion of client size config fields.
** 013 HC 20171102 Implemented image load size and offset, plus related changes.
** 014 EVL 20181112 Fixed incorrect transformation code for image size.
** 015 VVT 20210806 Added missing support for ButtonImageDefinition fields: offsetX, offsetCol,
** offsetY and offsetRow
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.aspects.ui;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import com.goldencode.p2j.net.SessionManager;
import com.goldencode.p2j.security.ContextLocal;
import com.goldencode.p2j.ui.*;
import com.goldencode.p2j.ui.chui.ThinClient;
/**
* The aspect implements synchronization of linked coordinate
* attributes like WIDTH-CHARS/WIDTH-PIXELS, COLUMN/X, etc. by
* intercepting the respective public fields from
* {@code com.goldencode.p2j.ui.*Config} classes. Also all assignments
* of coordinate values to the config coordinate fields are scaled
* through {@link Coordinate#scale(double)}.
* <p>
* The aspect intercepts both server and client.
* <p>
* During char->pixel conversion the converted value must be rounded to
* the nearest pixel. This also means that the original character value
* doesn't correspond to its pixel representation. This is why another
* conversion from pixel to char is performed and the original character
* value set to the config field may change!
*/
@Aspect
public class SyncCoordinatesAspect
{
/** Storage of context-local state variables. */
private ContextLocal<WorkArea> contextData = new ContextLocal<WorkArea>()
{
@Override
protected WorkArea initialValue()
{
WorkArea wa = new WorkArea();
boolean onClientSide = SessionManager.get().isLeaf();
if (onClientSide)
{
ThinClient tc = ThinClient.getInstance();
if (tc != null)
{
wa.cc = tc.getOutputManager().coordinates();
wa.cm = ConfigManager.getInstance();
}
}
else
{
wa.cc = LogicalTerminal.coordinates();
wa.cm = ConfigManager.getInstance();
}
return wa;
}
};
/** Thread local variable holding the number of suspensions. */
private static ThreadLocal<Integer> suspendCount = new ThreadLocal<Integer>()
{
@Override
protected Integer initialValue()
{
return 0;
}
};
/**
* The common pointcut for all the advices. This covers server and
* client UI calls, and excludes deserialization, cloning
* operations and methods marked by {@link NoSyncCoordinates} annotation.
*/
@Pointcut("within(com.goldencode.p2j.ui..*)" +
"&& !withincode(com.goldencode.p2j.ui.*Config.new(..)) " +
"&& !withincode(com.goldencode.p2j.ui.ButtonImageDefinition.new(..)) " +
"&& !withincode(void readExternal(..)) " +
"&& !withincode(void applyConfig(..)) ")
public void withinCommonPoint()
{
}
/**
* Suspends coordinate synchronization for the current thread.
* Every suspend call must be paired off with one call to {@link #resume()}.
*/
public static void suspend()
{
int nextCount = suspendCount.get().intValue() + 1;
suspendCount.set(nextCount);
}
/**
* Resumes coordinate synchronization previously suspended with
* {@link #resume()}.
*/
public static void resume()
{
int nextCount = suspendCount.get().intValue() - 1;
if (nextCount < 0)
{
throw new IllegalStateException("Suspend count out of balance!");
}
suspendCount.set(nextCount);
}
/**
* Returns <code>true</code> when coordinate synchronization has been
* suspended with {@link #suspend()}.
*
* @return See above.
*/
public static boolean isSuspended()
{
return suspendCount.get() > 0;
}
/**
* This advice is executed for methods annotated with {@link NoSyncCoordinates}.
* It suspends coordinate synchronization with {@link #suspend()} before
* the annotated method is executed and then resumes with {@link #resume()}
* after the annotated method returns.
*
* @param jp
* A reference to {@link ProceedingJoinPoint}.
*
* @return Returns the result of the executed method.
*/
@Around("execution(@com.goldencode.p2j.ui.NoSyncCoordinates * *(..))")
public Object suspendAround(ProceedingJoinPoint jp)
{
try
{
suspend();
return jp.proceed();
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
finally
{
resume();
}
}
/**
* The after-advice for {@link BaseConfig#initColumn}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.initColumn)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetInitColumn(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.initColumn = Coordinate.scale(cfg.initColumn);
// handle the uninitialized case
if (cfg.initColumn == BaseConfig.INV_COORD)
{
cfg.initX = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.initX = wa.cc.columnToPixels(cfg.initColumn);
cfg.initColumn = wa.cc.columnFromPixels(cfg.initX);
}
/**
* The after-advice for {@link BaseConfig#initRow}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.initRow)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetInitRow(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.initRow = Coordinate.scale(cfg.initRow);
// handle the uninitialized case
if (cfg.initRow == BaseConfig.INV_COORD)
{
cfg.initY = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.initY = wa.cc.rowToPixels(cfg.initRow);
cfg.initRow = wa.cc.rowFromPixels(cfg.initY);
}
/**
* The after-advice for {@link BaseConfig#initX}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.initX)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetInitX(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.initX == BaseConfig.INV_COORD)
{
cfg.initColumn = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.initColumn = wa.cc.columnFromPixels(cfg.initX);
}
/**
* The after-advice for {@link BaseConfig#initY}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.initY)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetInitY(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.initY == BaseConfig.INV_COORD)
{
cfg.initRow = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.initRow = wa.cc.rowFromPixels(cfg.initY);
}
/**
* The after-advice for {@link BaseConfig#column}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.column)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetColumn(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.column = Coordinate.scale(cfg.column);
// handle the uninitialized case
if (cfg.column == BaseConfig.INV_COORD)
{
cfg.x = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.x = wa.cc.columnToPixels(cfg.column);
cfg.column = wa.cc.columnFromPixels(cfg.x);
}
/**
* The after-advice for {@link BaseConfig#row}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.row)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetRow(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.row = Coordinate.scale(cfg.row);
// handle the uninitialized case
if (cfg.row == BaseConfig.INV_COORD)
{
cfg.y = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.y = wa.cc.rowToPixels(cfg.row);
cfg.row = wa.cc.rowFromPixels(cfg.y);
}
/**
* The after-advice for {@link BaseConfig#x}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.x)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetX(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.x == BaseConfig.INV_COORD)
{
cfg.column = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.column = wa.cc.columnFromPixels(cfg.x);
}
/**
* The after-advice for {@link BaseConfig#y}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.y)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetY(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.y == BaseConfig.INV_COORD)
{
cfg.row = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.row = wa.cc.rowFromPixels(cfg.y);
}
/**
* The after-advice for {@link BaseConfig#clientColumn}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientColumn)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientColumn(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.clientColumn = Coordinate.scale(cfg.clientColumn);
// handle the uninitialized case
if (cfg.clientColumn == BaseConfig.INV_COORD)
{
cfg.clientX = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientX = wa.cc.columnToPixels(cfg.clientColumn);
cfg.clientColumn = wa.cc.columnFromPixels(cfg.clientX);
}
/**
* The after-advice for {@link BaseConfig#clientRow}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientRow)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientRow(BaseConfig cfg)
{
if (isSuspended())
return;
cfg.clientRow = Coordinate.scale(cfg.clientRow);
// handle the uninitialized case
if (cfg.clientRow == BaseConfig.INV_COORD)
{
cfg.clientY = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientY = wa.cc.rowToPixels(cfg.clientRow);
cfg.clientRow = wa.cc.rowFromPixels(cfg.clientY);
}
/**
* The after-advice for {@link BaseConfig#clientX}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientX)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientX(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientX == BaseConfig.INV_COORD)
{
cfg.clientColumn = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientColumn = wa.cc.columnFromPixels(cfg.clientX);
}
/**
* The after-advice for {@link BaseConfig#clientY}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientY)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientY(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientY == BaseConfig.INV_COORD)
{
cfg.clientRow = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientRow = wa.cc.rowFromPixels(cfg.clientY);
}
/**
* The after-advice for WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.widthChars) " +
"&& !withincode(private void com.goldencode.p2j.ui.LabelConfig.setDefaults(..)) " +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetWidthChars(BaseConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.widthPixels = wa.cc.columnToPixels(cfg.widthChars);
cfg.widthChars = wa.cc.columnFromPixels(cfg.widthPixels);
}
/**
* The after-advice for HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.heightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetHeightChars(BaseConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.heightPixels = wa.cc.rowToPixels(cfg.heightChars);
cfg.heightChars = wa.cc.rowFromPixels(cfg.heightPixels);
}
/**
* The after-advice for WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.widthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetWidthPixels(BaseConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.widthChars = wa.cc.columnFromPixels(cfg.widthPixels);
}
/**
* The after-advice for HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.heightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetHeightPixels(BaseConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.heightChars = wa.cc.rowFromPixels(cfg.heightPixels);
}
/**
* The after-advice for WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientWidthChars) " +
"&& !withincode(private void com.goldencode.p2j.ui.LabelConfig.setDefaults(..)) " +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientWidthChars(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientWidthChars == BaseConfig.INV_COORD)
{
cfg.clientWidthPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientWidthPixels = wa.cc.columnToPixels(cfg.clientWidthChars);
cfg.clientWidthChars = wa.cc.columnFromPixels(cfg.clientWidthPixels);
}
/**
* The after-advice for HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientHeightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientHeightChars(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientHeightChars == BaseConfig.INV_COORD)
{
cfg.clientHeightPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientHeightPixels = wa.cc.rowToPixels(cfg.clientHeightChars);
cfg.clientHeightChars = wa.cc.rowFromPixels(cfg.clientHeightPixels);
}
/**
* The after-advice for WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientWidthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientWidthPixels(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientWidthPixels == BaseConfig.INV_COORD)
{
cfg.clientWidthChars = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientWidthChars = wa.cc.columnFromPixels(cfg.clientWidthPixels);
}
/**
* The after-advice for HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.BaseConfig.clientHeightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetClientHeightPixels(BaseConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.clientHeightPixels == BaseConfig.INV_COORD)
{
cfg.clientHeightChars = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.clientHeightChars = wa.cc.rowFromPixels(cfg.clientHeightPixels);
}
/**
* The after-advice for MIN-WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.minWidthChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMinWidthChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.minWidthPixels = wa.cc.columnToPixels(cfg.minWidthChars);
cfg.minWidthChars = wa.cc.columnFromPixels(cfg.minWidthPixels);
}
/**
* The after-advice for MIN-HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.minHeightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMinHeightChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.minHeightPixels = wa.cc.rowToPixels(cfg.minHeightChars);
cfg.minHeightChars = wa.cc.rowFromPixels(cfg.minHeightPixels);
}
/**
* The after-advice for MIN-WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.minWidthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMinWidthPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.minWidthChars = wa.cc.columnFromPixels(cfg.minWidthPixels);
}
/**
* The after-advice for MIN-HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.minHeightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMinHeightPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.minHeightChars = wa.cc.rowFromPixels(cfg.minHeightPixels);
}
/**
* The after-advice for MAX-WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.maxWidthChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMaxWidthChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.maxWidthPixels = wa.cc.columnToPixels(cfg.maxWidthChars);
cfg.maxWidthChars = wa.cc.columnFromPixels(cfg.maxWidthPixels);
}
/**
* The after-advice for MAX-HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.maxHeightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMaxHeightChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.maxHeightPixels = wa.cc.rowToPixels(cfg.maxHeightChars);
cfg.maxHeightChars = wa.cc.rowFromPixels(cfg.maxHeightPixels);
}
/**
* The after-advice for MAX-WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.maxWidthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMaxWidthPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.maxWidthChars = wa.cc.columnFromPixels(cfg.maxWidthPixels);
}
/**
* The after-advice for MAX-HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.maxHeightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetMaxHeightPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.maxHeightChars = wa.cc.rowFromPixels(cfg.maxHeightPixels);
}
/**
* The after-advice for FULL-WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.fullWidthChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetFullWidthChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.fullWidthPixels = wa.cc.columnToPixels(cfg.fullWidthChars);
cfg.fullWidthChars = wa.cc.columnFromPixels(cfg.fullWidthPixels);
}
/**
* The after-advice for FULL-HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.fullHeightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetFullHeightChars(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.fullHeightPixels = wa.cc.rowToPixels(cfg.fullHeightChars);
cfg.fullHeightChars = wa.cc.rowFromPixels(cfg.fullHeightPixels);
}
/**
* The after-advice for FULL-WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.fullWidthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetFullWidthPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.fullWidthChars = wa.cc.columnFromPixels(cfg.fullWidthPixels);
}
/**
* The after-advice for FULL-HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.WindowConfig.fullHeightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetFullHeightPixels(WindowConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
cfg.fullHeightChars = wa.cc.rowFromPixels(cfg.fullHeightPixels);
}
/**
* The after-advice for VIRTUAL-WIDTH-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.PaneConfig.virtualWidthChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetVirtWidthChars(PaneConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.virtualWidthChars == BaseConfig.INV_COORD)
{
cfg.virtualWidthPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.virtualWidthPixels = wa.cc.columnToPixels(cfg.virtualWidthChars);
cfg.virtualWidthChars = wa.cc.columnFromPixels(cfg.virtualWidthPixels);
}
/**
* The after-advice for VIRTUAL-HEIGHT-CHARS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.PaneConfig.virtualHeightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetVirtHeightChars(PaneConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.virtualHeightChars == BaseConfig.INV_COORD)
{
cfg.virtualHeightPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.virtualHeightPixels = wa.cc.rowToPixels(cfg.virtualHeightChars);
cfg.virtualHeightChars = wa.cc.rowFromPixels(cfg.virtualHeightPixels);
}
/**
* The after-advice for VIRTUAL-WIDTH-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.PaneConfig.virtualWidthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetVirtWidthPixels(PaneConfig cfg)
{
if (isSuspended())
return;
WorkArea wa = contextData.get();
// handle the uninitialized case
if (cfg.virtualWidthPixels == BaseConfig.INV_COORD)
{
cfg.virtualWidthChars = BaseConfig.INV_COORD;
return;
}
cfg.virtualWidthChars = wa.cc.columnFromPixels(cfg.virtualWidthPixels);
}
/**
* The after-advice for VIRTUAL-HEIGHT-PIXELS attribute.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.PaneConfig.virtualHeightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetVirtHeightPixels(PaneConfig cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.virtualHeightPixels == BaseConfig.INV_COORD)
{
cfg.virtualHeightChars = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
Coordinate.RoundingMode rmode = cfg.virtualHeightPixels < 0 ?
Coordinate.RoundingMode.TRUNCATE :
Coordinate.RoundingMode.ROUND;
cfg.virtualHeightChars = wa.cc.rowFromPixels(cfg.virtualHeightPixels, rmode);
}
/**
* The after-advice for {@link ButtonImageDefinition#heightChars}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.heightChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageHeightChars(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.heightChars == BaseConfig.INV_COORD)
{
cfg.heightPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.heightPixels = wa.cc.rowToPixels(cfg.heightChars);
cfg.heightChars = wa.cc.rowFromPixels(cfg.heightPixels);
}
/**
* The after-advice for {@link ButtonImageDefinition#widthChars}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.widthChars)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageWidthChars(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.widthChars == BaseConfig.INV_COORD)
{
cfg.widthPixels = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.widthPixels = wa.cc.columnToPixels(cfg.widthChars);
cfg.widthChars = wa.cc.columnFromPixels(cfg.widthPixels);
}
/**
* The after-advice for {@link ButtonImageDefinition#heightPixels}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.heightPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageHeightPixels(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.heightPixels == BaseConfig.INV_COORD)
{
cfg.heightChars = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.heightChars = wa.cc.rowFromPixels(cfg.heightPixels);
}
/**
* The after-advice for {@link ButtonImageDefinition#widthPixels}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.widthPixels)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageWidthPixels(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.widthPixels == BaseConfig.INV_COORD)
{
cfg.widthChars = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.widthChars = wa.cc.columnFromPixels(cfg.widthPixels);
}
/**
* The after-advice for {@link ButtonImageDefinition#offsetRow}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.offsetRow)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageOffsetRow(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.offsetRow == BaseConfig.INV_COORD)
{
cfg.offsetY = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.offsetY = wa.cc.rowToPixels(cfg.offsetRow);
cfg.offsetRow = wa.cc.rowFromPixels(cfg.offsetY);
}
/**
* The after-advice for {@link ButtonImageDefinition#offsetCol}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.offsetCol)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageOffsetCol(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.offsetCol == BaseConfig.INV_COORD)
{
cfg.offsetX = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.offsetX = wa.cc.columnToPixels(cfg.offsetCol);
cfg.offsetCol = wa.cc.columnFromPixels(cfg.offsetX);
}
/**
* The after-advice for {@link ButtonImageDefinition#offsetY}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.offsetY)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageOffsetY(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.offsetY == BaseConfig.INV_COORD)
{
cfg.offsetRow = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.offsetRow = wa.cc.rowFromPixels(cfg.offsetY);
}
/**
* The after-advice for {@link ButtonImageDefinition#offsetX}.
*
* @param cfg
* The target config reference being intercepted.
*/
@After("set(public * com.goldencode.p2j.ui.ButtonImageDefinition.offsetX)" +
"&& target(cfg) " +
"&& withinCommonPoint()")
public void afterSetButtonImageOffsetX(ButtonImageDefinition cfg)
{
if (isSuspended())
return;
// handle the uninitialized case
if (cfg.offsetX == BaseConfig.INV_COORD)
{
cfg.offsetCol = BaseConfig.INV_COORD;
return;
}
WorkArea wa = contextData.get();
cfg.offsetCol = wa.cc.columnFromPixels(cfg.offsetX);
}
/**
* Class for cached values saved in the context.
**/
private class WorkArea
{
/**
* Cached coordinates conversion reference.
*/
private CoordinatesConversion cc;
/**
* Cached config manager reference.
*/
private ConfigManager cm;
}
}