najoan125 / fabric-koreanchat

GNU Lesser General Public License v3.0
2 stars 1 forks source link

윈도우 너비를 넘어가는 텍스트를 지울 때 인디케이터 위치와 텍스트 커서가 일치하지 않음 #5

Closed Shihyeon closed 3 months ago

Shihyeon commented 3 months ago

이 모드에 기여하기 위해 몇몇 기능을 추가하던 도중

채팅창에 인디케이터 위치가 너무 높아 조정을 하고자 했습니다.

위쪽에 둔 이유가 컬러표 때문으로 보이는데, 최신 버전에서 컬러표(insert키) 지원이 되는지 모르겠고,

실질적으로 사용하지 않는 기능이기에, 아래 그림과 같이 채팅창에 가깝게 옮기고자 합니다. (아래 기능은 텍스트 위치에 따라 움직이는 인디케이터이며, 룻트님의 한글채팅에 영감을 받아 구현했습니다.) ([Ko]는 언어가 영어일 경우이며, 언어가 한글일 경우 [한글]로 표시됩니다.)

image

위처럼 구현하고 PR하고자 합니다.

이렇게 위치를 수정해도 괜찮을까요?

수정)

아래의 이유로 보이는데, 저는 저런 현상을 보지 못했는데, 최신 버전에서도 저렇게 되나요? 어떻게 재현할 수 있을까요?

인디케이터를 아래 에러-표시-텍스트가 덮어 쓰니 괜찮지 않을까요?

image

najoan125 commented 3 months ago

일단 PR해주시면 검토 후 merge하겠습니다

Shihyeon commented 3 months ago

6

PR하였습니다.

Shihyeon commented 3 months ago

영상입니다.

https://github.com/najoan125/fabric-koreanchat/assets/76618619/ac2df095-06df-4803-9c33-f6b789d8b26f

Shihyeon commented 3 months ago

움직이는 인디케이터에 관해 새로 구상중인 건, 텍스트 커서 위치를 얻고 그 위치에 y쪽만 수정하면 어떨까 생각중입니다. TextFieldWidget.class L427 보면 텍스트 커서를 띄우는 부분 있는데, 그 위치를 나타내는 o, l을 어찌저찌 잘 가져오면 되지 않을까 생각됩니다.

@Environment(EnvType.CLIENT)
public class TextFieldWidget extends ClickableWidget implements Drawable {

    ...

    public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
        if (this.isVisible()) {

            ...

            int k = this.drawsBackground ? this.getX() + 4 : this.getX();
            int l = this.drawsBackground ? this.getY() + (this.height - 8) / 2 : this.getY();
            int m = k;
            int n = MathHelper.clamp(this.selectionEnd - this.firstCharacterIndex, 0, string.length());
            if (!string.isEmpty()) {
                String string2 = bl ? string.substring(0, j) : string;
                m = context.drawTextWithShadow(this.textRenderer, (OrderedText)this.renderTextProvider.apply(string2, this.firstCharacterIndex), m, l, i);
            }
            int o = m;

            ...

            // 이 부분에 인디케이터 삽입하는 건?
            // Indicator.showIndicator(context, o, l-10, false);

            if (bl2) {
                if (bl3) {
                    RenderLayer var10001 = RenderLayer.getGuiOverlay();
                    var10003 = l - 1;
                    var10004 = o + 1;
                    var10005 = l + 1;
                    Objects.requireNonNull(this.textRenderer);
                    context.fill(var10001, o, var10003, var10004, var10005 + 9, -3092272);
                } else {
                    context.drawTextWithShadow(this.textRenderer, "_", o, l, i);
                }
            }

            ...

        }
    }
}
najoan125 commented 3 months ago

일단 merge했습니다 제가 코드를 살짝 수정한 다음 릴리즈 하도록 하겠습니다 감사합니다

Shihyeon commented 3 months ago

코드를 깔끔하게 수정해 주셔서 감사드립니다. 현재 버그가 하나 남아있어. 이 이슈는 수정을 위해 남겨두는 게 좋겠습니다.

제가 생각한 방법은 두 가지가 있습니다.

  1. 텍스트 커서의 위치 가져오기

  2. [전체 텍스트필드 크기] = [윈도우 너비보다 작은 좌측으로 넘어간 텍스트필드 크기] + [윈도우 너비만큼의 텍스트필드 크기] *N + [윈도우 너비만큼의 텍스트필드 크기(currently)] . [윈도우 너비만큼의 텍스트필드 크기(currently)]의 텍스트를 지울 때, [전체 텍스트필드 크기] - [윈도우 너비만큼의 텍스트필드 크기(currently)]만큼만 indicatorX이게 하고, [윈도우 너비만큼의 텍스트필드 크기(currently)]이 0이되는 순간 [윈도우 너비만큼의 텍스트필드 크기]로 넘어가고 반복, 이후 [윈도우 너비보다 작은 좌측으로 넘어간 텍스트필드 크기] 정상적으로 작동

다 구현해보다가 실력이 부족하여 구현하지 못 함...

najoan125 commented 3 months ago

이미 인지하고 있는 버그입니다. 어떻게든 수정하려고 해보았지만, 좌우 스크롤의 정확한 위치(오프셋)를 얻는 방법을 몰라서 해결하지 못했습니다. 스크롤이 넘어가는걸 계산해서 적용한다고 해도, 사용자가 화살표키로 스크롤을 이동하면 다시 틀어져서 어떻게 해야할지 구상 중이었습니다.

님께서 제안하신 좌측으로 넘어간 텍스트 필드 크기를 이용해서 계산하는 것도 실제로 얼마나 넘어가 있는지 정확한 계산이 힘들기 때문에 해결하는 데 좀 오래 걸릴 것 같습니다.

최대한 노력해서 빠른 시일 내에 해결해보도록 하겠습니다!

Shihyeon commented 3 months ago

위에서 나온 문제 및 커서 위치에 따른 인디케이터 위치를 fix하고 PR하였습니다.

테스트 및 코드 리뷰 끝내고 모드 버전 범프한 다음 모드린스 업로드하시면 좋을 것 같습니다.

이후 이슈 닫으면 되겠네요. 감사합니다.

Edit: 방향키로 이동할 때 애니메이션 인디케이터가 살짝 끊기는 이슈가 있으니 이 부분 참고해 주세요. 애니메이션 부분 이해가 덜 되어 제가 수정할 수 없었습니다...

najoan125 commented 3 months ago

애니메이션 인디케이터가 살짝 끊기는 이슈 해결했습니다. 인디케이터 위치 고쳐주셔서 감사해요