aiqtech commited on
Commit
4ec9e49
ยท
verified ยท
1 Parent(s): b80a36c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -59
app.py CHANGED
@@ -632,6 +632,40 @@ body {background: #f5f7fa !important}
632
  margin: 0 auto;
633
  }
634
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
635
  /* ํŒจ๋„ ์Šคํƒ€์ผ๋ง */
636
  .input-panel, .output-panel {
637
  background: white;
@@ -669,32 +703,33 @@ body {background: #f5f7fa !important}
669
 
670
  /* ๋ฒ„ํŠผ ์Šคํƒ€์ผ๋ง */
671
  .position-btn {
672
- padding: 12px;
673
- border: 2px solid #ddd;
674
- border-radius: 8px;
675
- background: white;
676
- cursor: pointer;
677
- transition: all 0.2s ease;
678
- width: 48px;
679
- height: 48px;
680
- display: flex;
681
- align-items: center;
682
- justify-content: center;
683
- font-size: 1.2em;
684
- margin: 4px;
 
685
  }
686
 
687
  .position-btn:hover {
688
- background: #e3f2fd;
689
  transform: translateY(-2px);
690
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
691
  }
692
 
693
  .position-btn.selected {
694
- background-color: #2196F3;
695
- color: white;
696
- border-color: #1976D2;
697
- box-shadow: 0 4px 12px rgba(33,150,243,0.3);
698
  }
699
 
700
  /* ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ */
@@ -710,16 +745,16 @@ body {background: #f5f7fa !important}
710
 
711
  /* ์ž…๋ ฅ ํ•„๋“œ ์Šคํƒ€์ผ๋ง */
712
  input[type="text"], textarea {
713
- border: 2px solid #e0e0e0;
714
- border-radius: 8px;
715
- padding: 12px;
716
- font-size: 1.1em;
717
- transition: all 0.3s ease;
718
  }
719
 
720
  input[type="text"]:focus, textarea:focus {
721
- border-color: #2196F3;
722
- box-shadow: 0 0 0 3px rgba(33,150,243,0.2);
723
  }
724
 
725
  /* ์Šฌ๋ผ์ด๋” ์Šคํƒ€์ผ๋ง */
@@ -728,17 +763,17 @@ input[type="text"]:focus, textarea:focus {
728
  }
729
 
730
  .slider {
731
- height: 6px;
732
- background: #e0e0e0;
733
- border-radius: 3px;
734
  }
735
 
736
  .slider-handle {
737
- width: 20px;
738
- height: 20px;
739
- background: #2196F3;
740
- border: 2px solid white;
741
- box-shadow: 0 2px 4px rgba(0,0,0,0.2);
742
  }
743
 
744
  /* ์ƒํƒœ ๋ฉ”์‹œ์ง€ */
@@ -748,6 +783,7 @@ input[type="text"]:focus, textarea:focus {
748
  margin: 10px 0;
749
  font-size: 0.9em;
750
  transition: all 0.3s ease;
 
751
  }
752
 
753
  .status-success {
@@ -777,9 +813,9 @@ input[type="text"]:focus, textarea:focus {
777
  }
778
 
779
  .position-btn {
780
- width: 40px;
781
- height: 40px;
782
- font-size: 1em;
783
  }
784
  }
785
 
@@ -793,11 +829,6 @@ input[type="text"]:focus, textarea:focus {
793
  animation: fadeIn 0.3s ease-out;
794
  }
795
 
796
- /* ์ƒํƒœ ๋ฉ”์‹œ์ง€ ์• ๋‹ˆ๋ฉ”์ด์…˜ */
797
- .status-message {
798
- animation: slideIn 0.3s ease-out;
799
- }
800
-
801
  @keyframes slideIn {
802
  from {
803
  transform: translateY(-10px);
@@ -808,6 +839,67 @@ input[type="text"]:focus, textarea:focus {
808
  opacity: 1;
809
  }
810
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
  """
812
 
813
  def add_text_with_stroke(draw, text, x, y, font, text_color, stroke_width):
@@ -989,6 +1081,7 @@ def update_controls(bg_prompt):
989
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
990
  position = gr.State(value="bottom-center")
991
  processing_status = gr.State(value="idle")
 
992
 
993
  gr.HTML("""
994
  <div class="main-title">
@@ -1007,9 +1100,9 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
1007
  # ์™ผ์ชฝ ํŒจ๋„ (์ž…๋ ฅ)
1008
  with gr.Column(scale=1):
1009
  with gr.Group(elem_classes="input-panel"):
1010
- with gr.Tabs():
1011
- # ์ฒซ ๋ฒˆ์งธ ํƒญ: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๋ฐ ์ธํŽ˜์ธํŒ…
1012
- with gr.Tab("Image Upload & Inpainting", elem_classes="tab"):
1013
 
1014
  input_image = gr.Image(
1015
  type="pil",
@@ -1031,8 +1124,8 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
1031
  inpaint_btn = gr.Button("Apply Inpainting", variant="primary")
1032
 
1033
  # ๋‘ ๋ฒˆ์งธ ํƒญ: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ๋ฐ ์ƒ์„ฑ
1034
- with gr.Tab("Background Removal", elem_classes="tab"):
1035
 
 
1036
  text_prompt = gr.Textbox(
1037
  label="Object to Extract",
1038
  placeholder="Enter what you want to extract...",
@@ -1059,17 +1152,21 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
1059
  with gr.Group(elem_classes="controls-panel", visible=False) as object_controls:
1060
  with gr.Column(scale=1):
1061
  with gr.Row():
1062
- btn_top_left = gr.Button("โ†–", elem_classes=["position-btn", "interactive-element"])
1063
- btn_top_center = gr.Button("โ†‘", elem_classes=["position-btn", "interactive-element"])
1064
- btn_top_right = gr.Button("โ†—", elem_classes=["position-btn", "interactive-element"])
 
 
1065
  with gr.Row():
1066
- btn_middle_left = gr.Button("โ†", elem_classes=["position-btn", "interactive-element"])
1067
- btn_middle_center = gr.Button("โ€ข", elem_classes=["position-btn", "interactive-element"])
1068
- btn_middle_right = gr.Button("โ†’", elem_classes=["position-btn", "interactive-element"])
 
1069
  with gr.Row():
1070
- btn_bottom_left = gr.Button("โ†™", elem_classes=["position-btn", "interactive-element"])
1071
- btn_bottom_center = gr.Button("โ†“", elem_classes=["position-btn", "interactive-element"], value="selected")
1072
- btn_bottom_right = gr.Button("โ†˜", elem_classes=["position-btn", "interactive-element"])
 
1073
  with gr.Column(scale=1):
1074
  scale_slider = gr.Slider(
1075
  minimum=10,
@@ -1207,12 +1304,12 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
1207
  visible=True
1208
  )
1209
 
1210
-
1211
  def handle_button_click(btn_pos):
1212
- """๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ"""
1213
- print(f"Button clicked: {btn_pos}") # ๋””๋ฒ„๊น…์šฉ
1214
- return update_position_and_ui(btn_pos)
1215
-
 
1216
  # ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ
1217
  for btn, pos in position_mapping.items():
1218
  btn.click(
 
632
  margin: 0 auto;
633
  }
634
 
635
+ /* ํƒญ ์Šคํƒ€์ผ๋ง */
636
+ .tabs-container {
637
+ margin-top: 1em;
638
+ }
639
+
640
+ .tab-nav {
641
+ pointer-events: auto !important;
642
+ cursor: pointer !important;
643
+ border-bottom: 2px solid #e0e0e0;
644
+ margin-bottom: 1em;
645
+ }
646
+
647
+ .tab-nav button {
648
+ pointer-events: auto !important;
649
+ cursor: pointer !important;
650
+ padding: 0.8em 1.2em;
651
+ margin-right: 0.5em;
652
+ border: none;
653
+ background: none;
654
+ color: #666;
655
+ transition: all 0.3s ease;
656
+ }
657
+
658
+ .tab-nav button:hover {
659
+ color: #2196F3;
660
+ background: rgba(33, 150, 243, 0.1);
661
+ }
662
+
663
+ .tab-nav button.selected {
664
+ color: #2196F3;
665
+ border-bottom: 2px solid #2196F3;
666
+ font-weight: bold;
667
+ }
668
+
669
  /* ํŒจ๋„ ์Šคํƒ€์ผ๋ง */
670
  .input-panel, .output-panel {
671
  background: white;
 
703
 
704
  /* ๋ฒ„ํŠผ ์Šคํƒ€์ผ๋ง */
705
  .position-btn {
706
+ padding: 12px !important;
707
+ border: 2px solid #ddd !important;
708
+ border-radius: 8px !important;
709
+ background: white !important;
710
+ cursor: pointer !important;
711
+ transition: all 0.2s ease !important;
712
+ width: 48px !important;
713
+ height: 48px !important;
714
+ display: flex !important;
715
+ align-items: center !important;
716
+ justify-content: center !important;
717
+ font-size: 1.2em !important;
718
+ margin: 4px !important;
719
+ pointer-events: auto !important;
720
  }
721
 
722
  .position-btn:hover {
723
+ background: #e3f2fd !important;
724
  transform: translateY(-2px);
725
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
726
  }
727
 
728
  .position-btn.selected {
729
+ background-color: #2196F3 !important;
730
+ color: white !important;
731
+ border-color: #1976D2 !important;
732
+ box-shadow: 0 4px 12px rgba(33,150,243,0.3) !important;
733
  }
734
 
735
  /* ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ */
 
745
 
746
  /* ์ž…๋ ฅ ํ•„๋“œ ์Šคํƒ€์ผ๋ง */
747
  input[type="text"], textarea {
748
+ border: 2px solid #e0e0e0 !important;
749
+ border-radius: 8px !important;
750
+ padding: 12px !important;
751
+ font-size: 1.1em !important;
752
+ transition: all 0.3s ease !important;
753
  }
754
 
755
  input[type="text"]:focus, textarea:focus {
756
+ border-color: #2196F3 !important;
757
+ box-shadow: 0 0 0 3px rgba(33,150,243,0.2) !important;
758
  }
759
 
760
  /* ์Šฌ๋ผ์ด๋” ์Šคํƒ€์ผ๋ง */
 
763
  }
764
 
765
  .slider {
766
+ height: 6px !important;
767
+ background: #e0e0e0 !important;
768
+ border-radius: 3px !important;
769
  }
770
 
771
  .slider-handle {
772
+ width: 20px !important;
773
+ height: 20px !important;
774
+ background: #2196F3 !important;
775
+ border: 2px solid white !important;
776
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
777
  }
778
 
779
  /* ์ƒํƒœ ๋ฉ”์‹œ์ง€ */
 
783
  margin: 10px 0;
784
  font-size: 0.9em;
785
  transition: all 0.3s ease;
786
+ animation: slideIn 0.3s ease-out;
787
  }
788
 
789
  .status-success {
 
813
  }
814
 
815
  .position-btn {
816
+ width: 40px !important;
817
+ height: 40px !important;
818
+ font-size: 1em !important;
819
  }
820
  }
821
 
 
829
  animation: fadeIn 0.3s ease-out;
830
  }
831
 
 
 
 
 
 
832
  @keyframes slideIn {
833
  from {
834
  transform: translateY(-10px);
 
839
  opacity: 1;
840
  }
841
  }
842
+
843
+ /* ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์š”์†Œ ๊ณตํ†ต ์Šคํƒ€์ผ */
844
+ .interactive-element {
845
+ pointer-events: auto !important;
846
+ cursor: pointer !important;
847
+ user-select: none !important;
848
+ }
849
+
850
+ /* ๋ฒ„ํŠผ ๊ณตํ†ต ์Šคํƒ€์ผ */
851
+ button, .button {
852
+ pointer-events: auto !important;
853
+ cursor: pointer !important;
854
+ user-select: none !important;
855
+ }
856
+
857
+ /* ํƒญ ์ปจํ…Œ์ด๋„ˆ ์Šคํƒ€์ผ */
858
+ .tabs-container {
859
+ pointer-events: auto !important;
860
+ }
861
+
862
+ .tab-item {
863
+ pointer-events: auto !important;
864
+ }
865
+
866
+ /* ํ˜ธ๋ฒ„ ํšจ๊ณผ */
867
+ .interactive-element:hover {
868
+ transform: translateY(-1px);
869
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
870
+ }
871
+
872
+ /* ํด๏ฟฝ๏ฟฝ ํšจ๊ณผ */
873
+ .interactive-element:active {
874
+ transform: translateY(1px);
875
+ }
876
+ """
877
+
878
+ js_code = """
879
+ <script>
880
+ document.addEventListener('DOMContentLoaded', function() {
881
+ function enableInteraction(selector) {
882
+ const elements = document.querySelectorAll(selector);
883
+ elements.forEach(el => {
884
+ el.style.pointerEvents = 'auto';
885
+ el.style.cursor = 'pointer';
886
+ });
887
+ }
888
+
889
+ // ํƒญ ํ™œ์„ฑํ™”
890
+ enableInteraction('.tab-nav button');
891
+ enableInteraction('.position-btn');
892
+ enableInteraction('.interactive-element');
893
+
894
+ // ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ
895
+ document.querySelectorAll('.position-btn').forEach(btn => {
896
+ btn.addEventListener('click', function() {
897
+ document.querySelectorAll('.position-btn').forEach(b => b.classList.remove('selected'));
898
+ this.classList.add('selected');
899
+ });
900
+ });
901
+ });
902
+ </script>
903
  """
904
 
905
  def add_text_with_stroke(draw, text, x, y, font, text_color, stroke_width):
 
1081
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
1082
  position = gr.State(value="bottom-center")
1083
  processing_status = gr.State(value="idle")
1084
+ gr.HTML(js_code) # JavaScript ์ฝ”๋“œ ์ถ”๊ฐ€
1085
 
1086
  gr.HTML("""
1087
  <div class="main-title">
 
1100
  # ์™ผ์ชฝ ํŒจ๋„ (์ž…๋ ฅ)
1101
  with gr.Column(scale=1):
1102
  with gr.Group(elem_classes="input-panel"):
1103
+ with gr.Tabs(elem_classes="tabs-container") as tabs:
1104
+ with gr.TabItem("Image Upload & Inpainting", elem_classes="tab-item"):
1105
+
1106
 
1107
  input_image = gr.Image(
1108
  type="pil",
 
1124
  inpaint_btn = gr.Button("Apply Inpainting", variant="primary")
1125
 
1126
  # ๋‘ ๋ฒˆ์งธ ํƒญ: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ๋ฐ ์ƒ์„ฑ
 
1127
 
1128
+ with gr.TabItem("Background Removal", elem_classes="tab-item"):
1129
  text_prompt = gr.Textbox(
1130
  label="Object to Extract",
1131
  placeholder="Enter what you want to extract...",
 
1152
  with gr.Group(elem_classes="controls-panel", visible=False) as object_controls:
1153
  with gr.Column(scale=1):
1154
  with gr.Row():
1155
+
1156
+ btn_top_left = gr.Button("โ†–", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1157
+ bbtn_top_center = gr.Button("โ†‘",elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1158
+ btn_top_right = gr.Button("โ†—", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1159
+
1160
  with gr.Row():
1161
+ btn_middle_left = gr.Button("โ†", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1162
+ tn_middle_center = gr.Button("โ€ข",elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1163
+ btn_middle_right = gr.Button("โ†’", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1164
+
1165
  with gr.Row():
1166
+ btn_bottom_left = gr.Button("โ†™", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1167
+ btn_bottom_center = gr.Button("โ†“", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary", value="selected")
1168
+ btn_bottom_right = gr.Button("โ†˜", elem_classes=["position-btn", "interactive-element"],interactive=True,variant="secondary")
1169
+
1170
  with gr.Column(scale=1):
1171
  scale_slider = gr.Slider(
1172
  minimum=10,
 
1304
  visible=True
1305
  )
1306
 
 
1307
  def handle_button_click(btn_pos):
1308
+ print(f"Button clicked: {btn_pos}")
1309
+ updates = {btn: gr.update(variant="secondary") for btn in position_mapping.keys()}
1310
+ updates[btn_pos] = gr.update(variant="primary")
1311
+ return [btn_pos] + [updates[btn] for btn in position_mapping.keys()]
1312
+
1313
  # ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ
1314
  for btn, pos in position_mapping.items():
1315
  btn.click(